1/** 2 * @licstart The following is the entire license notice for the 3 * JavaScript code in this page 4 * 5 * Copyright 2024 Mozilla Foundation 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * @licend The above is the entire license notice for the 20 * JavaScript code in this page 21 */ 22 23/** 24 * pdfjsVersion = 6.3.289 25 * pdfjsBuild = 1c8020a7d 26 */ 27/******/ var __webpack_modules__ = ({ 28 29/***/ 9306 30(module, __unused_webpack_exports, __webpack_require__) { 31 32 33var isCallable = __webpack_require__(4901); 34var tryToString = __webpack_require__(6823); 35 36var $TypeError = TypeError; 37 38// `Assert: IsCallable(argument) is true` 39module.exports = function (argument) { 40 if (isCallable(argument)) return argument; 41 throw new $TypeError(tryToString(argument) + ' is not a function'); 42}; 43 44 45/***/ }, 46 47/***/ 3506 48(module, __unused_webpack_exports, __webpack_require__) { 49 50 51var isPossiblePrototype = __webpack_require__(3925); 52 53var $String = String; 54var $TypeError = TypeError; 55 56module.exports = function (argument) { 57 if (isPossiblePrototype(argument)) return argument; 58 throw new $TypeError("Can't set " + $String(argument) + ' as a prototype'); 59}; 60 61 62/***/ }, 63 64/***/ 7080 65(module, __unused_webpack_exports, __webpack_require__) { 66 67 68var has = (__webpack_require__(4402).has); 69 70// Perform ? RequireInternalSlot(M, [[SetData]]) 71module.exports = function (it) { 72 has(it); 73 return it; 74}; 75 76 77/***/ }, 78 79/***/ 3463 80(module) { 81 82 83var $TypeError = TypeError; 84 85module.exports = function (argument) { 86 if (typeof argument == 'string') return argument; 87 throw new $TypeError('Argument is not a string'); 88}; 89 90 91/***/ }, 92 93/***/ 4328 94(module, __unused_webpack_exports, __webpack_require__) { 95 96 97var WeakMapHelpers = __webpack_require__(4995); 98 99var weakmap = new WeakMapHelpers.WeakMap(); 100var set = WeakMapHelpers.set; 101var remove = WeakMapHelpers.remove; 102 103module.exports = function (key) { 104 set(weakmap, key, 1); 105 remove(weakmap, key); 106 return key; 107}; 108 109 110/***/ }, 111 112/***/ 6557 113(module, __unused_webpack_exports, __webpack_require__) { 114 115 116var has = (__webpack_require__(4995).has); 117 118// Perform ? RequireInternalSlot(M, [[WeakMapData]]) 119module.exports = function (it) { 120 has(it); 121 return it; 122}; 123 124 125/***/ }, 126 127/***/ 6469 128(module, __unused_webpack_exports, __webpack_require__) { 129 130 131var wellKnownSymbol = __webpack_require__(8227); 132var create = __webpack_require__(2360); 133var defineProperty = (__webpack_require__(4913).f); 134 135var UNSCOPABLES = wellKnownSymbol('unscopables'); 136var ArrayPrototype = Array.prototype; 137 138// Array.prototype[@@unscopables] 139// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables 140if (ArrayPrototype[UNSCOPABLES] === undefined) { 141 defineProperty(ArrayPrototype, UNSCOPABLES, { 142 configurable: true, 143 value: create(null) 144 }); 145} 146 147// add a key to Array.prototype[@@unscopables] 148module.exports = function (key) { 149 ArrayPrototype[UNSCOPABLES][key] = true; 150}; 151 152 153/***/ }, 154 155/***/ 679 156(module, __unused_webpack_exports, __webpack_require__) { 157 158 159var isPrototypeOf = __webpack_require__(1625); 160 161var $TypeError = TypeError; 162 163module.exports = function (it, Prototype) { 164 if (isPrototypeOf(Prototype, it)) return it; 165 throw new $TypeError('Incorrect invocation'); 166}; 167 168 169/***/ }, 170 171/***/ 3972 172(module, __unused_webpack_exports, __webpack_require__) { 173 174 175var isObject = __webpack_require__(34); 176 177var $String = String; 178var $TypeError = TypeError; 179 180module.exports = function (argument) { 181 if (argument === undefined || isObject(argument)) return argument; 182 throw new $TypeError($String(argument) + ' is not an object or undefined'); 183}; 184 185 186/***/ }, 187 188/***/ 8551 189(module, __unused_webpack_exports, __webpack_require__) { 190 191 192var isObject = __webpack_require__(34); 193 194var $String = String; 195var $TypeError = TypeError; 196 197// `Assert: Type(argument) is Object` 198module.exports = function (argument) { 199 if (isObject(argument)) return argument; 200 throw new $TypeError($String(argument) + ' is not an object'); 201}; 202 203 204/***/ }, 205 206/***/ 4154 207(module, __unused_webpack_exports, __webpack_require__) { 208 209 210var classof = __webpack_require__(6955); 211 212var $TypeError = TypeError; 213 214// Perform ? RequireInternalSlot(argument, [[TypedArrayName]]) 215// If argument.[[TypedArrayName]] is not "Uint8Array", throw a TypeError exception 216module.exports = function (argument) { 217 if (classof(argument) === 'Uint8Array') return argument; 218 throw new $TypeError('Argument is not an Uint8Array'); 219}; 220 221 222/***/ }, 223 224/***/ 7811 225(module) { 226 227 228// eslint-disable-next-line es/no-typed-arrays -- safe 229module.exports = typeof ArrayBuffer != 'undefined' && typeof DataView != 'undefined'; 230 231 232/***/ }, 233 234/***/ 7394 235(module, __unused_webpack_exports, __webpack_require__) { 236 237 238var globalThis = __webpack_require__(4576); 239var uncurryThisAccessor = __webpack_require__(6706); 240var classof = __webpack_require__(2195); 241 242var ArrayBuffer = globalThis.ArrayBuffer; 243var TypeError = globalThis.TypeError; 244 245// Includes
vendor: 9,929 bytes, lines 246-536
246// - Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). 247// - If IsSharedArrayBuffer(O) is true, throw a TypeError exception. 248module.exports = ArrayBuffer && uncurryThisAccessor(ArrayBuffer.prototype, 'byteLength', 'get') || function (O) { 249 if (classof(O) !== 'ArrayBuffer') throw new TypeError('ArrayBuffer expected'); 250 return O.byteLength; 251}; 252 253 254/***/ }, 255 256/***/ 3238 257(module, __unused_webpack_exports, __webpack_require__) { 258 259 260var globalThis = __webpack_require__(4576); 261var NATIVE_ARRAY_BUFFER = __webpack_require__(7811); 262var arrayBufferByteLength = __webpack_require__(7394); 263 264var DataView = globalThis.DataView; 265 266module.exports = function (O) { 267 if (!NATIVE_ARRAY_BUFFER || arrayBufferByteLength(O) !== 0) return false; 268 try { 269 // eslint-disable-next-line no-new -- thrower 270 new DataView(O); 271 return false; 272 } catch (error) { 273 return true; 274 } 275}; 276 277 278/***/ }, 279 280/***/ 5169 281(module, __unused_webpack_exports, __webpack_require__) { 282 283 284var isDetached = __webpack_require__(3238); 285 286var $TypeError = TypeError; 287 288module.exports = function (it) { 289 if (isDetached(it)) throw new $TypeError('ArrayBuffer is detached'); 290 return it; 291}; 292 293 294/***/ }, 295 296/***/ 4644 297(module, __unused_webpack_exports, __webpack_require__) { 298 299 300var NATIVE_ARRAY_BUFFER = __webpack_require__(7811); 301var DESCRIPTORS = __webpack_require__(3724); 302var globalThis = __webpack_require__(4576); 303var isCallable = __webpack_require__(4901); 304var isObject = __webpack_require__(34); 305var hasOwn = __webpack_require__(9297); 306var classof = __webpack_require__(6955); 307var tryToString = __webpack_require__(6823); 308var createNonEnumerableProperty = __webpack_require__(6699); 309var defineBuiltIn = __webpack_require__(6840); 310var defineBuiltInAccessor = __webpack_require__(2106); 311var isPrototypeOf = __webpack_require__(1625); 312var getPrototypeOf = __webpack_require__(2787); 313var setPrototypeOf = __webpack_require__(2967); 314var wellKnownSymbol = __webpack_require__(8227); 315var uid = __webpack_require__(3392); 316var InternalStateModule = __webpack_require__(1181); 317 318var enforceInternalState = InternalStateModule.enforce; 319var getInternalState = InternalStateModule.get; 320var Int8Array = globalThis.Int8Array; 321var Int8ArrayPrototype = Int8Array && Int8Array.prototype; 322var Uint8ClampedArray = globalThis.Uint8ClampedArray; 323var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype; 324var TypedArray = Int8Array && getPrototypeOf(Int8Array); 325var TypedArrayPrototype = Int8ArrayPrototype && getPrototypeOf(Int8ArrayPrototype); 326var ObjectPrototype = Object.prototype; 327var TypeError = globalThis.TypeError; 328 329var TO_STRING_TAG = wellKnownSymbol('toStringTag'); 330var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG'); 331var TYPED_ARRAY_CONSTRUCTOR = 'TypedArrayConstructor'; 332// Fixing native typed arrays in Opera Presto crashes the browser, see #595 333var NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!setPrototypeOf && classof(globalThis.opera) !== 'Opera'; 334var TYPED_ARRAY_TAG_REQUIRED = false; 335var NAME, Constructor, Prototype; 336 337var TypedArrayConstructorsList = { 338 Int8Array: 1, 339 Uint8Array: 1, 340 Uint8ClampedArray: 1, 341 Int16Array: 2, 342 Uint16Array: 2, 343 Int32Array: 4, 344 Uint32Array: 4, 345 Float32Array: 4, 346 Float64Array: 8 347}; 348 349var BigIntArrayConstructorsList = { 350 BigInt64Array: 8, 351 BigUint64Array: 8 352}; 353 354var isView = function isView(it) { 355 if (!isObject(it)) return false; 356 var klass = classof(it); 357 return klass === 'DataView' 358 || hasOwn(TypedArrayConstructorsList, klass) 359 || hasOwn(BigIntArrayConstructorsList, klass); 360}; 361 362var getTypedArrayConstructor = function (it) { 363 var proto = getPrototypeOf(it); 364 if (!isObject(proto)) return; 365 var state = getInternalState(proto); 366 return (state && hasOwn(state, TYPED_ARRAY_CONSTRUCTOR)) ? state[TYPED_ARRAY_CONSTRUCTOR] : getTypedArrayConstructor(proto); 367}; 368 369var isTypedArray = function (it) { 370 if (!isObject(it)) return false; 371 var klass = classof(it); 372 return hasOwn(TypedArrayConstructorsList, klass) 373 || hasOwn(BigIntArrayConstructorsList, klass); 374}; 375 376var aTypedArray = function (it) { 377 if (isTypedArray(it)) return it; 378 throw new TypeError('Target is not a typed array'); 379}; 380 381var aTypedArrayConstructor = function (C) { 382 if (isCallable(C) && (!setPrototypeOf || isPrototypeOf(TypedArray, C))) return C; 383 throw new TypeError(tryToString(C) + ' is not a typed array constructor'); 384}; 385 386var exportTypedArrayMethod = function (KEY, property, forced, options) { 387 if (!DESCRIPTORS) return; 388 if (forced) for (var ARRAY in TypedArrayConstructorsList) { 389 var TypedArrayConstructor = globalThis[ARRAY]; 390 if (TypedArrayConstructor && hasOwn(TypedArrayConstructor.prototype, KEY)) try { 391 delete TypedArrayConstructor.prototype[KEY]; 392 } catch (error) { 393 // old WebKit bug - some methods are non-configurable 394 try { 395 TypedArrayConstructor.prototype[KEY] = property; 396 } catch (error2) { /* empty */ } 397 } 398 } 399 if (!TypedArrayPrototype[KEY] || forced) { 400 defineBuiltIn(TypedArrayPrototype, KEY, forced ? property 401 : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property, options); 402 } 403}; 404 405var exportTypedArrayStaticMethod = function (KEY, property, forced) { 406 var ARRAY, TypedArrayConstructor; 407 if (!DESCRIPTORS) return; 408 if (setPrototypeOf) { 409 if (forced) for (ARRAY in TypedArrayConstructorsList) { 410 TypedArrayConstructor = globalThis[ARRAY]; 411 if (TypedArrayConstructor && hasOwn(TypedArrayConstructor, KEY)) try { 412 delete TypedArrayConstructor[KEY]; 413 } catch (error) { /* empty */ } 414 } 415 if (!TypedArray[KEY] || forced) { 416 // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable 417 try { 418 return defineBuiltIn(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && TypedArray[KEY] || property); 419 } catch (error) { /* empty */ } 420 } else return; 421 } 422 for (ARRAY in TypedArrayConstructorsList) { 423 TypedArrayConstructor = globalThis[ARRAY]; 424 if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) { 425 defineBuiltIn(TypedArrayConstructor, KEY, property); 426 } 427 } 428}; 429 430for (NAME in TypedArrayConstructorsList) { 431 Constructor = globalThis[NAME]; 432 Prototype = Constructor && Constructor.prototype; 433 if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor; 434 else NATIVE_ARRAY_BUFFER_VIEWS = false; 435} 436 437for (NAME in BigIntArrayConstructorsList) { 438 Constructor = globalThis[NAME]; 439 Prototype = Constructor && Constructor.prototype; 440 if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor; 441} 442 443// WebKit bug - typed arrays constructors prototype is Object.prototype 444if (!NATIVE_ARRAY_BUFFER_VIEWS || !isCallable(TypedArray) || TypedArray === Function.prototype) { 445 // eslint-disable-next-line no-shadow -- safe 446 TypedArray = function TypedArray() { 447 throw new TypeError('Incorrect invocation'); 448 }; 449 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) { 450 if (globalThis[NAME]) setPrototypeOf(globalThis[NAME], TypedArray); 451 } 452} 453 454if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype) { 455 TypedArrayPrototype = TypedArray.prototype; 456 if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) { 457 if (globalThis[NAME]) setPrototypeOf(globalThis[NAME].prototype, TypedArrayPrototype); 458 } 459} 460 461// WebKit bug - one more object in Uint8ClampedArray prototype chain 462if (NATIVE_ARRAY_BUFFER_VIEWS && getPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) { 463 setPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype); 464} 465 466if (DESCRIPTORS && !hasOwn(TypedArrayPrototype, TO_STRING_TAG)) { 467 TYPED_ARRAY_TAG_REQUIRED = true; 468 defineBuiltInAccessor(TypedArrayPrototype, TO_STRING_TAG, { 469 configurable: true, 470 get: function () { 471 return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined; 472 } 473 }); 474 for (NAME in TypedArrayConstructorsList) if (globalThis[NAME]) { 475 createNonEnumerableProperty(globalThis[NAME].prototype, TYPED_ARRAY_TAG, NAME); 476 } 477} 478 479module.exports = { 480 NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS, 481 TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQUIRED && TYPED_ARRAY_TAG, 482 aTypedArray: aTypedArray, 483 aTypedArrayConstructor: aTypedArrayConstructor, 484 exportTypedArrayMethod: exportTypedArrayMethod, 485 exportTypedArrayStaticMethod: exportTypedArrayStaticMethod, 486 getTypedArrayConstructor: getTypedArrayConstructor, 487 isView: isView, 488 isTypedArray: isTypedArray, 489 TypedArray: TypedArray, 490 TypedArrayPrototype: TypedArrayPrototype 491}; 492 493 494/***/ }, 495 496/***/ 5370 497(module, __unused_webpack_exports, __webpack_require__) { 498 499 500var lengthOfArrayLike = __webpack_require__(6198); 501 502module.exports = function (Constructor, list, $length) { 503 var index = 0; 504 var length = arguments.length > 2 ? $length : lengthOfArrayLike(list); 505 var result = new Constructor(length); 506 while (length > index) result[index] = list[index++]; 507 return result; 508}; 509 510 511/***/ }, 512 513/***/ 9617 514(module, __unused_webpack_exports, __webpack_require__) { 515 516 517var toIndexedObject = __webpack_require__(5397); 518var toAbsoluteIndex = __webpack_require__(5610); 519var lengthOfArrayLike = __webpack_require__(6198); 520 521// `Array.prototype.{ indexOf, includes }` methods implementation 522var createMethod = function (IS_INCLUDES) { 523 return function ($this, el, fromIndex) { 524 var O = toIndexedObject($this); 525 var length = lengthOfArrayLike(O); 526 if (length === 0) return !IS_INCLUDES && -1; 527 var index = toAbsoluteIndex(fromIndex, length); 528 var value; 529 // Array#includes uses SameValueZero equality algorithm 530 // eslint-disable-next-line no-self-compare -- NaN check 531 if (IS_INCLUDES && el !== el) while (length > index) { 532 value = O[index++]; 533 // eslint-disable-next-line no-self-compare -- NaN check 534 if (value !== value) return true; 535 // Array#indexOf ignores holes, Array#includes - not 536 } else for (;length > index; index++) {
vendor: 9,704 bytes, lines 537-934
537 if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; 538 } return !IS_INCLUDES && -1; 539 }; 540}; 541 542module.exports = { 543 // `Array.prototype.includes` method 544 // https://tc39.es/ecma262/#sec-array.prototype.includes 545 includes: createMethod(true), 546 // `Array.prototype.indexOf` method 547 // https://tc39.es/ecma262/#sec-array.prototype.indexof 548 indexOf: createMethod(false) 549}; 550 551 552/***/ }, 553 554/***/ 4527 555(module, __unused_webpack_exports, __webpack_require__) { 556 557 558var DESCRIPTORS = __webpack_require__(3724); 559var isArray = __webpack_require__(4376); 560 561var $TypeError = TypeError; 562// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 563var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 564 565// Safari < 13 does not throw an error in this case 566var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () { 567 // makes no sense without proper strict mode support 568 if (this !== undefined) return true; 569 try { 570 // eslint-disable-next-line es/no-object-defineproperty -- safe 571 Object.defineProperty([], 'length', { writable: false }).length = 1; 572 } catch (error) { 573 return error instanceof TypeError; 574 } 575}(); 576 577module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { 578 if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) { 579 throw new $TypeError('Cannot set read only .length'); 580 } return O.length = length; 581} : function (O, length) { 582 return O.length = length; 583}; 584 585 586/***/ }, 587 588/***/ 7680 589(module, __unused_webpack_exports, __webpack_require__) { 590 591 592var uncurryThis = __webpack_require__(9504); 593 594module.exports = uncurryThis([].slice); 595 596 597/***/ }, 598 599/***/ 2804 600(module) { 601 602 603var commonAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 604var base64Alphabet = commonAlphabet + '+/'; 605var base64UrlAlphabet = commonAlphabet + '-_'; 606 607var inverse = function (characters) { 608 // TODO: use `Object.create(null)` in `core-js@4` 609 var result = {}; 610 var index = 0; 611 for (; index < 64; index++) result[characters.charAt(index)] = index; 612 return result; 613}; 614 615module.exports = { 616 i2c: base64Alphabet, 617 c2i: inverse(base64Alphabet), 618 i2cUrl: base64UrlAlphabet, 619 c2iUrl: inverse(base64UrlAlphabet) 620}; 621 622 623/***/ }, 624 625/***/ 6319 626(module, __unused_webpack_exports, __webpack_require__) { 627 628 629var anObject = __webpack_require__(8551); 630var iteratorClose = __webpack_require__(9539); 631 632// call something on iterator step with safe closing on error 633module.exports = function (iterator, fn, value, ENTRIES) { 634 try { 635 return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value); 636 } catch (error) { 637 iteratorClose(iterator, 'throw', error); 638 } 639}; 640 641 642/***/ }, 643 644/***/ 2195 645(module, __unused_webpack_exports, __webpack_require__) { 646 647 648var uncurryThis = __webpack_require__(9504); 649 650var toString = uncurryThis({}.toString); 651var stringSlice = uncurryThis(''.slice); 652 653module.exports = function (it) { 654 return stringSlice(toString(it), 8, -1); 655}; 656 657 658/***/ }, 659 660/***/ 6955 661(module, __unused_webpack_exports, __webpack_require__) { 662 663 664var TO_STRING_TAG_SUPPORT = __webpack_require__(2140); 665var isCallable = __webpack_require__(4901); 666var classofRaw = __webpack_require__(2195); 667var wellKnownSymbol = __webpack_require__(8227); 668 669var TO_STRING_TAG = wellKnownSymbol('toStringTag'); 670var $Object = Object; 671 672// ES3 wrong here 673var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments'; 674 675// fallback for IE11 Script Access Denied error 676var tryGet = function (it, key) { 677 try { 678 return it[key]; 679 } catch (error) { /* empty */ } 680}; 681 682// getting tag from ES6+ `Object.prototype.toString` 683module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) { 684 var O, tag, result; 685 return it === undefined ? 'Undefined' : it === null ? 'Null' 686 // @@toStringTag case 687 : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag 688 // builtinTag case 689 : CORRECT_ARGUMENTS ? classofRaw(O) 690 // ES3 arguments fallback 691 : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result; 692}; 693 694 695/***/ }, 696 697/***/ 7740 698(module, __unused_webpack_exports, __webpack_require__) { 699 700 701var hasOwn = __webpack_require__(9297); 702var ownKeys = __webpack_require__(5031); 703var getOwnPropertyDescriptorModule = __webpack_require__(7347); 704var definePropertyModule = __webpack_require__(4913); 705 706module.exports = function (target, source, exceptions) { 707 var keys = ownKeys(source); 708 var defineProperty = definePropertyModule.f; 709 var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; 710 for (var i = 0; i < keys.length; i++) { 711 var key = keys[i]; 712 if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) { 713 defineProperty(target, key, getOwnPropertyDescriptor(source, key)); 714 } 715 } 716}; 717 718 719/***/ }, 720 721/***/ 2211 722(module, __unused_webpack_exports, __webpack_require__) { 723 724 725var fails = __webpack_require__(9039); 726 727module.exports = !fails(function () { 728 function F() { /* empty */ } 729 F.prototype.constructor = null; 730 // eslint-disable-next-line es/no-object-getprototypeof -- required for testing 731 return Object.getPrototypeOf(new F()) !== F.prototype; 732}); 733 734 735/***/ }, 736 737/***/ 2529 738(module) { 739 740 741// `CreateIterResultObject` abstract operation 742// https://tc39.es/ecma262/#sec-createiterresultobject 743module.exports = function (value, done) { 744 return { value: value, done: done }; 745}; 746 747 748/***/ }, 749 750/***/ 6699 751(module, __unused_webpack_exports, __webpack_require__) { 752 753 754var DESCRIPTORS = __webpack_require__(3724); 755var definePropertyModule = __webpack_require__(4913); 756var createPropertyDescriptor = __webpack_require__(6980); 757 758module.exports = DESCRIPTORS ? function (object, key, value) { 759 return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); 760} : function (object, key, value) { 761 object[key] = value; 762 return object; 763}; 764 765 766/***/ }, 767 768/***/ 6980 769(module) { 770 771 772module.exports = function (bitmap, value) { 773 return { 774 enumerable: !(bitmap & 1), 775 configurable: !(bitmap & 2), 776 writable: !(bitmap & 4), 777 value: value 778 }; 779}; 780 781 782/***/ }, 783 784/***/ 4659 785(module, __unused_webpack_exports, __webpack_require__) { 786 787 788var DESCRIPTORS = __webpack_require__(3724); 789var definePropertyModule = __webpack_require__(4913); 790var createPropertyDescriptor = __webpack_require__(6980); 791 792module.exports = function (object, key, value) { 793 if (DESCRIPTORS) definePropertyModule.f(object, key, createPropertyDescriptor(0, value)); 794 else object[key] = value; 795}; 796 797 798/***/ }, 799 800/***/ 2106 801(module, __unused_webpack_exports, __webpack_require__) { 802 803 804var makeBuiltIn = __webpack_require__(283); 805var defineProperty = __webpack_require__(4913); 806 807module.exports = function (target, name, descriptor) { 808 if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true }); 809 if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true }); 810 return defineProperty.f(target, name, descriptor); 811}; 812 813 814/***/ }, 815 816/***/ 6840 817(module, __unused_webpack_exports, __webpack_require__) { 818 819 820var isCallable = __webpack_require__(4901); 821var definePropertyModule = __webpack_require__(4913); 822var makeBuiltIn = __webpack_require__(283); 823var defineGlobalProperty = __webpack_require__(9433); 824 825module.exports = function (O, key, value, options) { 826 if (!options) options = {}; 827 var simple = options.enumerable; 828 var name = options.name !== undefined ? options.name : key; 829 if (isCallable(value)) makeBuiltIn(value, name, options); 830 if (options.global) { 831 if (simple) O[key] = value; 832 else defineGlobalProperty(key, value); 833 } else { 834 try { 835 if (!options.unsafe) delete O[key]; 836 else if (O[key]) simple = true; 837 } catch (error) { /* empty */ } 838 if (simple) O[key] = value; 839 else definePropertyModule.f(O, key, { 840 value: value, 841 enumerable: false, 842 configurable: !options.nonConfigurable, 843 writable: !options.nonWritable 844 }); 845 } return O; 846}; 847 848 849/***/ }, 850 851/***/ 6279 852(module, __unused_webpack_exports, __webpack_require__) { 853 854 855var defineBuiltIn = __webpack_require__(6840); 856 857module.exports = function (target, src, options) { 858 for (var key in src) defineBuiltIn(target, key, src[key], options); 859 return target; 860}; 861 862 863/***/ }, 864 865/***/ 9433 866(module, __unused_webpack_exports, __webpack_require__) { 867 868 869var globalThis = __webpack_require__(4576); 870 871// eslint-disable-next-line es/no-object-defineproperty -- safe 872var defineProperty = Object.defineProperty; 873 874module.exports = function (key, value) { 875 try { 876 defineProperty(globalThis, key, { value: value, configurable: true, writable: true }); 877 } catch (error) { 878 globalThis[key] = value; 879 } return value; 880}; 881 882 883/***/ }, 884 885/***/ 3724 886(module, __unused_webpack_exports, __webpack_require__) { 887 888 889var fails = __webpack_require__(9039); 890 891// Detect IE8's incomplete defineProperty implementation 892module.exports = !fails(function () { 893 // eslint-disable-next-line es/no-object-defineproperty -- required for testing 894 return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7; 895}); 896 897 898/***/ }, 899 900/***/ 4055 901(module, __unused_webpack_exports, __webpack_require__) { 902 903 904var globalThis = __webpack_require__(4576); 905var isObject = __webpack_require__(34); 906 907var document = globalThis.document; 908// typeof document.createElement is 'object' in old IE 909var EXISTS = isObject(document) && isObject(document.createElement); 910 911module.exports = function (it) { 912 return EXISTS ? document.createElement(it) : {}; 913}; 914 915 916/***/ }, 917 918/***/ 6837 919(module) { 920 921 922var $TypeError = TypeError; 923var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 924 925module.exports = function (it) { 926 if (it > MAX_SAFE_INTEGER) throw new $TypeError('Maximum allowed index exceeded'); 927 return it; 928}; 929 930 931/***/ }, 932 933/***/ 5002 934(module) {
vendor: 1,551 bytes, lines 935-966
935 936 937module.exports = { 938 IndexSizeError: { s: 'INDEX_SIZE_ERR', c: 1, m: 1 }, 939 DOMStringSizeError: { s: 'DOMSTRING_SIZE_ERR', c: 2, m: 0 }, 940 HierarchyRequestError: { s: 'HIERARCHY_REQUEST_ERR', c: 3, m: 1 }, 941 WrongDocumentError: { s: 'WRONG_DOCUMENT_ERR', c: 4, m: 1 }, 942 InvalidCharacterError: { s: 'INVALID_CHARACTER_ERR', c: 5, m: 1 }, 943 NoDataAllowedError: { s: 'NO_DATA_ALLOWED_ERR', c: 6, m: 0 }, 944 NoModificationAllowedError: { s: 'NO_MODIFICATION_ALLOWED_ERR', c: 7, m: 1 }, 945 NotFoundError: { s: 'NOT_FOUND_ERR', c: 8, m: 1 }, 946 NotSupportedError: { s: 'NOT_SUPPORTED_ERR', c: 9, m: 1 }, 947 InUseAttributeError: { s: 'INUSE_ATTRIBUTE_ERR', c: 10, m: 1 }, 948 InvalidStateError: { s: 'INVALID_STATE_ERR', c: 11, m: 1 }, 949 SyntaxError: { s: 'SYNTAX_ERR', c: 12, m: 1 }, 950 InvalidModificationError: { s: 'INVALID_MODIFICATION_ERR', c: 13, m: 1 }, 951 NamespaceError: { s: 'NAMESPACE_ERR', c: 14, m: 1 }, 952 InvalidAccessError: { s: 'INVALID_ACCESS_ERR', c: 15, m: 1 }, 953 ValidationError: { s: 'VALIDATION_ERR', c: 16, m: 0 }, 954 TypeMismatchError: { s: 'TYPE_MISMATCH_ERR', c: 17, m: 1 }, 955 SecurityError: { s: 'SECURITY_ERR', c: 18, m: 1 }, 956 NetworkError: { s: 'NETWORK_ERR', c: 19, m: 1 }, 957 AbortError: { s: 'ABORT_ERR', c: 20, m: 1 }, 958 URLMismatchError: { s: 'URL_MISMATCH_ERR', c: 21, m: 1 }, 959 QuotaExceededError: { s: 'QUOTA_EXCEEDED_ERR', c: 22, m: 1 }, 960 TimeoutError: { s: 'TIMEOUT_ERR', c: 23, m: 1 }, 961 InvalidNodeTypeError: { s: 'INVALID_NODE_TYPE_ERR', c: 24, m: 1 }, 962 DataCloneError: { s: 'DATA_CLONE_ERR', c: 25, m: 1 } 963}; 964 965 966/***/ }
vendor: 4,479 bytes, lines 966-1108
966, 967 968/***/ 8727 969(module) { 970 971 972// IE8- don't enum bug keys 973module.exports = [ 974 'constructor', 975 'hasOwnProperty', 976 'isPrototypeOf', 977 'propertyIsEnumerable', 978 'toLocaleString', 979 'toString', 980 'valueOf' 981]; 982 983 984/***/ }, 985 986/***/ 2839 987(module, __unused_webpack_exports, __webpack_require__) { 988 989 990var globalThis = __webpack_require__(4576); 991 992var navigator = globalThis.navigator; 993var userAgent = navigator && navigator.userAgent; 994 995module.exports = userAgent ? String(userAgent) : ''; 996 997 998/***/ }, 999 1000/***/ 9519 1001(module, __unused_webpack_exports, __webpack_require__) { 1002 1003 1004var globalThis = __webpack_require__(4576); 1005var userAgent = __webpack_require__(2839); 1006 1007var process = globalThis.process; 1008var Deno = globalThis.Deno; 1009var versions = process && process.versions || Deno && Deno.version; 1010var v8 = versions && versions.v8; 1011var match, version; 1012 1013if (v8) { 1014 match = v8.split('.'); 1015 // in old Chrome, versions of V8 isn't V8 = Chrome / 10 1016 // but their correct versions are not interesting for us 1017 version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); 1018} 1019 1020// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` 1021// so check `userAgent` even if `.v8` exists, but 0 1022if (!version && userAgent) { 1023 match = userAgent.match(/Edge\/(\d+)/); 1024 if (!match || match[1] >= 74) { 1025 match = userAgent.match(/Chrome\/(\d+)/); 1026 if (match) version = +match[1]; 1027 } 1028} 1029 1030module.exports = version; 1031 1032 1033/***/ }, 1034 1035/***/ 6193 1036(module, __unused_webpack_exports, __webpack_require__) { 1037 1038 1039var uncurryThis = __webpack_require__(9504); 1040 1041var $Error = Error; 1042var replace = uncurryThis(''.replace); 1043 1044var TEST = (function (arg) { return String(new $Error(arg).stack); })('zxcasd'); 1045// eslint-disable-next-line redos/no-vulnerable -- safe 1046var V8_OR_CHAKRA_STACK_ENTRY = /\n\s*at [^:]*:[^\n]*/; 1047var IS_V8_OR_CHAKRA_STACK = V8_OR_CHAKRA_STACK_ENTRY.test(TEST); 1048 1049module.exports = function (stack, dropEntries) { 1050 if (IS_V8_OR_CHAKRA_STACK && typeof stack == 'string' && !$Error.prepareStackTrace) { 1051 while (dropEntries--) stack = replace(stack, V8_OR_CHAKRA_STACK_ENTRY, ''); 1052 } return stack; 1053}; 1054 1055 1056/***/ }, 1057 1058/***/ 6518 1059(module, __unused_webpack_exports, __webpack_require__) { 1060 1061 1062var globalThis = __webpack_require__(4576); 1063var getOwnPropertyDescriptor = (__webpack_require__(7347).f); 1064var createNonEnumerableProperty = __webpack_require__(6699); 1065var defineBuiltIn = __webpack_require__(6840); 1066var defineGlobalProperty = __webpack_require__(9433); 1067var copyConstructorProperties = __webpack_require__(7740); 1068var isForced = __webpack_require__(2796); 1069 1070/* 1071 options.target - name of the target object 1072 options.global - target is the global object 1073 options.stat - export as static methods of target 1074 options.proto - export as prototype methods of target 1075 options.real - real prototype method for the `pure` version 1076 options.forced - export even if the native feature is available 1077 options.bind - bind methods to the target, required for the `pure` version 1078 options.wrap - wrap constructors to preventing global pollution, required for the `pure` version 1079 options.unsafe - use the simple assignment of property instead of delete + defineProperty 1080 options.sham - add a flag to not completely full polyfills 1081 options.enumerable - export as enumerable property 1082 options.dontCallGetSet - prevent calling a getter on target 1083 options.name - the .name of the function if it does not match the key 1084*/ 1085module.exports = function (options, source) { 1086 var TARGET = options.target; 1087 var GLOBAL = options.global; 1088 var STATIC = options.stat; 1089 var FORCED, target, key, targetProperty, sourceProperty, descriptor; 1090 if (GLOBAL) { 1091 target = globalThis; 1092 } else if (STATIC) { 1093 target = globalThis[TARGET] || defineGlobalProperty(TARGET, {}); 1094 } else { 1095 target = globalThis[TARGET] && globalThis[TARGET].prototype; 1096 } 1097 if (target) for (key in source) { 1098 sourceProperty = source[key]; 1099 if (options.dontCallGetSet) { 1100 descriptor = getOwnPropertyDescriptor(target, key); 1101 targetProperty = descriptor && descriptor.value; 1102 } else targetProperty = target[key]; 1103 FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); 1104 // contained in target 1105 if (!FORCED && targetProperty !== undefined) { 1106 if (typeof sourceProperty == typeof targetProperty) continue; 1107 copyConstructorProperties(sourceProperty, targetProperty); 1108 }
vendor: 4,356 bytes, lines 1109-1291
1109 // add a flag to not completely full polyfills 1110 if (options.sham || (targetProperty && targetProperty.sham)) { 1111 createNonEnumerableProperty(sourceProperty, 'sham', true); 1112 } 1113 defineBuiltIn(target, key, sourceProperty, options); 1114 } 1115}; 1116 1117 1118/***/ }, 1119 1120/***/ 9039 1121(module) { 1122 1123 1124module.exports = function (exec) { 1125 try { 1126 return !!exec(); 1127 } catch (error) { 1128 return true; 1129 } 1130}; 1131 1132 1133/***/ }, 1134 1135/***/ 8745 1136(module, __unused_webpack_exports, __webpack_require__) { 1137 1138 1139var NATIVE_BIND = __webpack_require__(616); 1140 1141var FunctionPrototype = Function.prototype; 1142var apply = FunctionPrototype.apply; 1143var call = FunctionPrototype.call; 1144 1145// eslint-disable-next-line es/no-function-prototype-bind, es/no-reflect -- safe 1146module.exports = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call.bind(apply) : function () { 1147 return call.apply(apply, arguments); 1148}); 1149 1150 1151/***/ }, 1152 1153/***/ 6080 1154(module, __unused_webpack_exports, __webpack_require__) { 1155 1156 1157var uncurryThis = __webpack_require__(7476); 1158var aCallable = __webpack_require__(9306); 1159var NATIVE_BIND = __webpack_require__(616); 1160 1161var bind = uncurryThis(uncurryThis.bind); 1162 1163// optional / simple context binding 1164module.exports = function (fn, that) { 1165 aCallable(fn); 1166 return that === undefined ? fn : NATIVE_BIND ? bind(fn, that) : function (/* ...args */) { 1167 return fn.apply(that, arguments); 1168 }; 1169}; 1170 1171 1172/***/ }, 1173 1174/***/ 616 1175(module, __unused_webpack_exports, __webpack_require__) { 1176 1177 1178var fails = __webpack_require__(9039); 1179 1180module.exports = !fails(function () { 1181 // eslint-disable-next-line es/no-function-prototype-bind -- safe 1182 var test = function () { /* empty */ }.bind(); 1183 // eslint-disable-next-line no-prototype-builtins -- safe 1184 return typeof test != 'function' || test.hasOwnProperty('prototype'); 1185}); 1186 1187 1188/***/ }, 1189 1190/***/ 9565 1191(module, __unused_webpack_exports, __webpack_require__) { 1192 1193 1194var NATIVE_BIND = __webpack_require__(616); 1195 1196var call = Function.prototype.call; 1197// eslint-disable-next-line es/no-function-prototype-bind -- safe 1198module.exports = NATIVE_BIND ? call.bind(call) : function () { 1199 return call.apply(call, arguments); 1200}; 1201 1202 1203/***/ }, 1204 1205/***/ 350 1206(module, __unused_webpack_exports, __webpack_require__) { 1207 1208 1209var DESCRIPTORS = __webpack_require__(3724); 1210var hasOwn = __webpack_require__(9297); 1211 1212var FunctionPrototype = Function.prototype; 1213// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 1214var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor; 1215 1216var EXISTS = hasOwn(FunctionPrototype, 'name'); 1217// additional protection from minified / mangled / dropped function names 1218var PROPER = EXISTS && function something() { /* empty */ }.name === 'something'; 1219var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable)); 1220 1221module.exports = { 1222 EXISTS: EXISTS, 1223 PROPER: PROPER, 1224 CONFIGURABLE: CONFIGURABLE 1225}; 1226 1227 1228/***/ }, 1229 1230/***/ 6706 1231(module, __unused_webpack_exports, __webpack_require__) { 1232 1233 1234var uncurryThis = __webpack_require__(9504); 1235var aCallable = __webpack_require__(9306); 1236 1237module.exports = function (object, key, method) { 1238 try { 1239 // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 1240 return uncurryThis(aCallable(Object.getOwnPropertyDescriptor(object, key)[method])); 1241 } catch (error) { /* empty */ } 1242}; 1243 1244 1245/***/ }, 1246 1247/***/ 7476 1248(module, __unused_webpack_exports, __webpack_require__) { 1249 1250 1251var classofRaw = __webpack_require__(2195); 1252var uncurryThis = __webpack_require__(9504); 1253 1254module.exports = function (fn) { 1255 // Nashorn bug: 1256 // https://github.com/zloirock/core-js/issues/1128 1257 // https://github.com/zloirock/core-js/issues/1130 1258 if (classofRaw(fn) === 'Function') return uncurryThis(fn); 1259}; 1260 1261 1262/***/ }, 1263 1264/***/ 9504 1265(module, __unused_webpack_exports, __webpack_require__) { 1266 1267 1268var NATIVE_BIND = __webpack_require__(616); 1269 1270var FunctionPrototype = Function.prototype; 1271var call = FunctionPrototype.call; 1272// eslint-disable-next-line es/no-function-prototype-bind -- safe 1273var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call); 1274 1275module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) { 1276 return function () { 1277 return call.apply(fn, arguments); 1278 }; 1279}; 1280 1281 1282/***/ }, 1283 1284/***/ 944 1285(module) { 1286 1287 1288var $TypeError = TypeError; 1289 1290module.exports = function (options) { 1291 var alphabet = options && options.alphabet;
vendor: 31,982 bytes, lines 1292-2480
1292 if (alphabet === undefined || alphabet === 'base64' || alphabet === 'base64url') return alphabet || 'base64'; 1293 throw new $TypeError('Incorrect `alphabet` option'); 1294}; 1295 1296 1297/***/ }, 1298 1299/***/ 7751 1300(module, __unused_webpack_exports, __webpack_require__) { 1301 1302 1303var globalThis = __webpack_require__(4576); 1304var isCallable = __webpack_require__(4901); 1305 1306var aFunction = function (argument) { 1307 return isCallable(argument) ? argument : undefined; 1308}; 1309 1310module.exports = function (namespace, method) { 1311 return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method]; 1312}; 1313 1314 1315/***/ }, 1316 1317/***/ 1767 1318(module) { 1319 1320 1321// `GetIteratorDirect(obj)` abstract operation 1322// https://tc39.es/ecma262/#sec-getiteratordirect 1323module.exports = function (obj) { 1324 return { 1325 iterator: obj, 1326 next: obj.next, 1327 done: false 1328 }; 1329}; 1330 1331 1332/***/ }, 1333 1334/***/ 8646 1335(module, __unused_webpack_exports, __webpack_require__) { 1336 1337 1338var call = __webpack_require__(9565); 1339var anObject = __webpack_require__(8551); 1340var getIteratorDirect = __webpack_require__(1767); 1341var getIteratorMethod = __webpack_require__(3085); 1342 1343module.exports = function (obj, stringHandling) { 1344 if (!stringHandling || typeof obj !== 'string') anObject(obj); 1345 var method = getIteratorMethod(obj); 1346 return getIteratorDirect(anObject(method !== undefined ? call(method, obj) : obj)); 1347}; 1348 1349 1350/***/ }, 1351 1352/***/ 8563 1353(module, __unused_webpack_exports, __webpack_require__) { 1354 1355 1356var call = __webpack_require__(9565); 1357var isCallable = __webpack_require__(4901); 1358var anObject = __webpack_require__(8551); 1359var tryToString = __webpack_require__(6823); 1360var getIteratorMethod = __webpack_require__(3085); 1361 1362var $TypeError = TypeError; 1363 1364module.exports = function (argument, usingIterator) { 1365 var iteratorMethod = arguments.length < 2 ? getIteratorMethod(argument) : usingIterator; 1366 if (isCallable(iteratorMethod)) return anObject(call(iteratorMethod, argument)); 1367 throw new $TypeError(tryToString(argument) + ' is not iterable'); 1368}; 1369 1370 1371/***/ }, 1372 1373/***/ 3085 1374(module, __unused_webpack_exports, __webpack_require__) { 1375 1376 1377var classof = __webpack_require__(2195); 1378var isNullOrUndefined = __webpack_require__(4117); 1379var getMethod = __webpack_require__(5966); 1380var wellKnownSymbol = __webpack_require__(8227); 1381 1382var ITERATOR = wellKnownSymbol('iterator'); 1383var ArrayPrototype = Array.prototype; 1384 1385module.exports = function (it) { 1386 if (!isNullOrUndefined(it)) return getMethod(it, ITERATOR) 1387 || getMethod(it, '@@iterator') 1388 || (classof(it) === 'Arguments' ? ArrayPrototype[ITERATOR] : undefined); 1389}; 1390 1391 1392/***/ }, 1393 1394/***/ 5966 1395(module, __unused_webpack_exports, __webpack_require__) { 1396 1397 1398var aCallable = __webpack_require__(9306); 1399var isNullOrUndefined = __webpack_require__(4117); 1400 1401// `GetMethod` abstract operation 1402// https://tc39.es/ecma262/#sec-getmethod 1403module.exports = function (V, P) { 1404 var func = V[P]; 1405 return isNullOrUndefined(func) ? undefined : aCallable(func); 1406}; 1407 1408 1409/***/ }, 1410 1411/***/ 3789 1412(module, __unused_webpack_exports, __webpack_require__) { 1413 1414 1415var aCallable = __webpack_require__(9306); 1416var anObject = __webpack_require__(8551); 1417var call = __webpack_require__(9565); 1418var toIntegerOrInfinity = __webpack_require__(1291); 1419var getIteratorDirect = __webpack_require__(1767); 1420 1421var INVALID_SIZE = 'Invalid size'; 1422var $RangeError = RangeError; 1423var $TypeError = TypeError; 1424var max = Math.max; 1425 1426var SetRecord = function (set, intSize) { 1427 this.set = set; 1428 this.size = max(intSize, 0); 1429 this.has = aCallable(set.has); 1430 this.keys = aCallable(set.keys); 1431}; 1432 1433SetRecord.prototype = { 1434 getIterator: function () { 1435 return getIteratorDirect(anObject(call(this.keys, this.set))); 1436 }, 1437 includes: function (it) { 1438 return call(this.has, this.set, it); 1439 } 1440}; 1441 1442// `GetSetRecord` abstract operation 1443// https://tc39.es/proposal-set-methods/#sec-getsetrecord 1444module.exports = function (obj) { 1445 anObject(obj); 1446 var numSize = +obj.size; 1447 // NOTE: If size is undefined, then numSize will be NaN 1448 // eslint-disable-next-line no-self-compare -- NaN check 1449 if (numSize !== numSize) throw new $TypeError(INVALID_SIZE); 1450 var intSize = toIntegerOrInfinity(numSize); 1451 if (intSize < 0) throw new $RangeError(INVALID_SIZE); 1452 return new SetRecord(obj, intSize); 1453}; 1454 1455 1456/***/ }, 1457 1458/***/ 4576 1459(module) { 1460 1461 1462var check = function (it) { 1463 return it && it.Math === Math && it; 1464}; 1465 1466// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 1467module.exports = 1468 // eslint-disable-next-line es/no-global-this -- safe 1469 check(typeof globalThis == 'object' && globalThis) || 1470 check(typeof window == 'object' && window) || 1471 // eslint-disable-next-line no-restricted-globals -- safe 1472 check(typeof self == 'object' && self) || 1473 check(typeof global == 'object' && global) || 1474 check(typeof this == 'object' && this) || 1475 // eslint-disable-next-line no-new-func -- fallback 1476 (function () { return this; })() || Function('return this')(); 1477 1478 1479/***/ }, 1480 1481/***/ 9297 1482(module, __unused_webpack_exports, __webpack_require__) { 1483 1484 1485var uncurryThis = __webpack_require__(9504); 1486var toObject = __webpack_require__(8981); 1487 1488var hasOwnProperty = uncurryThis({}.hasOwnProperty); 1489 1490// `HasOwnProperty` abstract operation 1491// https://tc39.es/ecma262/#sec-hasownproperty 1492// eslint-disable-next-line es/no-object-hasown -- safe 1493module.exports = Object.hasOwn || function hasOwn(it, key) { 1494 return hasOwnProperty(toObject(it), key); 1495}; 1496 1497 1498/***/ }, 1499 1500/***/ 421 1501(module) { 1502 1503 1504module.exports = {}; 1505 1506 1507/***/ }, 1508 1509/***/ 397 1510(module, __unused_webpack_exports, __webpack_require__) { 1511 1512 1513var getBuiltIn = __webpack_require__(7751); 1514 1515module.exports = getBuiltIn('document', 'documentElement'); 1516 1517 1518/***/ }, 1519 1520/***/ 5917 1521(module, __unused_webpack_exports, __webpack_require__) { 1522 1523 1524var DESCRIPTORS = __webpack_require__(3724); 1525var fails = __webpack_require__(9039); 1526var createElement = __webpack_require__(4055); 1527 1528// Thanks to IE8 for its funny defineProperty 1529module.exports = !DESCRIPTORS && !fails(function () { 1530 // eslint-disable-next-line es/no-object-defineproperty -- required for testing 1531 return Object.defineProperty(createElement('div'), 'a', { 1532 get: function () { return 7; } 1533 }).a !== 7; 1534}); 1535 1536 1537/***/ }, 1538 1539/***/ 7055 1540(module, __unused_webpack_exports, __webpack_require__) { 1541 1542 1543var uncurryThis = __webpack_require__(9504); 1544var fails = __webpack_require__(9039); 1545var classof = __webpack_require__(2195); 1546 1547var $Object = Object; 1548var split = uncurryThis(''.split); 1549 1550// fallback for non-array-like ES3 and non-enumerable old V8 strings 1551module.exports = fails(function () { 1552 // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 1553 // eslint-disable-next-line no-prototype-builtins -- safe 1554 return !$Object('z').propertyIsEnumerable(0); 1555}) ? function (it) { 1556 return classof(it) === 'String' ? split(it, '') : $Object(it); 1557} : $Object; 1558 1559 1560/***/ }, 1561 1562/***/ 3167 1563(module, __unused_webpack_exports, __webpack_require__) { 1564 1565 1566var isCallable = __webpack_require__(4901); 1567var isObject = __webpack_require__(34); 1568var setPrototypeOf = __webpack_require__(2967); 1569 1570// makes subclassing work correct for wrapped built-ins 1571module.exports = function ($this, dummy, Wrapper) { 1572 var NewTarget, NewTargetPrototype; 1573 if ( 1574 // it can work only with native `setPrototypeOf` 1575 setPrototypeOf && 1576 // we haven't completely correct pre-ES6 way for getting `new.target`, so use this 1577 isCallable(NewTarget = dummy.constructor) && 1578 NewTarget !== Wrapper && 1579 isObject(NewTargetPrototype = NewTarget.prototype) && 1580 NewTargetPrototype !== Wrapper.prototype 1581 ) setPrototypeOf($this, NewTargetPrototype); 1582 return $this; 1583}; 1584 1585 1586/***/ }, 1587 1588/***/ 3706 1589(module, __unused_webpack_exports, __webpack_require__) { 1590 1591 1592var uncurryThis = __webpack_require__(9504); 1593var isCallable = __webpack_require__(4901); 1594var store = __webpack_require__(7629); 1595 1596var functionToString = uncurryThis(Function.toString); 1597 1598// this helper broken in `[email protected]`, so we can't use `shared` helper 1599if (!isCallable(store.inspectSource)) { 1600 store.inspectSource = function (it) { 1601 return functionToString(it); 1602 }; 1603} 1604 1605module.exports = store.inspectSource; 1606 1607 1608/***/ }, 1609 1610/***/ 1181 1611(module, __unused_webpack_exports, __webpack_require__) { 1612 1613 1614var NATIVE_WEAK_MAP = __webpack_require__(8622); 1615var globalThis = __webpack_require__(4576); 1616var isObject = __webpack_require__(34); 1617var createNonEnumerableProperty = __webpack_require__(6699); 1618var hasOwn = __webpack_require__(9297); 1619var shared = __webpack_require__(7629); 1620var sharedKey = __webpack_require__(6119); 1621var hiddenKeys = __webpack_require__(421); 1622 1623var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; 1624var TypeError = globalThis.TypeError; 1625var WeakMap = globalThis.WeakMap; 1626var set, get, has; 1627 1628var enforce = function (it) { 1629 return has(it) ? get(it) : set(it, {}); 1630}; 1631 1632var getterFor = function (TYPE) { 1633 return function (it) { 1634 var state; 1635 if (!isObject(it) || (state = get(it)).type !== TYPE) { 1636 throw new TypeError('Incompatible receiver, ' + TYPE + ' required'); 1637 } return state; 1638 }; 1639}; 1640 1641if (NATIVE_WEAK_MAP || shared.state) { 1642 var store = shared.state || (shared.state = new WeakMap()); 1643 /* eslint-disable no-self-assign -- prototype methods protection */ 1644 store.get = store.get; 1645 store.has = store.has; 1646 store.set = store.set; 1647 /* eslint-enable no-self-assign -- prototype methods protection */ 1648 set = function (it, metadata) { 1649 if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); 1650 metadata.facade = it; 1651 store.set(it, metadata); 1652 return metadata; 1653 }; 1654 get = function (it) { 1655 return store.get(it) || {}; 1656 }; 1657 has = function (it) { 1658 return store.has(it); 1659 }; 1660} else { 1661 var STATE = sharedKey('state'); 1662 hiddenKeys[STATE] = true; 1663 set = function (it, metadata) { 1664 if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); 1665 metadata.facade = it; 1666 createNonEnumerableProperty(it, STATE, metadata); 1667 return metadata; 1668 }; 1669 get = function (it) { 1670 return hasOwn(it, STATE) ? it[STATE] : {}; 1671 }; 1672 has = function (it) { 1673 return hasOwn(it, STATE); 1674 }; 1675} 1676 1677module.exports = { 1678 set: set, 1679 get: get, 1680 has: has, 1681 enforce: enforce, 1682 getterFor: getterFor 1683}; 1684 1685 1686/***/ }, 1687 1688/***/ 4209 1689(module, __unused_webpack_exports, __webpack_require__) { 1690 1691 1692var wellKnownSymbol = __webpack_require__(8227); 1693var Iterators = __webpack_require__(6269); 1694 1695var ITERATOR = wellKnownSymbol('iterator'); 1696var ArrayPrototype = Array.prototype; 1697 1698// check on default Array iterator 1699module.exports = function (it) { 1700 return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it); 1701}; 1702 1703 1704/***/ }, 1705 1706/***/ 4376 1707(module, __unused_webpack_exports, __webpack_require__) { 1708 1709 1710var classof = __webpack_require__(2195); 1711 1712// `IsArray` abstract operation 1713// https://tc39.es/ecma262/#sec-isarray 1714// eslint-disable-next-line es/no-array-isarray -- safe 1715module.exports = Array.isArray || function isArray(argument) { 1716 return classof(argument) === 'Array'; 1717}; 1718 1719 1720/***/ }, 1721 1722/***/ 1108 1723(module, __unused_webpack_exports, __webpack_require__) { 1724 1725 1726var classof = __webpack_require__(6955); 1727 1728module.exports = function (it) { 1729 var klass = classof(it); 1730 return klass === 'BigInt64Array' || klass === 'BigUint64Array'; 1731}; 1732 1733 1734/***/ }, 1735 1736/***/ 4901 1737(module) { 1738 1739 1740// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot 1741var documentAll = typeof document == 'object' && document.all; 1742 1743// `IsCallable` abstract operation 1744// https://tc39.es/ecma262/#sec-iscallable 1745// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing 1746module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) { 1747 return typeof argument == 'function' || argument === documentAll; 1748} : function (argument) { 1749 return typeof argument == 'function'; 1750}; 1751 1752 1753/***/ }, 1754 1755/***/ 2796 1756(module, __unused_webpack_exports, __webpack_require__) { 1757 1758 1759var fails = __webpack_require__(9039); 1760var isCallable = __webpack_require__(4901); 1761 1762var replacement = /#|\.prototype\./; 1763 1764var isForced = function (feature, detection) { 1765 var value = data[normalize(feature)]; 1766 return value === POLYFILL ? true 1767 : value === NATIVE ? false 1768 : isCallable(detection) ? fails(detection) 1769 : !!detection; 1770}; 1771 1772var normalize = isForced.normalize = function (string) { 1773 return String(string).replace(replacement, '.').toLowerCase(); 1774}; 1775 1776var data = isForced.data = {}; 1777var NATIVE = isForced.NATIVE = 'N'; 1778var POLYFILL = isForced.POLYFILL = 'P'; 1779 1780module.exports = isForced; 1781 1782 1783/***/ }, 1784 1785/***/ 4117 1786(module) { 1787 1788 1789// we can't use just `it == null` since of `document.all` special case 1790// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec 1791module.exports = function (it) { 1792 return it === null || it === undefined; 1793}; 1794 1795 1796/***/ }, 1797 1798/***/ 34 1799(module, __unused_webpack_exports, __webpack_require__) { 1800 1801 1802var isCallable = __webpack_require__(4901); 1803 1804module.exports = function (it) { 1805 return typeof it == 'object' ? it !== null : isCallable(it); 1806}; 1807 1808 1809/***/ }, 1810 1811/***/ 3925 1812(module, __unused_webpack_exports, __webpack_require__) { 1813 1814 1815var isObject = __webpack_require__(34); 1816 1817module.exports = function (argument) { 1818 return isObject(argument) || argument === null; 1819}; 1820 1821 1822/***/ }, 1823 1824/***/ 6395 1825(module) { 1826 1827 1828module.exports = false; 1829 1830 1831/***/ }, 1832 1833/***/ 5810 1834(module, __unused_webpack_exports, __webpack_require__) { 1835 1836 1837var isObject = __webpack_require__(34); 1838var getInternalState = (__webpack_require__(1181).get); 1839 1840module.exports = function isRawJSON(O) { 1841 if (!isObject(O)) return false; 1842 var state = getInternalState(O); 1843 return !!state && state.type === 'RawJSON'; 1844}; 1845 1846 1847/***/ }, 1848 1849/***/ 757 1850(module, __unused_webpack_exports, __webpack_require__) { 1851 1852 1853var getBuiltIn = __webpack_require__(7751); 1854var isCallable = __webpack_require__(4901); 1855var isPrototypeOf = __webpack_require__(1625); 1856var USE_SYMBOL_AS_UID = __webpack_require__(7040); 1857 1858var $Object = Object; 1859 1860module.exports = USE_SYMBOL_AS_UID ? function (it) { 1861 return typeof it == 'symbol'; 1862} : function (it) { 1863 var $Symbol = getBuiltIn('Symbol'); 1864 return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); 1865}; 1866 1867 1868/***/ }, 1869 1870/***/ 507 1871(module, __unused_webpack_exports, __webpack_require__) { 1872 1873 1874var call = __webpack_require__(9565); 1875 1876module.exports = function (record, fn, ITERATOR_INSTEAD_OF_RECORD) { 1877 var iterator = ITERATOR_INSTEAD_OF_RECORD ? record : record.iterator; 1878 var next = record.next; 1879 var step, result; 1880 while (!(step = call(next, iterator)).done) { 1881 result = fn(step.value); 1882 if (result !== undefined) return result; 1883 } 1884}; 1885 1886 1887/***/ }, 1888 1889/***/ 2652 1890(module, __unused_webpack_exports, __webpack_require__) { 1891 1892 1893var bind = __webpack_require__(6080); 1894var call = __webpack_require__(9565); 1895var anObject = __webpack_require__(8551); 1896var tryToString = __webpack_require__(6823); 1897var isArrayIteratorMethod = __webpack_require__(4209); 1898var lengthOfArrayLike = __webpack_require__(6198); 1899var isPrototypeOf = __webpack_require__(1625); 1900var getIterator = __webpack_require__(8563); 1901var getIteratorMethod = __webpack_require__(3085); 1902var iteratorClose = __webpack_require__(9539); 1903 1904var $TypeError = TypeError; 1905 1906var Result = function (stopped, result) { 1907 this.stopped = stopped; 1908 this.result = result; 1909}; 1910 1911var ResultPrototype = Result.prototype; 1912 1913module.exports = function (iterable, unboundFunction, options) { 1914 var that = options && options.that; 1915 var AS_ENTRIES = !!(options && options.AS_ENTRIES); 1916 var IS_RECORD = !!(options && options.IS_RECORD); 1917 var IS_ITERATOR = !!(options && options.IS_ITERATOR); 1918 var INTERRUPTED = !!(options && options.INTERRUPTED); 1919 var fn = bind(unboundFunction, that); 1920 var iterator, iterFn, index, length, result, next, step; 1921 1922 var stop = function (condition) { 1923 var $iterator = iterator; 1924 iterator = undefined; 1925 if ($iterator) iteratorClose($iterator, 'normal'); 1926 return new Result(true, condition); 1927 }; 1928 1929 var callFn = function (value) { 1930 if (AS_ENTRIES) { 1931 anObject(value); 1932 return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); 1933 } return INTERRUPTED ? fn(value, stop) : fn(value); 1934 }; 1935 1936 if (IS_RECORD) { 1937 iterator = iterable.iterator; 1938 } else if (IS_ITERATOR) { 1939 iterator = iterable; 1940 } else { 1941 iterFn = getIteratorMethod(iterable); 1942 if (!iterFn) throw new $TypeError(tryToString(iterable) + ' is not iterable'); 1943 // optimisation for array iterators 1944 if (isArrayIteratorMethod(iterFn)) { 1945 for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) { 1946 result = callFn(iterable[index]); 1947 if (result && isPrototypeOf(ResultPrototype, result)) return result; 1948 } return new Result(false); 1949 } 1950 iterator = getIterator(iterable, iterFn); 1951 } 1952 1953 next = IS_RECORD ? iterable.next : iterator.next; 1954 while (!(step = call(next, iterator)).done) { 1955 // `IteratorValue` errors should propagate without closing the iterator 1956 var value = step.value; 1957 try { 1958 result = callFn(value); 1959 } catch (error) { 1960 if (iterator) iteratorClose(iterator, 'throw', error); 1961 else throw error; 1962 } 1963 if (typeof result == 'object' && result && isPrototypeOf(ResultPrototype, result)) return result; 1964 } return new Result(false); 1965}; 1966 1967 1968/***/ }, 1969 1970/***/ 6859 1971(module) { 1972 1973 1974// release references held by exhausted / closed iterator helpers to allow GC of the source chain 1975module.exports = function (state) { 1976 state.iterator = state.next = state.nextHandler = state.mapper = state.predicate = state.inner = 1977 state.iterables = state.iters = state.openIters = state.padding = state.finishResults = state.buffer = null; 1978}; 1979 1980 1981/***/ }, 1982 1983/***/ 1385 1984(module, __unused_webpack_exports, __webpack_require__) { 1985 1986 1987var iteratorClose = __webpack_require__(9539); 1988 1989module.exports = function (iters, kind, value) { 1990 for (var i = iters.length - 1; i >= 0; i--) { 1991 if (iters[i] === undefined) continue; 1992 try { 1993 value = iteratorClose(iters[i].iterator, kind, value); 1994 } catch (error) { 1995 kind = 'throw'; 1996 value = error; 1997 } 1998 } 1999 if (kind === 'throw') throw value; 2000 return value; 2001}; 2002 2003 2004/***/ }, 2005 2006/***/ 9539 2007(module, __unused_webpack_exports, __webpack_require__) { 2008 2009 2010var call = __webpack_require__(9565); 2011var anObject = __webpack_require__(8551); 2012var getMethod = __webpack_require__(5966); 2013 2014module.exports = function (iterator, kind, value) { 2015 var innerResult, innerError; 2016 anObject(iterator); 2017 try { 2018 innerResult = getMethod(iterator, 'return'); 2019 if (!innerResult) { 2020 if (kind === 'throw') throw value; 2021 return value; 2022 } 2023 innerResult = call(innerResult, iterator); 2024 } catch (error) { 2025 innerError = true; 2026 innerResult = error; 2027 } 2028 if (kind === 'throw') throw value; 2029 if (innerError) throw innerResult; 2030 anObject(innerResult); 2031 return value; 2032}; 2033 2034 2035/***/ }, 2036 2037/***/ 9462 2038(module, __unused_webpack_exports, __webpack_require__) { 2039 2040 2041var call = __webpack_require__(9565); 2042var create = __webpack_require__(2360); 2043var createNonEnumerableProperty = __webpack_require__(6699); 2044var defineBuiltIns = __webpack_require__(6279); 2045var wellKnownSymbol = __webpack_require__(8227); 2046var InternalStateModule = __webpack_require__(1181); 2047var getMethod = __webpack_require__(5966); 2048var IteratorPrototype = (__webpack_require__(7657).IteratorPrototype); 2049var createIterResultObject = __webpack_require__(2529); 2050var iteratorClose = __webpack_require__(9539); 2051var iteratorCloseAll = __webpack_require__(1385); 2052var cleanupState = __webpack_require__(6859); 2053 2054var TO_STRING_TAG = wellKnownSymbol('toStringTag'); 2055var ITERATOR_HELPER = 'IteratorHelper'; 2056var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator'; 2057var NORMAL = 'normal'; 2058var THROW = 'throw'; 2059var setInternalState = InternalStateModule.set; 2060 2061var createIteratorProxyPrototype = function (IS_ITERATOR) { 2062 var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER); 2063 2064 return defineBuiltIns(create(IteratorPrototype), { 2065 next: function next() { 2066 var state = getInternalState(this); 2067 // for simplification: 2068 // for `%WrapForValidIteratorPrototype%.next` or with `state.returnHandlerResult` our `nextHandler` returns `IterResultObject` 2069 // for `%IteratorHelperPrototype%.next` - just a value 2070 if (IS_ITERATOR) return state.nextHandler(); 2071 if (state.done) return createIterResultObject(undefined, true); 2072 try { 2073 var result = state.nextHandler(); 2074 if (state.done) cleanupState(state); 2075 return state.returnHandlerResult ? result : createIterResultObject(result, state.done); 2076 } catch (error) { 2077 state.done = true; 2078 cleanupState(state); 2079 throw error; 2080 } 2081 }, 2082 'return': function () { 2083 var state = getInternalState(this); 2084 var iterator = state.iterator; 2085 var inner = state.inner; 2086 var openIters = state.openIters; 2087 var done = state.done; 2088 state.done = true; 2089 if (IS_ITERATOR) { 2090 var returnMethod = getMethod(iterator, 'return'); 2091 return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true); 2092 } 2093 cleanupState(state); 2094 if (done) return createIterResultObject(undefined, true); 2095 if (inner) try { 2096 iteratorClose(inner.iterator, NORMAL); 2097 } catch (error) { 2098 return iteratorClose(iterator, THROW, error); 2099 } 2100 if (openIters) try { 2101 iteratorCloseAll(openIters, NORMAL); 2102 } catch (error) { 2103 if (iterator) return iteratorClose(iterator, THROW, error); 2104 throw error; 2105 } 2106 if (iterator) iteratorClose(iterator, NORMAL); 2107 return createIterResultObject(undefined, true); 2108 } 2109 }); 2110}; 2111 2112var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true); 2113var IteratorHelperPrototype = createIteratorProxyPrototype(false); 2114 2115createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper'); 2116 2117module.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) { 2118 var IteratorProxy = function Iterator(record, state) { 2119 if (state) { 2120 state.iterator = record.iterator; 2121 state.next = record.next; 2122 } else state = record; 2123 state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER; 2124 state.returnHandlerResult = !!RETURN_HANDLER_RESULT; 2125 state.nextHandler = nextHandler; 2126 state.counter = 0; 2127 state.done = false; 2128 setInternalState(this, state); 2129 }; 2130 2131 IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype; 2132 2133 return IteratorProxy; 2134}; 2135 2136 2137/***/ }, 2138 2139/***/ 684 2140(module) { 2141 2142 2143// Should throw an error on invalid iterator 2144// https://issues.chromium.org/issues/336839115 2145module.exports = function (methodName, argument) { 2146 // eslint-disable-next-line es/no-iterator -- required for testing 2147 var method = typeof Iterator == 'function' && Iterator.prototype[methodName]; 2148 if (method) try { 2149 method.call({ next: null }, argument).next(); 2150 } catch (error) { 2151 return true; 2152 } 2153}; 2154 2155 2156/***/ }, 2157 2158/***/ 4549 2159(module, __unused_webpack_exports, __webpack_require__) { 2160 2161 2162var globalThis = __webpack_require__(4576); 2163 2164// https://github.com/tc39/ecma262/pull/3467 2165module.exports = function (METHOD_NAME, ExpectedError) { 2166 var Iterator = globalThis.Iterator; 2167 var IteratorPrototype = Iterator && Iterator.prototype; 2168 var method = IteratorPrototype && IteratorPrototype[METHOD_NAME]; 2169 2170 var CLOSED = false; 2171 2172 if (method) try { 2173 method.call({ 2174 next: function () { return { done: true }; }, 2175 'return': function () { CLOSED = true; } 2176 }, -1); 2177 } catch (error) { 2178 // https://bugs.webkit.org/show_bug.cgi?id=291195 2179 if (!(error instanceof ExpectedError)) CLOSED = false; 2180 } 2181 2182 if (!CLOSED) return method; 2183}; 2184 2185 2186/***/ }, 2187 2188/***/ 7657 2189(module, __unused_webpack_exports, __webpack_require__) { 2190 2191 2192var fails = __webpack_require__(9039); 2193var isCallable = __webpack_require__(4901); 2194var isObject = __webpack_require__(34); 2195var create = __webpack_require__(2360); 2196var getPrototypeOf = __webpack_require__(2787); 2197var defineBuiltIn = __webpack_require__(6840); 2198var wellKnownSymbol = __webpack_require__(8227); 2199var IS_PURE = __webpack_require__(6395); 2200 2201var ITERATOR = wellKnownSymbol('iterator'); 2202var BUGGY_SAFARI_ITERATORS = false; 2203 2204// `%IteratorPrototype%` object 2205// https://tc39.es/ecma262/#sec-%iteratorprototype%-object 2206var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator; 2207 2208/* eslint-disable es/no-array-prototype-keys -- safe */ 2209if ([].keys) { 2210 arrayIterator = [].keys(); 2211 // Safari 8 has buggy iterators w/o `next` 2212 if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true; 2213 else { 2214 PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator)); 2215 if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype; 2216 } 2217} 2218 2219var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype) || fails(function () { 2220 var test = {}; 2221 // FF44- legacy iterators case 2222 return IteratorPrototype[ITERATOR].call(test) !== test; 2223}); 2224 2225if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {}; 2226else if (IS_PURE) IteratorPrototype = create(IteratorPrototype); 2227 2228// `%IteratorPrototype%[@@iterator]()` method 2229// https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator 2230if (!isCallable(IteratorPrototype[ITERATOR])) { 2231 defineBuiltIn(IteratorPrototype, ITERATOR, function () { 2232 return this; 2233 }); 2234} 2235 2236module.exports = { 2237 IteratorPrototype: IteratorPrototype, 2238 BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS 2239}; 2240 2241 2242/***/ }, 2243 2244/***/ 6269 2245(module) { 2246 2247 2248module.exports = Object.create ? Object.create(null) : {}; 2249 2250 2251/***/ }, 2252 2253/***/ 6198 2254(module, __unused_webpack_exports, __webpack_require__) { 2255 2256 2257var toLength = __webpack_require__(8014); 2258 2259// `LengthOfArrayLike` abstract operation 2260// https://tc39.es/ecma262/#sec-lengthofarraylike 2261module.exports = function (obj) { 2262 return toLength(obj.length); 2263}; 2264 2265 2266/***/ }, 2267 2268/***/ 283 2269(module, __unused_webpack_exports, __webpack_require__) { 2270 2271 2272var uncurryThis = __webpack_require__(9504); 2273var fails = __webpack_require__(9039); 2274var isCallable = __webpack_require__(4901); 2275var hasOwn = __webpack_require__(9297); 2276var DESCRIPTORS = __webpack_require__(3724); 2277var CONFIGURABLE_FUNCTION_NAME = (__webpack_require__(350).CONFIGURABLE); 2278var inspectSource = __webpack_require__(3706); 2279var InternalStateModule = __webpack_require__(1181); 2280 2281var enforceInternalState = InternalStateModule.enforce; 2282var getInternalState = InternalStateModule.get; 2283var $String = String; 2284// eslint-disable-next-line es/no-object-defineproperty -- safe 2285var defineProperty = Object.defineProperty; 2286var stringSlice = uncurryThis(''.slice); 2287var replace = uncurryThis(''.replace); 2288var join = uncurryThis([].join); 2289 2290var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () { 2291 return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; 2292}); 2293 2294var TEMPLATE = String(String).split('String'); 2295 2296var makeBuiltIn = module.exports = function (value, name, options) { 2297 if (stringSlice($String(name), 0, 7) === 'Symbol(') { 2298 name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']'; 2299 } 2300 if (options && options.getter) name = 'get ' + name; 2301 if (options && options.setter) name = 'set ' + name; 2302 if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) { 2303 if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true }); 2304 else value.name = name; 2305 } 2306 if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { 2307 defineProperty(value, 'length', { value: options.arity }); 2308 } 2309 try { 2310 if (options && hasOwn(options, 'constructor') && options.constructor) { 2311 if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false }); 2312 // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable 2313 } else if (value.prototype) value.prototype = undefined; 2314 } catch (error) { /* empty */ } 2315 var state = enforceInternalState(value); 2316 if (!hasOwn(state, 'source')) { 2317 state.source = join(TEMPLATE, typeof name == 'string' ? name : ''); 2318 } return value; 2319}; 2320 2321// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative 2322// eslint-disable-next-line no-extend-native -- required 2323Function.prototype.toString = makeBuiltIn(function toString() { 2324 return isCallable(this) && getInternalState(this).source || inspectSource(this); 2325}, 'toString'); 2326 2327 2328/***/ }, 2329 2330/***/ 2248 2331(module, __unused_webpack_exports, __webpack_require__) { 2332 2333 2334var uncurryThis = __webpack_require__(9504); 2335 2336// eslint-disable-next-line es/no-map -- safe 2337var MapPrototype = Map.prototype; 2338 2339module.exports = { 2340 // eslint-disable-next-line es/no-map -- safe 2341 Map: Map, 2342 set: uncurryThis(MapPrototype.set), 2343 get: uncurryThis(MapPrototype.get), 2344 has: uncurryThis(MapPrototype.has), 2345 remove: uncurryThis(MapPrototype['delete']), 2346 proto: MapPrototype 2347}; 2348 2349 2350/***/ }, 2351 2352/***/ 741 2353(module) { 2354 2355 2356var ceil = Math.ceil; 2357var floor = Math.floor; 2358 2359// `Math.trunc` method 2360// https://tc39.es/ecma262/#sec-math.trunc 2361// eslint-disable-next-line es/no-math-trunc -- safe 2362module.exports = Math.trunc || function trunc(x) { 2363 var n = +x; 2364 return (n > 0 ? floor : ceil)(n); 2365}; 2366 2367 2368/***/ }, 2369 2370/***/ 7819 2371(module, __unused_webpack_exports, __webpack_require__) { 2372 2373 2374/* eslint-disable es/no-json -- safe */ 2375var fails = __webpack_require__(9039); 2376 2377module.exports = !fails(function () { 2378 var unsafeInt = '9007199254740993'; 2379 // eslint-disable-next-line es/no-json-rawjson -- feature detection 2380 var raw = JSON.rawJSON(unsafeInt); 2381 // eslint-disable-next-line es/no-json-israwjson -- feature detection 2382 return !JSON.isRawJSON(raw) || JSON.stringify(raw) !== unsafeInt; 2383}); 2384 2385 2386/***/ }, 2387 2388/***/ 6043 2389(module, __unused_webpack_exports, __webpack_require__) { 2390 2391 2392var aCallable = __webpack_require__(9306); 2393 2394var $TypeError = TypeError; 2395 2396var PromiseCapability = function (C) { 2397 var resolve, reject; 2398 this.promise = new C(function ($$resolve, $$reject) { 2399 if (resolve !== undefined || reject !== undefined) throw new $TypeError('Bad Promise constructor'); 2400 resolve = $$resolve; 2401 reject = $$reject; 2402 }); 2403 this.resolve = aCallable(resolve); 2404 this.reject = aCallable(reject); 2405}; 2406 2407// `NewPromiseCapability` abstract operation 2408// https://tc39.es/ecma262/#sec-newpromisecapability 2409module.exports.f = function (C) { 2410 return new PromiseCapability(C); 2411}; 2412 2413 2414/***/ }, 2415 2416/***/ 2603 2417(module, __unused_webpack_exports, __webpack_require__) { 2418 2419 2420var toString = __webpack_require__(655); 2421 2422module.exports = function (argument, $default) { 2423 return argument === undefined ? arguments.length < 2 ? '' : $default : toString(argument); 2424}; 2425 2426 2427/***/ }, 2428 2429/***/ 4149 2430(module) { 2431 2432 2433var $RangeError = RangeError; 2434 2435module.exports = function (it) { 2436 // eslint-disable-next-line no-self-compare -- NaN check 2437 if (it === it) return it; 2438 throw new $RangeError('NaN is not allowed'); 2439}; 2440 2441 2442/***/ }, 2443 2444/***/ 2360 2445(module, __unused_webpack_exports, __webpack_require__) { 2446 2447 2448/* global ActiveXObject -- old IE, WSH */ 2449var anObject = __webpack_require__(8551); 2450var definePropertiesModule = __webpack_require__(6801); 2451var enumBugKeys = __webpack_require__(8727); 2452var hiddenKeys = __webpack_require__(421); 2453var html = __webpack_require__(397); 2454var documentCreateElement = __webpack_require__(4055); 2455var sharedKey = __webpack_require__(6119); 2456 2457var GT = '>'; 2458var LT = '<'; 2459var PROTOTYPE = 'prototype'; 2460var SCRIPT = 'script'; 2461var IE_PROTO = sharedKey('IE_PROTO'); 2462 2463var EmptyConstructor = function () { /* empty */ }; 2464 2465var scriptTag = function (content) { 2466 return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; 2467}; 2468 2469// Create object with fake `null` prototype: use ActiveX Object with cleared prototype 2470var NullProtoObjectViaActiveX = function (activeXDocument) { 2471 activeXDocument.write(scriptTag('')); 2472 activeXDocument.close(); 2473 var temp = activeXDocument.parentWindow.Object; 2474 // eslint-disable-next-line no-useless-assignment -- avoid memory leak 2475 activeXDocument = null; 2476 return temp; 2477}; 2478 2479// Create object with fake `null` prototype: use iframe Object with cleared prototype 2480var NullProtoObjectViaIFrame = function () {
vendor: 11,602 bytes, lines 2481-2848
2481 // Thrash, waste and sodomy: IE GC bug 2482 var iframe = documentCreateElement('iframe'); 2483 var JS = 'java' + SCRIPT + ':'; 2484 var iframeDocument; 2485 iframe.style.display = 'none'; 2486 html.appendChild(iframe); 2487 // https://github.com/zloirock/core-js/issues/475 2488 iframe.src = String(JS); 2489 iframeDocument = iframe.contentWindow.document; 2490 iframeDocument.open(); 2491 iframeDocument.write(scriptTag('document.F=Object')); 2492 iframeDocument.close(); 2493 return iframeDocument.F; 2494}; 2495 2496// Check for document.domain and active x support 2497// No need to use active x approach when document.domain is not set 2498// see https://github.com/es-shims/es5-shim/issues/150 2499// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 2500// avoid IE GC bug 2501var activeXDocument; 2502var NullProtoObject = function () { 2503 try { 2504 activeXDocument = new ActiveXObject('htmlfile'); 2505 } catch (error) { /* ignore */ } 2506 NullProtoObject = typeof document != 'undefined' 2507 ? document.domain && activeXDocument 2508 ? NullProtoObjectViaActiveX(activeXDocument) // old IE 2509 : NullProtoObjectViaIFrame() 2510 : NullProtoObjectViaActiveX(activeXDocument); // WSH 2511 var length = enumBugKeys.length; 2512 while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; 2513 return NullProtoObject(); 2514}; 2515 2516hiddenKeys[IE_PROTO] = true; 2517 2518// `Object.create` method 2519// https://tc39.es/ecma262/#sec-object.create 2520// eslint-disable-next-line es/no-object-create -- safe 2521module.exports = Object.create || function create(O, Properties) { 2522 var result; 2523 if (O !== null) { 2524 EmptyConstructor[PROTOTYPE] = anObject(O); 2525 result = new EmptyConstructor(); 2526 EmptyConstructor[PROTOTYPE] = null; 2527 // add "__proto__" for Object.getPrototypeOf polyfill 2528 result[IE_PROTO] = O; 2529 } else result = NullProtoObject(); 2530 return Properties === undefined ? result : definePropertiesModule.f(result, Properties); 2531}; 2532 2533 2534/***/ }, 2535 2536/***/ 6801 2537(__unused_webpack_module, exports, __webpack_require__) { 2538 2539 2540var DESCRIPTORS = __webpack_require__(3724); 2541var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(8686); 2542var definePropertyModule = __webpack_require__(4913); 2543var anObject = __webpack_require__(8551); 2544var toIndexedObject = __webpack_require__(5397); 2545var objectKeys = __webpack_require__(1072); 2546 2547// `Object.defineProperties` method 2548// https://tc39.es/ecma262/#sec-object.defineproperties 2549// eslint-disable-next-line es/no-object-defineproperties -- safe 2550exports.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) { 2551 anObject(O); 2552 var props = toIndexedObject(Properties); 2553 var keys = objectKeys(Properties); 2554 var length = keys.length; 2555 var index = 0; 2556 var key; 2557 while (length > index) definePropertyModule.f(O, key = keys[index++], props[key]); 2558 return O; 2559}; 2560 2561 2562/***/ }, 2563 2564/***/ 4913 2565(__unused_webpack_module, exports, __webpack_require__) { 2566 2567 2568var DESCRIPTORS = __webpack_require__(3724); 2569var IE8_DOM_DEFINE = __webpack_require__(5917); 2570var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(8686); 2571var anObject = __webpack_require__(8551); 2572var toPropertyKey = __webpack_require__(6969); 2573 2574var $TypeError = TypeError; 2575// eslint-disable-next-line es/no-object-defineproperty -- safe 2576var $defineProperty = Object.defineProperty; 2577// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 2578var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 2579var ENUMERABLE = 'enumerable'; 2580var CONFIGURABLE = 'configurable'; 2581var WRITABLE = 'writable'; 2582 2583// `Object.defineProperty` method 2584// https://tc39.es/ecma262/#sec-object.defineproperty 2585exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { 2586 anObject(O); 2587 P = toPropertyKey(P); 2588 anObject(Attributes); 2589 if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { 2590 var current = $getOwnPropertyDescriptor(O, P); 2591 if (current && current[WRITABLE]) { 2592 O[P] = Attributes.value; 2593 Attributes = { 2594 configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], 2595 enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], 2596 writable: false 2597 }; 2598 } 2599 } return $defineProperty(O, P, Attributes); 2600} : $defineProperty : function defineProperty(O, P, Attributes) { 2601 anObject(O); 2602 P = toPropertyKey(P); 2603 anObject(Attributes); 2604 if (IE8_DOM_DEFINE) try { 2605 return $defineProperty(O, P, Attributes); 2606 } catch (error) { /* empty */ } 2607 if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported'); 2608 if ('value' in Attributes) O[P] = Attributes.value; 2609 return O; 2610}; 2611 2612 2613/***/ }, 2614 2615/***/ 7347 2616(__unused_webpack_module, exports, __webpack_require__) { 2617 2618 2619var DESCRIPTORS = __webpack_require__(3724); 2620var call = __webpack_require__(9565); 2621var propertyIsEnumerableModule = __webpack_require__(8773); 2622var createPropertyDescriptor = __webpack_require__(6980); 2623var toIndexedObject = __webpack_require__(5397); 2624var toPropertyKey = __webpack_require__(6969); 2625var hasOwn = __webpack_require__(9297); 2626var IE8_DOM_DEFINE = __webpack_require__(5917); 2627 2628// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 2629var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 2630 2631// `Object.getOwnPropertyDescriptor` method 2632// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor 2633exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { 2634 O = toIndexedObject(O); 2635 P = toPropertyKey(P); 2636 if (IE8_DOM_DEFINE) try { 2637 return $getOwnPropertyDescriptor(O, P); 2638 } catch (error) { /* empty */ } 2639 if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]); 2640}; 2641 2642 2643/***/ }, 2644 2645/***/ 8480 2646(__unused_webpack_module, exports, __webpack_require__) { 2647 2648 2649var internalObjectKeys = __webpack_require__(1828); 2650var enumBugKeys = __webpack_require__(8727); 2651 2652var hiddenKeys = enumBugKeys.concat('length', 'prototype'); 2653 2654// `Object.getOwnPropertyNames` method 2655// https://tc39.es/ecma262/#sec-object.getownpropertynames 2656// eslint-disable-next-line es/no-object-getownpropertynames -- safe 2657exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { 2658 return internalObjectKeys(O, hiddenKeys); 2659}; 2660 2661 2662/***/ }, 2663 2664/***/ 3717 2665(__unused_webpack_module, exports) { 2666 2667 2668// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe 2669exports.f = Object.getOwnPropertySymbols; 2670 2671 2672/***/ }, 2673 2674/***/ 2787 2675(module, __unused_webpack_exports, __webpack_require__) { 2676 2677 2678var hasOwn = __webpack_require__(9297); 2679var isCallable = __webpack_require__(4901); 2680var toObject = __webpack_require__(8981); 2681var sharedKey = __webpack_require__(6119); 2682var CORRECT_PROTOTYPE_GETTER = __webpack_require__(2211); 2683 2684var IE_PROTO = sharedKey('IE_PROTO'); 2685var $Object = Object; 2686var ObjectPrototype = $Object.prototype; 2687 2688// `Object.getPrototypeOf` method 2689// https://tc39.es/ecma262/#sec-object.getprototypeof 2690// eslint-disable-next-line es/no-object-getprototypeof -- safe 2691module.exports = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) { 2692 var object = toObject(O); 2693 if (hasOwn(object, IE_PROTO)) return object[IE_PROTO]; 2694 var constructor = object.constructor; 2695 if (isCallable(constructor) && object instanceof constructor) { 2696 return constructor.prototype; 2697 } return object instanceof $Object ? ObjectPrototype : null; 2698}; 2699 2700 2701/***/ }, 2702 2703/***/ 1625 2704(module, __unused_webpack_exports, __webpack_require__) { 2705 2706 2707var uncurryThis = __webpack_require__(9504); 2708 2709module.exports = uncurryThis({}.isPrototypeOf); 2710 2711 2712/***/ }, 2713 2714/***/ 1828 2715(module, __unused_webpack_exports, __webpack_require__) { 2716 2717 2718var uncurryThis = __webpack_require__(9504); 2719var hasOwn = __webpack_require__(9297); 2720var toIndexedObject = __webpack_require__(5397); 2721var indexOf = (__webpack_require__(9617).indexOf); 2722var hiddenKeys = __webpack_require__(421); 2723 2724var push = uncurryThis([].push); 2725 2726module.exports = function (object, names) { 2727 var O = toIndexedObject(object); 2728 var i = 0; 2729 var result = []; 2730 var key; 2731 for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key); 2732 // Don't enum bug & hidden keys 2733 while (names.length > i) if (hasOwn(O, key = names[i++])) { 2734 ~indexOf(result, key) || push(result, key); 2735 } 2736 return result; 2737}; 2738 2739 2740/***/ }, 2741 2742/***/ 1072 2743(module, __unused_webpack_exports, __webpack_require__) { 2744 2745 2746var internalObjectKeys = __webpack_require__(1828); 2747var enumBugKeys = __webpack_require__(8727); 2748 2749// `Object.keys` method 2750// https://tc39.es/ecma262/#sec-object.keys 2751// eslint-disable-next-line es/no-object-keys -- safe 2752module.exports = Object.keys || function keys(O) { 2753 return internalObjectKeys(O, enumBugKeys); 2754}; 2755 2756 2757/***/ }, 2758 2759/***/ 8773 2760(__unused_webpack_module, exports) { 2761 2762 2763var $propertyIsEnumerable = {}.propertyIsEnumerable; 2764// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 2765var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 2766 2767// Nashorn ~ JDK8 bug 2768var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1); 2769 2770// `Object.prototype.propertyIsEnumerable` method implementation 2771// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable 2772exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) { 2773 var descriptor = getOwnPropertyDescriptor(this, V); 2774 return !!descriptor && descriptor.enumerable; 2775} : $propertyIsEnumerable; 2776 2777 2778/***/ }, 2779 2780/***/ 2967 2781(module, __unused_webpack_exports, __webpack_require__) { 2782 2783 2784/* eslint-disable no-proto -- safe */ 2785var uncurryThisAccessor = __webpack_require__(6706); 2786var isObject = __webpack_require__(34); 2787var requireObjectCoercible = __webpack_require__(7750); 2788var aPossiblePrototype = __webpack_require__(3506); 2789 2790// `Object.setPrototypeOf` method 2791// https://tc39.es/ecma262/#sec-object.setprototypeof 2792// Works with __proto__ only. Old v8 can't work with null proto objects. 2793// eslint-disable-next-line es/no-object-setprototypeof -- safe 2794module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () { 2795 var CORRECT_SETTER = false; 2796 var test = {}; 2797 var setter; 2798 try { 2799 setter = uncurryThisAccessor(Object.prototype, '__proto__', 'set'); 2800 setter(test, []); 2801 CORRECT_SETTER = test instanceof Array; 2802 } catch (error) { /* empty */ } 2803 return function setPrototypeOf(O, proto) { 2804 requireObjectCoercible(O); 2805 aPossiblePrototype(proto); 2806 if (!isObject(O)) return O; 2807 if (CORRECT_SETTER) setter(O, proto); 2808 else O.__proto__ = proto; 2809 return O; 2810 }; 2811}() : undefined); 2812 2813 2814/***/ }, 2815 2816/***/ 4270 2817(module, __unused_webpack_exports, __webpack_require__) { 2818 2819 2820var call = __webpack_require__(9565); 2821var isCallable = __webpack_require__(4901); 2822var isObject = __webpack_require__(34); 2823 2824var $TypeError = TypeError; 2825 2826// `OrdinaryToPrimitive` abstract operation 2827// https://tc39.es/ecma262/#sec-ordinarytoprimitive 2828module.exports = function (input, pref) { 2829 var fn, val; 2830 if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; 2831 if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val; 2832 if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; 2833 throw new $TypeError("Can't convert object to primitive value"); 2834}; 2835 2836 2837/***/ }, 2838 2839/***/ 5031 2840(module, __unused_webpack_exports, __webpack_require__) { 2841 2842 2843var getBuiltIn = __webpack_require__(7751); 2844var uncurryThis = __webpack_require__(9504); 2845var getOwnPropertyNamesModule = __webpack_require__(8480); 2846var getOwnPropertySymbolsModule = __webpack_require__(3717); 2847var anObject = __webpack_require__(8551); 2848
vendor: 6,481 bytes, lines 2849-3108
2849var concat = uncurryThis([].concat); 2850 2851// all object keys, includes non-enumerable and symbols 2852module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { 2853 var keys = getOwnPropertyNamesModule.f(anObject(it)); 2854 var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; 2855 return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys; 2856}; 2857 2858 2859/***/ }, 2860 2861/***/ 8235 2862(module, __unused_webpack_exports, __webpack_require__) { 2863 2864 2865var uncurryThis = __webpack_require__(9504); 2866var hasOwn = __webpack_require__(9297); 2867 2868var $SyntaxError = SyntaxError; 2869var $parseInt = parseInt; 2870var fromCharCode = String.fromCharCode; 2871var at = uncurryThis(''.charAt); 2872var slice = uncurryThis(''.slice); 2873var exec = uncurryThis(/./.exec); 2874 2875var codePoints = { 2876 '\\"': '"', 2877 '\\\\': '\\', 2878 '\\/': '/', 2879 '\\b': '\b', 2880 '\\f': '\f', 2881 '\\n': '\n', 2882 '\\r': '\r', 2883 '\\t': '\t' 2884}; 2885 2886var IS_4_HEX_DIGITS = /^[\da-f]{4}$/i; 2887// eslint-disable-next-line regexp/no-control-character -- safe 2888var IS_C0_CONTROL_CODE = /^[\u0000-\u001F]$/; 2889 2890module.exports = function (source, i) { 2891 var unterminated = true; 2892 var value = ''; 2893 while (i < source.length) { 2894 var chr = at(source, i); 2895 if (chr === '\\') { 2896 var twoChars = slice(source, i, i + 2); 2897 if (hasOwn(codePoints, twoChars)) { 2898 value += codePoints[twoChars]; 2899 i += 2; 2900 } else if (twoChars === '\\u') { 2901 i += 2; 2902 var fourHexDigits = slice(source, i, i + 4); 2903 if (!exec(IS_4_HEX_DIGITS, fourHexDigits)) throw new $SyntaxError('Bad Unicode escape at: ' + i); 2904 value += fromCharCode($parseInt(fourHexDigits, 16)); 2905 i += 4; 2906 } else throw new $SyntaxError('Unknown escape sequence: "' + twoChars + '"'); 2907 } else if (chr === '"') { 2908 unterminated = false; 2909 i++; 2910 break; 2911 } else { 2912 if (exec(IS_C0_CONTROL_CODE, chr)) throw new $SyntaxError('Bad control character in string literal at: ' + i); 2913 value += chr; 2914 i++; 2915 } 2916 } 2917 if (unterminated) throw new $SyntaxError('Unterminated string at: ' + i); 2918 return { value: value, end: i }; 2919}; 2920 2921 2922/***/ }, 2923 2924/***/ 1103 2925(module) { 2926 2927 2928module.exports = function (exec) { 2929 try { 2930 return { error: false, value: exec() }; 2931 } catch (error) { 2932 return { error: true, value: error }; 2933 } 2934}; 2935 2936 2937/***/ }, 2938 2939/***/ 3438 2940(module, __unused_webpack_exports, __webpack_require__) { 2941 2942 2943var anObject = __webpack_require__(8551); 2944var isObject = __webpack_require__(34); 2945var newPromiseCapability = __webpack_require__(6043); 2946 2947module.exports = function (C, x) { 2948 anObject(C); 2949 if (isObject(x) && x.constructor === C) return x; 2950 var promiseCapability = newPromiseCapability.f(C); 2951 var resolve = promiseCapability.resolve; 2952 resolve(x); 2953 return promiseCapability.promise; 2954}; 2955 2956 2957/***/ }, 2958 2959/***/ 7750 2960(module, __unused_webpack_exports, __webpack_require__) { 2961 2962 2963var isNullOrUndefined = __webpack_require__(4117); 2964 2965var $TypeError = TypeError; 2966 2967// `RequireObjectCoercible` abstract operation 2968// https://tc39.es/ecma262/#sec-requireobjectcoercible 2969module.exports = function (it) { 2970 if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it); 2971 return it; 2972}; 2973 2974 2975/***/ }, 2976 2977/***/ 9286 2978(module, __unused_webpack_exports, __webpack_require__) { 2979 2980 2981var SetHelpers = __webpack_require__(4402); 2982var iterate = __webpack_require__(8469); 2983 2984var Set = SetHelpers.Set; 2985var add = SetHelpers.add; 2986 2987module.exports = function (set) { 2988 var result = new Set(); 2989 iterate(set, function (it) { 2990 add(result, it); 2991 }); 2992 return result; 2993}; 2994 2995 2996/***/ }, 2997 2998/***/ 3440 2999(module, __unused_webpack_exports, __webpack_require__) { 3000 3001 3002var aSet = __webpack_require__(7080); 3003var SetHelpers = __webpack_require__(4402); 3004var clone = __webpack_require__(9286); 3005var size = __webpack_require__(5170); 3006var getSetRecord = __webpack_require__(3789); 3007var iterateSet = __webpack_require__(8469); 3008var iterateSimple = __webpack_require__(507); 3009 3010var has = SetHelpers.has; 3011var remove = SetHelpers.remove; 3012 3013// `Set.prototype.difference` method 3014// https://tc39.es/ecma262/#sec-set.prototype.difference 3015module.exports = function difference(other) { 3016 var O = aSet(this); 3017 var otherRec = getSetRecord(other); 3018 var result = clone(O); 3019 if (size(result) <= otherRec.size) iterateSet(result, function (e) { 3020 if (otherRec.includes(e)) remove(result, e); 3021 }); 3022 else iterateSimple(otherRec.getIterator(), function (e) { 3023 if (has(result, e)) remove(result, e); 3024 }); 3025 return result; 3026}; 3027 3028 3029/***/ }, 3030 3031/***/ 4402 3032(module, __unused_webpack_exports, __webpack_require__) { 3033 3034 3035var uncurryThis = __webpack_require__(9504); 3036 3037// eslint-disable-next-line es/no-set -- safe 3038var SetPrototype = Set.prototype; 3039 3040module.exports = { 3041 // eslint-disable-next-line es/no-set -- safe 3042 Set: Set, 3043 add: uncurryThis(SetPrototype.add), 3044 has: uncurryThis(SetPrototype.has), 3045 remove: uncurryThis(SetPrototype['delete']), 3046 proto: SetPrototype 3047}; 3048 3049 3050/***/ }, 3051 3052/***/ 8750 3053(module, __unused_webpack_exports, __webpack_require__) { 3054 3055 3056var aSet = __webpack_require__(7080); 3057var SetHelpers = __webpack_require__(4402); 3058var size = __webpack_require__(5170); 3059var getSetRecord = __webpack_require__(3789); 3060var iterateSet = __webpack_require__(8469); 3061var iterateSimple = __webpack_require__(507); 3062 3063var Set = SetHelpers.Set; 3064var add = SetHelpers.add; 3065var has = SetHelpers.has; 3066 3067// `Set.prototype.intersection` method 3068// https://tc39.es/ecma262/#sec-set.prototype.intersection 3069module.exports = function intersection(other) { 3070 var O = aSet(this); 3071 var otherRec = getSetRecord(other); 3072 var result = new Set(); 3073 3074 if (size(O) > otherRec.size) { 3075 iterateSimple(otherRec.getIterator(), function (e) { 3076 if (has(O, e)) add(result, e); 3077 }); 3078 } else { 3079 iterateSet(O, function (e) { 3080 if (otherRec.includes(e)) add(result, e); 3081 }); 3082 } 3083 3084 return result; 3085}; 3086 3087 3088/***/ }, 3089 3090/***/ 4449 3091(module, __unused_webpack_exports, __webpack_require__) { 3092 3093 3094var aSet = __webpack_require__(7080); 3095var has = (__webpack_require__(4402).has); 3096var size = __webpack_require__(5170); 3097var getSetRecord = __webpack_require__(3789); 3098var iterateSet = __webpack_require__(8469); 3099var iterateSimple = __webpack_require__(507); 3100var iteratorClose = __webpack_require__(9539); 3101 3102// `Set.prototype.isDisjointFrom` method 3103// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom 3104module.exports = function isDisjointFrom(other) { 3105 var O = aSet(this); 3106 var otherRec = getSetRecord(other); 3107 if (size(O) <= otherRec.size) return iterateSet(O, function (e) { 3108 if (otherRec.includes(e)) return false;
vendor: 4,495 bytes, lines 3109-3284
3109 }, true) !== false; 3110 var iterator = otherRec.getIterator(); 3111 return iterateSimple(iterator, function (e) { 3112 if (has(O, e)) return iteratorClose(iterator.iterator, 'normal', false); 3113 }) !== false; 3114}; 3115 3116 3117/***/ }, 3118 3119/***/ 3838 3120(module, __unused_webpack_exports, __webpack_require__) { 3121 3122 3123var aSet = __webpack_require__(7080); 3124var size = __webpack_require__(5170); 3125var iterate = __webpack_require__(8469); 3126var getSetRecord = __webpack_require__(3789); 3127 3128// `Set.prototype.isSubsetOf` method 3129// https://tc39.es/ecma262/#sec-set.prototype.issubsetof 3130module.exports = function isSubsetOf(other) { 3131 var O = aSet(this); 3132 var otherRec = getSetRecord(other); 3133 if (size(O) > otherRec.size) return false; 3134 return iterate(O, function (e) { 3135 if (!otherRec.includes(e)) return false; 3136 }, true) !== false; 3137}; 3138 3139 3140/***/ }, 3141 3142/***/ 8527 3143(module, __unused_webpack_exports, __webpack_require__) { 3144 3145 3146var aSet = __webpack_require__(7080); 3147var has = (__webpack_require__(4402).has); 3148var size = __webpack_require__(5170); 3149var getSetRecord = __webpack_require__(3789); 3150var iterateSimple = __webpack_require__(507); 3151var iteratorClose = __webpack_require__(9539); 3152 3153// `Set.prototype.isSupersetOf` method 3154// https://tc39.es/ecma262/#sec-set.prototype.issupersetof 3155module.exports = function isSupersetOf(other) { 3156 var O = aSet(this); 3157 var otherRec = getSetRecord(other); 3158 if (size(O) < otherRec.size) return false; 3159 var iterator = otherRec.getIterator(); 3160 return iterateSimple(iterator, function (e) { 3161 if (!has(O, e)) return iteratorClose(iterator.iterator, 'normal', false); 3162 }) !== false; 3163}; 3164 3165 3166/***/ }, 3167 3168/***/ 8469 3169(module, __unused_webpack_exports, __webpack_require__) { 3170 3171 3172var uncurryThis = __webpack_require__(9504); 3173var iterateSimple = __webpack_require__(507); 3174var SetHelpers = __webpack_require__(4402); 3175 3176var Set = SetHelpers.Set; 3177var SetPrototype = SetHelpers.proto; 3178var forEach = uncurryThis(SetPrototype.forEach); 3179var keys = uncurryThis(SetPrototype.keys); 3180var next = keys(new Set()).next; 3181 3182module.exports = function (set, fn, interruptible) { 3183 return interruptible ? iterateSimple({ iterator: keys(set), next: next }, fn) : forEach(set, fn); 3184}; 3185 3186 3187/***/ }, 3188 3189/***/ 4916 3190(module, __unused_webpack_exports, __webpack_require__) { 3191 3192 3193var getBuiltIn = __webpack_require__(7751); 3194 3195var createSetLike = function (size) { 3196 return { 3197 size: size, 3198 has: function () { 3199 return false; 3200 }, 3201 keys: function () { 3202 return { 3203 next: function () { 3204 return { done: true }; 3205 } 3206 }; 3207 } 3208 }; 3209}; 3210 3211var createSetLikeWithInfinitySize = function (size) { 3212 return { 3213 size: size, 3214 has: function () { 3215 return true; 3216 }, 3217 keys: function () { 3218 throw new Error('e'); 3219 } 3220 }; 3221}; 3222 3223module.exports = function (name, callback) { 3224 var Set = getBuiltIn('Set'); 3225 try { 3226 new Set()[name](createSetLike(0)); 3227 try { 3228 // late spec change, early WebKit ~ Safari 17 implementation does not pass it 3229 // https://github.com/tc39/proposal-set-methods/pull/88 3230 // also covered engines with 3231 // https://bugs.webkit.org/show_bug.cgi?id=272679 3232 new Set()[name](createSetLike(-1)); 3233 return false; 3234 } catch (error2) { 3235 if (!callback) return true; 3236 // early V8 implementation bug 3237 // https://issues.chromium.org/issues/351332634 3238 try { 3239 new Set()[name](createSetLikeWithInfinitySize(-Infinity)); 3240 return false; 3241 } catch (error) { 3242 var set = new Set([1, 2]); 3243 return callback(set[name](createSetLikeWithInfinitySize(Infinity))); 3244 } 3245 } 3246 } catch (error) { 3247 return false; 3248 } 3249}; 3250 3251 3252/***/ }, 3253 3254/***/ 9835 3255(module) { 3256 3257 3258// Should get iterator record of a set-like object before cloning this 3259// https://bugs.webkit.org/show_bug.cgi?id=289430 3260module.exports = function (METHOD_NAME) { 3261 try { 3262 // eslint-disable-next-line es/no-set -- needed for test 3263 var baseSet = new Set(); 3264 var setLike = { 3265 size: 0, 3266 has: function () { return true; }, 3267 keys: function () { 3268 // eslint-disable-next-line es/no-object-defineproperty -- needed for test 3269 return Object.defineProperty({}, 'next', { 3270 get: function () { 3271 baseSet.clear(); 3272 baseSet.add(4); 3273 return function () { 3274 return { done: true }; 3275 }; 3276 } 3277 }); 3278 } 3279 }; 3280 var result = baseSet[METHOD_NAME](setLike); 3281 3282 return result.size === 1 && result.values().next().value === 4; 3283 } catch (error) { 3284 return false;
vendor: 4,232 bytes, lines 3285-3449
3285 } 3286}; 3287 3288 3289/***/ }, 3290 3291/***/ 5170 3292(module, __unused_webpack_exports, __webpack_require__) { 3293 3294 3295var uncurryThisAccessor = __webpack_require__(6706); 3296var SetHelpers = __webpack_require__(4402); 3297 3298module.exports = uncurryThisAccessor(SetHelpers.proto, 'size', 'get') || function (set) { 3299 return set.size; 3300}; 3301 3302 3303/***/ }, 3304 3305/***/ 3650 3306(module, __unused_webpack_exports, __webpack_require__) { 3307 3308 3309var aSet = __webpack_require__(7080); 3310var SetHelpers = __webpack_require__(4402); 3311var clone = __webpack_require__(9286); 3312var getSetRecord = __webpack_require__(3789); 3313var iterateSimple = __webpack_require__(507); 3314 3315var add = SetHelpers.add; 3316var has = SetHelpers.has; 3317var remove = SetHelpers.remove; 3318 3319// `Set.prototype.symmetricDifference` method 3320// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference 3321module.exports = function symmetricDifference(other) { 3322 var O = aSet(this); 3323 var keysIter = getSetRecord(other).getIterator(); 3324 var result = clone(O); 3325 iterateSimple(keysIter, function (e) { 3326 if (has(O, e)) remove(result, e); 3327 else add(result, e); 3328 }); 3329 return result; 3330}; 3331 3332 3333/***/ }, 3334 3335/***/ 4204 3336(module, __unused_webpack_exports, __webpack_require__) { 3337 3338 3339var aSet = __webpack_require__(7080); 3340var add = (__webpack_require__(4402).add); 3341var clone = __webpack_require__(9286); 3342var getSetRecord = __webpack_require__(3789); 3343var iterateSimple = __webpack_require__(507); 3344 3345// `Set.prototype.union` method 3346// https://tc39.es/ecma262/#sec-set.prototype.union 3347module.exports = function union(other) { 3348 var O = aSet(this); 3349 var keysIter = getSetRecord(other).getIterator(); 3350 var result = clone(O); 3351 iterateSimple(keysIter, function (it) { 3352 add(result, it); 3353 }); 3354 return result; 3355}; 3356 3357 3358/***/ }, 3359 3360/***/ 6119 3361(module, __unused_webpack_exports, __webpack_require__) { 3362 3363 3364var shared = __webpack_require__(5745); 3365var uid = __webpack_require__(3392); 3366 3367var keys = shared('keys'); 3368 3369module.exports = function (key) { 3370 return keys[key] || (keys[key] = uid(key)); 3371}; 3372 3373 3374/***/ }, 3375 3376/***/ 7629 3377(module, __unused_webpack_exports, __webpack_require__) { 3378 3379 3380var IS_PURE = __webpack_require__(6395); 3381var globalThis = __webpack_require__(4576); 3382var defineGlobalProperty = __webpack_require__(9433); 3383 3384var SHARED = '__core-js_shared__'; 3385var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {}); 3386 3387(store.versions || (store.versions = [])).push({ 3388 version: '3.50.0', 3389 mode: IS_PURE ? 'pure' : 'global', 3390 copyright: '© 2013â2025 Denis Pushkarev (zloirock.ru), 2025â2026 CoreJS Company (core-js.io). All rights reserved.', 3391 license: 'https://github.com/zloirock/core-js/blob/v3.50.0/LICENSE', 3392 source: 'https://github.com/zloirock/core-js' 3393}); 3394 3395 3396/***/ }, 3397 3398/***/ 5745 3399(module, __unused_webpack_exports, __webpack_require__) { 3400 3401 3402var store = __webpack_require__(7629); 3403// eslint-disable-next-line es/no-object-create -- safe 3404var create = Object.create || Object; 3405 3406module.exports = function (key, value) { 3407 return store[key] || (store[key] = value || create(null)); 3408}; 3409 3410 3411/***/ }, 3412 3413/***/ 4495 3414(module, __unused_webpack_exports, __webpack_require__) { 3415 3416 3417/* eslint-disable es/no-symbol -- required for testing */ 3418var V8_VERSION = __webpack_require__(9519); 3419var fails = __webpack_require__(9039); 3420var globalThis = __webpack_require__(4576); 3421 3422var $String = globalThis.String; 3423 3424// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing 3425module.exports = !!Object.getOwnPropertySymbols && !fails(function () { 3426 var symbol = Symbol('symbol detection'); 3427 // Chrome 38 Symbol has incorrect toString conversion 3428 // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances 3429 // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will, 3430 // of course, fail. 3431 return !$String(symbol) || !(Object(symbol) instanceof Symbol) || 3432 // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances 3433 !Symbol.sham && V8_VERSION && V8_VERSION < 41; 3434}); 3435 3436 3437/***/ }, 3438 3439/***/ 1240 3440(module, __unused_webpack_exports, __webpack_require__) { 3441 3442 3443var uncurryThis = __webpack_require__(9504); 3444 3445// `thisNumberValue` abstract operation 3446// https://tc39.es/ecma262/#sec-thisnumbervalue 3447module.exports = uncurryThis(1.1.valueOf); 3448 3449
vendor: 6,454 bytes, lines 3450-3722
3450/***/ }, 3451 3452/***/ 5610 3453(module, __unused_webpack_exports, __webpack_require__) { 3454 3455 3456var toIntegerOrInfinity = __webpack_require__(1291); 3457 3458var max = Math.max; 3459var min = Math.min; 3460 3461// Helper for a popular repeating case of the spec: 3462// Let integer be ? ToInteger(index). 3463// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). 3464module.exports = function (index, length) { 3465 var integer = toIntegerOrInfinity(index); 3466 return integer < 0 ? max(integer + length, 0) : min(integer, length); 3467}; 3468 3469 3470/***/ }, 3471 3472/***/ 5854 3473(module, __unused_webpack_exports, __webpack_require__) { 3474 3475 3476var toPrimitive = __webpack_require__(2777); 3477 3478var $TypeError = TypeError; 3479 3480// `ToBigInt` abstract operation 3481// https://tc39.es/ecma262/#sec-tobigint 3482module.exports = function (argument) { 3483 var prim = toPrimitive(argument, 'number'); 3484 if (typeof prim == 'number') throw new $TypeError("Can't convert number to bigint"); 3485 // eslint-disable-next-line es/no-bigint -- safe 3486 return BigInt(prim); 3487}; 3488 3489 3490/***/ }, 3491 3492/***/ 5397 3493(module, __unused_webpack_exports, __webpack_require__) { 3494 3495 3496// toObject with fallback for non-array-like ES3 strings 3497var IndexedObject = __webpack_require__(7055); 3498var requireObjectCoercible = __webpack_require__(7750); 3499 3500module.exports = function (it) { 3501 return IndexedObject(requireObjectCoercible(it)); 3502}; 3503 3504 3505/***/ }, 3506 3507/***/ 1291 3508(module, __unused_webpack_exports, __webpack_require__) { 3509 3510 3511var trunc = __webpack_require__(741); 3512 3513// `ToIntegerOrInfinity` abstract operation 3514// https://tc39.es/ecma262/#sec-tointegerorinfinity 3515module.exports = function (argument) { 3516 var number = +argument; 3517 // eslint-disable-next-line no-self-compare -- NaN check 3518 return number !== number || number === 0 ? 0 : trunc(number); 3519}; 3520 3521 3522/***/ }, 3523 3524/***/ 8014 3525(module, __unused_webpack_exports, __webpack_require__) { 3526 3527 3528var toIntegerOrInfinity = __webpack_require__(1291); 3529 3530var min = Math.min; 3531 3532// `ToLength` abstract operation 3533// https://tc39.es/ecma262/#sec-tolength 3534module.exports = function (argument) { 3535 var len = toIntegerOrInfinity(argument); 3536 return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 3537}; 3538 3539 3540/***/ }, 3541 3542/***/ 8981 3543(module, __unused_webpack_exports, __webpack_require__) { 3544 3545 3546var requireObjectCoercible = __webpack_require__(7750); 3547 3548var $Object = Object; 3549 3550// `ToObject` abstract operation 3551// https://tc39.es/ecma262/#sec-toobject 3552module.exports = function (argument) { 3553 return $Object(requireObjectCoercible(argument)); 3554}; 3555 3556 3557/***/ }, 3558 3559/***/ 9590 3560(module, __unused_webpack_exports, __webpack_require__) { 3561 3562 3563var toIntegerOrInfinity = __webpack_require__(1291); 3564 3565var $RangeError = RangeError; 3566 3567module.exports = function (it) { 3568 var result = toIntegerOrInfinity(it); 3569 if (result < 0) throw new $RangeError("The argument can't be less than 0"); 3570 return result; 3571}; 3572 3573 3574/***/ }, 3575 3576/***/ 2777 3577(module, __unused_webpack_exports, __webpack_require__) { 3578 3579 3580var call = __webpack_require__(9565); 3581var isObject = __webpack_require__(34); 3582var isSymbol = __webpack_require__(757); 3583var getMethod = __webpack_require__(5966); 3584var ordinaryToPrimitive = __webpack_require__(4270); 3585var wellKnownSymbol = __webpack_require__(8227); 3586 3587var $TypeError = TypeError; 3588var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); 3589 3590// `ToPrimitive` abstract operation 3591// https://tc39.es/ecma262/#sec-toprimitive 3592module.exports = function (input, pref) { 3593 if (!isObject(input) || isSymbol(input)) return input; 3594 var exoticToPrim = getMethod(input, TO_PRIMITIVE); 3595 var result; 3596 if (exoticToPrim) { 3597 if (pref === undefined) pref = 'default'; 3598 result = call(exoticToPrim, input, pref); 3599 if (!isObject(result) || isSymbol(result)) return result; 3600 throw new $TypeError("Can't convert object to primitive value"); 3601 } 3602 if (pref === undefined) pref = 'number'; 3603 return ordinaryToPrimitive(input, pref); 3604}; 3605 3606 3607/***/ }, 3608 3609/***/ 6969 3610(module, __unused_webpack_exports, __webpack_require__) { 3611 3612 3613var toPrimitive = __webpack_require__(2777); 3614var isSymbol = __webpack_require__(757); 3615 3616// `ToPropertyKey` abstract operation 3617// https://tc39.es/ecma262/#sec-topropertykey 3618module.exports = function (argument) { 3619 var key = toPrimitive(argument, 'string'); 3620 return isSymbol(key) ? key : key + ''; 3621}; 3622 3623 3624/***/ }, 3625 3626/***/ 2140 3627(module, __unused_webpack_exports, __webpack_require__) { 3628 3629 3630var wellKnownSymbol = __webpack_require__(8227); 3631 3632var TO_STRING_TAG = wellKnownSymbol('toStringTag'); 3633var test = {}; 3634// eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation 3635test[TO_STRING_TAG] = 'z'; 3636 3637module.exports = String(test) === '[object z]'; 3638 3639 3640/***/ }, 3641 3642/***/ 655 3643(module, __unused_webpack_exports, __webpack_require__) { 3644 3645 3646var classof = __webpack_require__(6955); 3647 3648var $String = String; 3649 3650module.exports = function (argument) { 3651 if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string'); 3652 return $String(argument); 3653}; 3654 3655 3656/***/ }, 3657 3658/***/ 6823 3659(module) { 3660 3661 3662var $String = String; 3663 3664module.exports = function (argument) { 3665 try { 3666 return $String(argument); 3667 } catch (error) { 3668 return 'Object'; 3669 } 3670}; 3671 3672 3673/***/ }, 3674 3675/***/ 3392 3676(module, __unused_webpack_exports, __webpack_require__) { 3677 3678 3679var uncurryThis = __webpack_require__(9504); 3680 3681var id = 0; 3682var postfix = Math.random(); 3683var toString = uncurryThis(1.1.toString); 3684 3685module.exports = function (key) { 3686 return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); 3687}; 3688 3689 3690/***/ }, 3691 3692/***/ 9143 3693(module, __unused_webpack_exports, __webpack_require__) { 3694 3695 3696var globalThis = __webpack_require__(4576); 3697var uncurryThis = __webpack_require__(9504); 3698var anObjectOrUndefined = __webpack_require__(3972); 3699var aString = __webpack_require__(3463); 3700var hasOwn = __webpack_require__(9297); 3701var base64Map = __webpack_require__(2804); 3702var getAlphabetOption = __webpack_require__(944); 3703var notDetached = __webpack_require__(5169); 3704 3705var base64Alphabet = base64Map.c2i; 3706var base64UrlAlphabet = base64Map.c2iUrl; 3707 3708var SyntaxError = globalThis.SyntaxError; 3709var TypeError = globalThis.TypeError; 3710var $Array = globalThis.Array; 3711var at = uncurryThis(''.charAt); 3712var floor = Math.floor; 3713 3714var skipAsciiWhitespace = function (string, index) { 3715 var length = string.length; 3716 for (;index < length; index++) { 3717 var chr = at(string, index); 3718 if (chr !== ' ' && chr !== '\t' && chr !== '\n' && chr !== '\f' && chr !== '\r') break; 3719 } return index; 3720}; 3721 3722var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) {
vendor: 75,421 bytes, lines 3723-6067
3723 var chunkLength = chunk.length; 3724 3725 if (chunkLength < 4) { 3726 chunk += chunkLength === 2 ? 'AA' : 'A'; 3727 } 3728 3729 var triplet = (alphabet[at(chunk, 0)] << 18) 3730 + (alphabet[at(chunk, 1)] << 12) 3731 + (alphabet[at(chunk, 2)] << 6) 3732 + alphabet[at(chunk, 3)]; 3733 3734 var chunkBytes = [ 3735 (triplet >> 16) & 255, 3736 (triplet >> 8) & 255, 3737 triplet & 255 3738 ]; 3739 3740 if (chunkLength === 2) { 3741 if (throwOnExtraBits && chunkBytes[1] !== 0) { 3742 throw new SyntaxError('Extra bits'); 3743 } 3744 return [chunkBytes[0]]; 3745 } 3746 3747 if (chunkLength === 3) { 3748 if (throwOnExtraBits && chunkBytes[2] !== 0) { 3749 throw new SyntaxError('Extra bits'); 3750 } 3751 return [chunkBytes[0], chunkBytes[1]]; 3752 } 3753 3754 return chunkBytes; 3755}; 3756 3757var writeBytes = function (bytes, elements, written) { 3758 var elementsLength = elements.length; 3759 for (var index = 0; index < elementsLength; index++) { 3760 bytes[written + index] = elements[index]; 3761 } 3762 return written + elementsLength; 3763}; 3764 3765/* eslint-disable max-statements, max-depth -- TODO */ 3766module.exports = function (string, options, into, maxLength) { 3767 aString(string); 3768 anObjectOrUndefined(options); 3769 var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; 3770 var lastChunkHandling = options ? options.lastChunkHandling : undefined; 3771 3772 if (lastChunkHandling === undefined) lastChunkHandling = 'loose'; 3773 3774 if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') { 3775 throw new TypeError('Incorrect `lastChunkHandling` option'); 3776 } 3777 3778 if (into) notDetached(into.buffer); 3779 3780 var stringLength = string.length; 3781 var bytes = into || $Array(floor(stringLength * 3 / 4)); 3782 var written = 0; 3783 var read = 0; 3784 var chunk = ''; 3785 var index = 0; 3786 3787 if (maxLength) while (true) { 3788 index = skipAsciiWhitespace(string, index); 3789 if (index === stringLength) { 3790 if (chunk.length > 0) { 3791 if (lastChunkHandling === 'stop-before-partial') { 3792 break; 3793 } 3794 if (lastChunkHandling === 'loose') { 3795 if (chunk.length === 1) { 3796 throw new SyntaxError('Malformed padding: exactly one additional character'); 3797 } 3798 written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); 3799 } else { 3800 throw new SyntaxError('Missing padding'); 3801 } 3802 } 3803 read = stringLength; 3804 break; 3805 } 3806 var chr = at(string, index); 3807 ++index; 3808 if (chr === '=') { 3809 if (chunk.length < 2) { 3810 throw new SyntaxError('Padding is too early'); 3811 } 3812 index = skipAsciiWhitespace(string, index); 3813 if (chunk.length === 2) { 3814 if (index === stringLength) { 3815 if (lastChunkHandling === 'stop-before-partial') { 3816 break; 3817 } 3818 throw new SyntaxError('Malformed padding: only one ='); 3819 } 3820 if (at(string, index) === '=') { 3821 ++index; 3822 index = skipAsciiWhitespace(string, index); 3823 } 3824 } 3825 if (index < stringLength) { 3826 throw new SyntaxError('Unexpected character after padding'); 3827 } 3828 written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written); 3829 read = stringLength; 3830 break; 3831 } 3832 if (!hasOwn(alphabet, chr)) { 3833 throw new SyntaxError('Unexpected character'); 3834 } 3835 var remainingBytes = maxLength - written; 3836 if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) { 3837 // special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=` 3838 break; 3839 } 3840 3841 chunk += chr; 3842 if (chunk.length === 4) { 3843 written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); 3844 chunk = ''; 3845 read = index; 3846 if (written === maxLength) { 3847 break; 3848 } 3849 } 3850 } 3851 if (!into) bytes.length = written; 3852 return { bytes: bytes, read: read, written: written }; 3853}; 3854 3855 3856/***/ }, 3857 3858/***/ 2303 3859(module, __unused_webpack_exports, __webpack_require__) { 3860 3861 3862var globalThis = __webpack_require__(4576); 3863var uncurryThis = __webpack_require__(9504); 3864 3865var Uint8Array = globalThis.Uint8Array; 3866var SyntaxError = globalThis.SyntaxError; 3867var min = Math.min; 3868var stringMatch = uncurryThis(''.match); 3869 3870module.exports = function (string, into) { 3871 var stringLength = string.length; 3872 if (stringLength % 2 !== 0) throw new SyntaxError('String should be an even number of characters'); 3873 var maxLength = into ? min(into.length, stringLength / 2) : stringLength / 2; 3874 var bytes = into || new Uint8Array(maxLength); 3875 var segments = stringMatch(string, /[\S\s]{2}/g); 3876 var written = 0; 3877 for (; written < maxLength; written++) { 3878 var result = +('0x' + segments[written] + '0'); 3879 // eslint-disable-next-line no-self-compare -- NaN check 3880 if (result !== result) { 3881 throw new SyntaxError('String should only contain hex characters'); 3882 } 3883 bytes[written] = result >> 4; 3884 } 3885 return { bytes: bytes, read: written << 1 }; 3886}; 3887 3888 3889/***/ }, 3890 3891/***/ 7416 3892(module, __unused_webpack_exports, __webpack_require__) { 3893 3894 3895var fails = __webpack_require__(9039); 3896var wellKnownSymbol = __webpack_require__(8227); 3897var DESCRIPTORS = __webpack_require__(3724); 3898var IS_PURE = __webpack_require__(6395); 3899 3900var ITERATOR = wellKnownSymbol('iterator'); 3901 3902module.exports = !fails(function () { 3903 // eslint-disable-next-line unicorn/relative-url-style -- required for testing 3904 var url = new URL('b?a=1&b=2&c=3', 'https://a'); 3905 var params = url.searchParams; 3906 var params2 = new URLSearchParams('a=1&a=2&b=3'); 3907 var result = ''; 3908 url.pathname = 'c%20d'; 3909 params.forEach(function (value, key) { 3910 params['delete']('b'); 3911 result += key + value; 3912 }); 3913 params2['delete']('a', 2); 3914 // `undefined` case is a Chromium 117 bug 3915 // https://bugs.chromium.org/p/v8/issues/detail?id=14222 3916 params2['delete']('b', undefined); 3917 return (IS_PURE && (!url.toJSON || !params2.has('a', 1) || params2.has('a', 2) || !params2.has('a', undefined) || params2.has('b'))) 3918 || (!params.size && (IS_PURE || !DESCRIPTORS)) 3919 || !params.sort 3920 || url.href !== 'https://a/c%20d?a=1&c=3' 3921 || params.get('c') !== '3' 3922 || String(new URLSearchParams('?a=1')) !== 'a=1' 3923 || !params[ITERATOR] 3924 // throws in Edge 3925 || new URL('https://a@b').username !== 'a' 3926 || new URLSearchParams(new URLSearchParams('a=b')).get('a') !== 'b' 3927 // not punycoded in Edge 3928 || new URL('https://ÑеÑÑ').host !== 'xn--e1aybc' 3929 // not escaped in Chrome 62- 3930 || new URL('https://a#б').hash !== '#%D0%B1' 3931 // fails in Chrome 66- 3932 || result !== 'a1c3' 3933 // throws in Safari 3934 || new URL('https://x', undefined).host !== 'x'; 3935}); 3936 3937 3938/***/ }, 3939 3940/***/ 7040 3941(module, __unused_webpack_exports, __webpack_require__) { 3942 3943 3944/* eslint-disable es/no-symbol -- required for testing */ 3945var NATIVE_SYMBOL = __webpack_require__(4495); 3946 3947module.exports = NATIVE_SYMBOL && 3948 !Symbol.sham && 3949 typeof Symbol.iterator == 'symbol'; 3950 3951 3952/***/ }, 3953 3954/***/ 8686 3955(module, __unused_webpack_exports, __webpack_require__) { 3956 3957 3958var DESCRIPTORS = __webpack_require__(3724); 3959var fails = __webpack_require__(9039); 3960 3961// V8 ~ Chrome 36- 3962// https://bugs.chromium.org/p/v8/issues/detail?id=3334 3963module.exports = DESCRIPTORS && fails(function () { 3964 // eslint-disable-next-line es/no-object-defineproperty -- required for testing 3965 return Object.defineProperty(function () { /* empty */ }, 'prototype', { 3966 value: 42, 3967 writable: false 3968 }).prototype !== 42; 3969}); 3970 3971 3972/***/ }, 3973 3974/***/ 2812 3975(module) { 3976 3977 3978var $TypeError = TypeError; 3979 3980module.exports = function (passed, required) { 3981 if (passed < required) throw new $TypeError('Not enough arguments'); 3982 return passed; 3983}; 3984 3985 3986/***/ }, 3987 3988/***/ 8622 3989(module, __unused_webpack_exports, __webpack_require__) { 3990 3991 3992var globalThis = __webpack_require__(4576); 3993var isCallable = __webpack_require__(4901); 3994 3995var WeakMap = globalThis.WeakMap; 3996 3997module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap)); 3998 3999 4000/***/ }, 4001 4002/***/ 4995 4003(module, __unused_webpack_exports, __webpack_require__) { 4004 4005 4006var uncurryThis = __webpack_require__(9504); 4007 4008// eslint-disable-next-line es/no-weak-map -- safe 4009var WeakMapPrototype = WeakMap.prototype; 4010 4011module.exports = { 4012 // eslint-disable-next-line es/no-weak-map -- safe 4013 WeakMap: WeakMap, 4014 set: uncurryThis(WeakMapPrototype.set), 4015 get: uncurryThis(WeakMapPrototype.get), 4016 has: uncurryThis(WeakMapPrototype.has), 4017 remove: uncurryThis(WeakMapPrototype['delete']) 4018}; 4019 4020 4021/***/ }, 4022 4023/***/ 8227 4024(module, __unused_webpack_exports, __webpack_require__) { 4025 4026 4027var globalThis = __webpack_require__(4576); 4028var shared = __webpack_require__(5745); 4029var hasOwn = __webpack_require__(9297); 4030var uid = __webpack_require__(3392); 4031var NATIVE_SYMBOL = __webpack_require__(4495); 4032var USE_SYMBOL_AS_UID = __webpack_require__(7040); 4033 4034var Symbol = globalThis.Symbol; 4035var WellKnownSymbolsStore = shared('wks'); 4036var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid; 4037 4038module.exports = function (name) { 4039 if (!hasOwn(WellKnownSymbolsStore, name)) { 4040 WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name) 4041 ? Symbol[name] 4042 : createWellKnownSymbol('Symbol.' + name); 4043 } return WellKnownSymbolsStore[name]; 4044}; 4045 4046 4047/***/ }, 4048 4049/***/ 4423 4050(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4051 4052 4053var $ = __webpack_require__(6518); 4054var $includes = (__webpack_require__(9617).includes); 4055var fails = __webpack_require__(9039); 4056var addToUnscopables = __webpack_require__(6469); 4057 4058// FF99+ bug 4059var BROKEN_ON_SPARSE = fails(function () { 4060 // eslint-disable-next-line es/no-array-prototype-includes -- detection 4061 return !Array(1).includes(); 4062}); 4063 4064// Safari 26.4- bug 4065var BROKEN_ON_SPARSE_WITH_FROM_INDEX = fails(function () { 4066 // eslint-disable-next-line no-sparse-arrays, es/no-array-prototype-includes -- detection 4067 return [, 1].includes(undefined, 1); 4068}); 4069 4070// `Array.prototype.includes` method 4071// https://tc39.es/ecma262/#sec-array.prototype.includes 4072$({ target: 'Array', proto: true, forced: BROKEN_ON_SPARSE || BROKEN_ON_SPARSE_WITH_FROM_INDEX }, { 4073 includes: function includes(el /* , fromIndex = 0 */) { 4074 return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); 4075 } 4076}); 4077 4078// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables 4079addToUnscopables('includes'); 4080 4081 4082/***/ }, 4083 4084/***/ 4114 4085(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4086 4087 4088var $ = __webpack_require__(6518); 4089var toObject = __webpack_require__(8981); 4090var lengthOfArrayLike = __webpack_require__(6198); 4091var setArrayLength = __webpack_require__(4527); 4092var doesNotExceedSafeInteger = __webpack_require__(6837); 4093var fails = __webpack_require__(9039); 4094 4095var INCORRECT_TO_LENGTH = fails(function () { 4096 return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; 4097}); 4098 4099// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError 4100// https://bugs.chromium.org/p/v8/issues/detail?id=12681 4101var properErrorOnNonWritableLength = function () { 4102 try { 4103 // eslint-disable-next-line es/no-object-defineproperty -- safe 4104 Object.defineProperty([], 'length', { writable: false }).push(); 4105 } catch (error) { 4106 return error instanceof TypeError; 4107 } 4108}; 4109 4110var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); 4111 4112// `Array.prototype.push` method 4113// https://tc39.es/ecma262/#sec-array.prototype.push 4114$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, { 4115 // eslint-disable-next-line no-unused-vars -- required for `.length` 4116 push: function push(item) { 4117 var O = toObject(this); 4118 var len = lengthOfArrayLike(O); 4119 var argCount = arguments.length; 4120 doesNotExceedSafeInteger(len + argCount); 4121 for (var i = 0; i < argCount; i++) { 4122 O[len] = arguments[i]; 4123 len++; 4124 } 4125 setArrayLength(O, len); 4126 return len; 4127 } 4128}); 4129 4130 4131/***/ }, 4132 4133/***/ 8111 4134(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4135 4136 4137var $ = __webpack_require__(6518); 4138var globalThis = __webpack_require__(4576); 4139var anInstance = __webpack_require__(679); 4140var anObject = __webpack_require__(8551); 4141var isCallable = __webpack_require__(4901); 4142var getPrototypeOf = __webpack_require__(2787); 4143var defineBuiltInAccessor = __webpack_require__(2106); 4144var createProperty = __webpack_require__(4659); 4145var fails = __webpack_require__(9039); 4146var hasOwn = __webpack_require__(9297); 4147var wellKnownSymbol = __webpack_require__(8227); 4148var IteratorPrototype = (__webpack_require__(7657).IteratorPrototype); 4149var DESCRIPTORS = __webpack_require__(3724); 4150var IS_PURE = __webpack_require__(6395); 4151 4152var CONSTRUCTOR = 'constructor'; 4153var ITERATOR = 'Iterator'; 4154var TO_STRING_TAG = wellKnownSymbol('toStringTag'); 4155 4156var $TypeError = TypeError; 4157var NativeIterator = globalThis[ITERATOR]; 4158 4159// FF56- have non-standard global helper `Iterator` 4160var FORCED = IS_PURE 4161 || !isCallable(NativeIterator) 4162 || NativeIterator.prototype !== IteratorPrototype 4163 // FF44- non-standard `Iterator` passes previous tests 4164 || !fails(function () { NativeIterator({}); }); 4165 4166var IteratorConstructor = function Iterator() { 4167 anInstance(this, IteratorPrototype); 4168 if (getPrototypeOf(this) === IteratorPrototype) throw new $TypeError('Abstract class Iterator not directly constructable'); 4169}; 4170 4171var defineIteratorPrototypeAccessor = function (key, value) { 4172 if (DESCRIPTORS) { 4173 defineBuiltInAccessor(IteratorPrototype, key, { 4174 configurable: true, 4175 get: function () { 4176 return value; 4177 }, 4178 set: function (replacement) { 4179 anObject(this); 4180 if (this === IteratorPrototype) throw new $TypeError("You can't redefine this property"); 4181 if (hasOwn(this, key)) this[key] = replacement; 4182 else createProperty(this, key, replacement); 4183 } 4184 }); 4185 } else IteratorPrototype[key] = value; 4186}; 4187 4188if (!hasOwn(IteratorPrototype, TO_STRING_TAG)) defineIteratorPrototypeAccessor(TO_STRING_TAG, ITERATOR); 4189 4190if (FORCED || !hasOwn(IteratorPrototype, CONSTRUCTOR) || IteratorPrototype[CONSTRUCTOR] === Object) { 4191 defineIteratorPrototypeAccessor(CONSTRUCTOR, IteratorConstructor); 4192} 4193 4194IteratorConstructor.prototype = IteratorPrototype; 4195 4196// `Iterator` constructor 4197// https://tc39.es/ecma262/#sec-iterator 4198$({ global: true, constructor: true, forced: FORCED }, { 4199 Iterator: IteratorConstructor 4200}); 4201 4202 4203/***/ }, 4204 4205/***/ 9314 4206(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4207 4208 4209var $ = __webpack_require__(6518); 4210var call = __webpack_require__(9565); 4211var anObject = __webpack_require__(8551); 4212var getIteratorDirect = __webpack_require__(1767); 4213var notANaN = __webpack_require__(4149); 4214var toPositiveInteger = __webpack_require__(9590); 4215var iteratorClose = __webpack_require__(9539); 4216var createIteratorProxy = __webpack_require__(9462); 4217var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(684); 4218var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4219var IS_PURE = __webpack_require__(6395); 4220 4221var $RangeError = RangeError; 4222var $Infinity = Infinity; 4223 4224var DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('drop', 0); 4225var dropWithoutClosingOnEarlyError = !IS_PURE && !DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR 4226 && iteratorHelperWithoutClosingOnEarlyError('drop', RangeError); 4227 4228var FORCED = IS_PURE || DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR || dropWithoutClosingOnEarlyError || !function () { 4229 try { 4230 // eslint-disable-next-line es/no-iterator, es/no-iterator-prototype-drop -- detection 4231 Iterator.prototype.drop.call({ 4232 next: function () { return { done: true }; } 4233 }, 0x20000000000000); 4234 } catch (error) { 4235 return error instanceof $RangeError; 4236 } 4237}(); 4238 4239var IteratorProxy = createIteratorProxy(function () { 4240 var iterator = this.iterator; 4241 var next = this.next; 4242 var result, done; 4243 while (this.remaining) { 4244 this.remaining--; 4245 result = anObject(call(next, iterator)); 4246 done = this.done = !!result.done; 4247 if (done) return; 4248 } 4249 result = anObject(call(next, iterator)); 4250 done = this.done = !!result.done; 4251 if (!done) return result.value; 4252}); 4253 4254// `Iterator.prototype.drop` method 4255// https://tc39.es/ecma262/#sec-iterator.prototype.drop 4256$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { 4257 drop: function drop(limit) { 4258 anObject(this); 4259 var remaining; 4260 try { 4261 remaining = toPositiveInteger(notANaN(+limit)); 4262 if (remaining > 0x1FFFFFFFFFFFFF && remaining !== $Infinity) { 4263 throw new $RangeError('The argument should be a safe integer'); 4264 } 4265 } catch (error) { 4266 iteratorClose(this, 'throw', error); 4267 } 4268 4269 if (dropWithoutClosingOnEarlyError) return call(dropWithoutClosingOnEarlyError, this, remaining); 4270 4271 return new IteratorProxy(getIteratorDirect(this), { 4272 remaining: remaining 4273 }); 4274 } 4275}); 4276 4277 4278/***/ }, 4279 4280/***/ 1148 4281(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4282 4283 4284var $ = __webpack_require__(6518); 4285var call = __webpack_require__(9565); 4286var iterate = __webpack_require__(2652); 4287var aCallable = __webpack_require__(9306); 4288var anObject = __webpack_require__(8551); 4289var getIteratorDirect = __webpack_require__(1767); 4290var iteratorClose = __webpack_require__(9539); 4291var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4292 4293var everyWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('every', TypeError); 4294 4295// `Iterator.prototype.every` method 4296// https://tc39.es/ecma262/#sec-iterator.prototype.every 4297$({ target: 'Iterator', proto: true, real: true, forced: everyWithoutClosingOnEarlyError }, { 4298 every: function every(predicate) { 4299 anObject(this); 4300 try { 4301 aCallable(predicate); 4302 } catch (error) { 4303 iteratorClose(this, 'throw', error); 4304 } 4305 4306 if (everyWithoutClosingOnEarlyError) return call(everyWithoutClosingOnEarlyError, this, predicate); 4307 4308 var record = getIteratorDirect(this); 4309 var counter = 0; 4310 return !iterate(record, function (value, stop) { 4311 if (!predicate(value, counter++)) return stop(); 4312 }, { IS_RECORD: true, INTERRUPTED: true }).stopped; 4313 } 4314}); 4315 4316 4317/***/ }, 4318 4319/***/ 2489 4320(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4321 4322 4323var $ = __webpack_require__(6518); 4324var call = __webpack_require__(9565); 4325var aCallable = __webpack_require__(9306); 4326var anObject = __webpack_require__(8551); 4327var getIteratorDirect = __webpack_require__(1767); 4328var createIteratorProxy = __webpack_require__(9462); 4329var callWithSafeIterationClosing = __webpack_require__(6319); 4330var IS_PURE = __webpack_require__(6395); 4331var iteratorClose = __webpack_require__(9539); 4332var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(684); 4333var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4334 4335var FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('filter', function () { /* empty */ }); 4336var filterWithoutClosingOnEarlyError = !IS_PURE && !FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR 4337 && iteratorHelperWithoutClosingOnEarlyError('filter', TypeError); 4338 4339var FORCED = IS_PURE || FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR || filterWithoutClosingOnEarlyError; 4340 4341var IteratorProxy = createIteratorProxy(function () { 4342 var iterator = this.iterator; 4343 var predicate = this.predicate; 4344 var next = this.next; 4345 var result, done, value; 4346 while (true) { 4347 result = anObject(call(next, iterator)); 4348 done = this.done = !!result.done; 4349 if (done) return; 4350 value = result.value; 4351 if (callWithSafeIterationClosing(iterator, predicate, [value, this.counter++], true)) return value; 4352 } 4353}); 4354 4355// `Iterator.prototype.filter` method 4356// https://tc39.es/ecma262/#sec-iterator.prototype.filter 4357$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { 4358 filter: function filter(predicate) { 4359 anObject(this); 4360 try { 4361 aCallable(predicate); 4362 } catch (error) { 4363 iteratorClose(this, 'throw', error); 4364 } 4365 4366 if (filterWithoutClosingOnEarlyError) return call(filterWithoutClosingOnEarlyError, this, predicate); 4367 4368 return new IteratorProxy(getIteratorDirect(this), { 4369 predicate: predicate 4370 }); 4371 } 4372}); 4373 4374 4375/***/ }, 4376 4377/***/ 116 4378(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4379 4380 4381var $ = __webpack_require__(6518); 4382var call = __webpack_require__(9565); 4383var iterate = __webpack_require__(2652); 4384var aCallable = __webpack_require__(9306); 4385var anObject = __webpack_require__(8551); 4386var getIteratorDirect = __webpack_require__(1767); 4387var iteratorClose = __webpack_require__(9539); 4388var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4389 4390var findWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('find', TypeError); 4391 4392// `Iterator.prototype.find` method 4393// https://tc39.es/ecma262/#sec-iterator.prototype.find 4394$({ target: 'Iterator', proto: true, real: true, forced: findWithoutClosingOnEarlyError }, { 4395 find: function find(predicate) { 4396 anObject(this); 4397 try { 4398 aCallable(predicate); 4399 } catch (error) { 4400 iteratorClose(this, 'throw', error); 4401 } 4402 4403 if (findWithoutClosingOnEarlyError) return call(findWithoutClosingOnEarlyError, this, predicate); 4404 4405 var record = getIteratorDirect(this); 4406 var counter = 0; 4407 return iterate(record, function (value, stop) { 4408 if (predicate(value, counter++)) return stop(value); 4409 }, { IS_RECORD: true, INTERRUPTED: true }).result; 4410 } 4411}); 4412 4413 4414/***/ }, 4415 4416/***/ 531 4417(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4418 4419 4420var $ = __webpack_require__(6518); 4421var call = __webpack_require__(9565); 4422var aCallable = __webpack_require__(9306); 4423var anObject = __webpack_require__(8551); 4424var getIteratorDirect = __webpack_require__(1767); 4425var getIteratorFlattenable = __webpack_require__(8646); 4426var createIteratorProxy = __webpack_require__(9462); 4427var iteratorClose = __webpack_require__(9539); 4428var fails = __webpack_require__(9039); 4429var IS_PURE = __webpack_require__(6395); 4430var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(684); 4431var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4432 4433// Should not throw an error for an iterator without `return` method. Fixed in Safari 26.2 4434// https://bugs.webkit.org/show_bug.cgi?id=297532 4435var THROWS_ON_ITERATOR_WITHOUT_RETURN = !IS_PURE && fails(function () { 4436 // eslint-disable-next-line es/no-array-prototype-values, es/no-iterator-prototype-flatmap, es/no-iterator-prototype-find -- testing 4437 return [1].values() 4438 .flatMap(function () { return [1]; }) 4439 .find(function () { return true; }) !== 1; 4440}); 4441 4442var FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !THROWS_ON_ITERATOR_WITHOUT_RETURN 4443 && !iteratorHelperThrowsOnInvalidIterator('flatMap', function () { /* empty */ }); 4444 4445var flatMapWithoutClosingOnEarlyError = !IS_PURE && !THROWS_ON_ITERATOR_WITHOUT_RETURN && !FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR 4446 && iteratorHelperWithoutClosingOnEarlyError('flatMap', TypeError); 4447 4448var FORCED = IS_PURE || THROWS_ON_ITERATOR_WITHOUT_RETURN || FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR 4449 || flatMapWithoutClosingOnEarlyError; 4450 4451var IteratorProxy = createIteratorProxy(function () { 4452 var iterator = this.iterator; 4453 var mapper = this.mapper; 4454 var result, inner; 4455 4456 while (true) { 4457 if (inner = this.inner) try { 4458 result = anObject(call(inner.next, inner.iterator)); 4459 if (!result.done) return result.value; 4460 this.inner = null; 4461 } catch (error) { iteratorClose(iterator, 'throw', error); } 4462 4463 result = anObject(call(this.next, iterator)); 4464 4465 if (this.done = !!result.done) return; 4466 4467 try { 4468 this.inner = getIteratorFlattenable(mapper(result.value, this.counter++), false); 4469 } catch (error) { iteratorClose(iterator, 'throw', error); } 4470 } 4471}); 4472 4473// `Iterator.prototype.flatMap` method 4474// https://tc39.es/ecma262/#sec-iterator.prototype.flatmap 4475$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { 4476 flatMap: function flatMap(mapper) { 4477 anObject(this); 4478 try { 4479 aCallable(mapper); 4480 } catch (error) { 4481 iteratorClose(this, 'throw', error); 4482 } 4483 4484 if (flatMapWithoutClosingOnEarlyError) return call(flatMapWithoutClosingOnEarlyError, this, mapper); 4485 4486 return new IteratorProxy(getIteratorDirect(this), { 4487 mapper: mapper, 4488 inner: null 4489 }); 4490 } 4491}); 4492 4493 4494/***/ }, 4495 4496/***/ 7588 4497(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4498 4499 4500var $ = __webpack_require__(6518); 4501var call = __webpack_require__(9565); 4502var iterate = __webpack_require__(2652); 4503var aCallable = __webpack_require__(9306); 4504var anObject = __webpack_require__(8551); 4505var getIteratorDirect = __webpack_require__(1767); 4506var iteratorClose = __webpack_require__(9539); 4507var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4508 4509var forEachWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('forEach', TypeError); 4510 4511// `Iterator.prototype.forEach` method 4512// https://tc39.es/ecma262/#sec-iterator.prototype.foreach 4513$({ target: 'Iterator', proto: true, real: true, forced: forEachWithoutClosingOnEarlyError }, { 4514 forEach: function forEach(fn) { 4515 anObject(this); 4516 try { 4517 aCallable(fn); 4518 } catch (error) { 4519 iteratorClose(this, 'throw', error); 4520 } 4521 4522 if (forEachWithoutClosingOnEarlyError) return call(forEachWithoutClosingOnEarlyError, this, fn); 4523 4524 var record = getIteratorDirect(this); 4525 var counter = 0; 4526 iterate(record, function (value) { 4527 fn(value, counter++); 4528 }, { IS_RECORD: true }); 4529 } 4530}); 4531 4532 4533/***/ }, 4534 4535/***/ 1701 4536(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4537 4538 4539var $ = __webpack_require__(6518); 4540var call = __webpack_require__(9565); 4541var aCallable = __webpack_require__(9306); 4542var anObject = __webpack_require__(8551); 4543var getIteratorDirect = __webpack_require__(1767); 4544var createIteratorProxy = __webpack_require__(9462); 4545var callWithSafeIterationClosing = __webpack_require__(6319); 4546var iteratorClose = __webpack_require__(9539); 4547var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(684); 4548var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4549var IS_PURE = __webpack_require__(6395); 4550 4551var MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('map', function () { /* empty */ }); 4552var mapWithoutClosingOnEarlyError = !IS_PURE && !MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR 4553 && iteratorHelperWithoutClosingOnEarlyError('map', TypeError); 4554 4555var FORCED = IS_PURE || MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR || mapWithoutClosingOnEarlyError; 4556 4557var IteratorProxy = createIteratorProxy(function () { 4558 var iterator = this.iterator; 4559 var result = anObject(call(this.next, iterator)); 4560 var done = this.done = !!result.done; 4561 if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true); 4562}); 4563 4564// `Iterator.prototype.map` method 4565// https://tc39.es/ecma262/#sec-iterator.prototype.map 4566$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { 4567 map: function map(mapper) { 4568 anObject(this); 4569 try { 4570 aCallable(mapper); 4571 } catch (error) { 4572 iteratorClose(this, 'throw', error); 4573 } 4574 4575 if (mapWithoutClosingOnEarlyError) return call(mapWithoutClosingOnEarlyError, this, mapper); 4576 4577 return new IteratorProxy(getIteratorDirect(this), { 4578 mapper: mapper 4579 }); 4580 } 4581}); 4582 4583 4584/***/ }, 4585 4586/***/ 3579 4587(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4588 4589 4590var $ = __webpack_require__(6518); 4591var call = __webpack_require__(9565); 4592var iterate = __webpack_require__(2652); 4593var aCallable = __webpack_require__(9306); 4594var anObject = __webpack_require__(8551); 4595var getIteratorDirect = __webpack_require__(1767); 4596var iteratorClose = __webpack_require__(9539); 4597var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4598 4599var someWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('some', TypeError); 4600 4601// `Iterator.prototype.some` method 4602// https://tc39.es/ecma262/#sec-iterator.prototype.some 4603$({ target: 'Iterator', proto: true, real: true, forced: someWithoutClosingOnEarlyError }, { 4604 some: function some(predicate) { 4605 anObject(this); 4606 try { 4607 aCallable(predicate); 4608 } catch (error) { 4609 iteratorClose(this, 'throw', error); 4610 } 4611 4612 if (someWithoutClosingOnEarlyError) return call(someWithoutClosingOnEarlyError, this, predicate); 4613 4614 var record = getIteratorDirect(this); 4615 var counter = 0; 4616 return iterate(record, function (value, stop) { 4617 if (predicate(value, counter++)) return stop(); 4618 }, { IS_RECORD: true, INTERRUPTED: true }).stopped; 4619 } 4620}); 4621 4622 4623/***/ }, 4624 4625/***/ 4972 4626(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4627 4628 4629var $ = __webpack_require__(6518); 4630var call = __webpack_require__(9565); 4631var anObject = __webpack_require__(8551); 4632var getIteratorDirect = __webpack_require__(1767); 4633var notANaN = __webpack_require__(4149); 4634var toPositiveInteger = __webpack_require__(9590); 4635var createIteratorProxy = __webpack_require__(9462); 4636var iteratorClose = __webpack_require__(9539); 4637var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(684); 4638var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(4549); 4639var IS_PURE = __webpack_require__(6395); 4640 4641var $RangeError = RangeError; 4642var $Infinity = Infinity; 4643 4644var TAKE_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('take', 1); 4645var takeWithoutClosingOnEarlyError = !IS_PURE && !TAKE_WITHOUT_THROWING_ON_INVALID_ITERATOR 4646 && iteratorHelperWithoutClosingOnEarlyError('take', RangeError); 4647 4648var FORCED = IS_PURE || TAKE_WITHOUT_THROWING_ON_INVALID_ITERATOR || takeWithoutClosingOnEarlyError || !function () { 4649 try { 4650 // eslint-disable-next-line es/no-iterator, es/no-iterator-prototype-take -- detection 4651 Iterator.prototype.take.call({ 4652 next: function () { return { done: true }; } 4653 }, 0x20000000000000); 4654 } catch (error) { 4655 return error instanceof $RangeError; 4656 } 4657}(); 4658 4659var IteratorProxy = createIteratorProxy(function () { 4660 var iterator = this.iterator; 4661 if (!this.remaining--) { 4662 this.done = true; 4663 return iteratorClose(iterator, 'normal', undefined); 4664 } 4665 var result = anObject(call(this.next, iterator)); 4666 var done = this.done = !!result.done; 4667 if (!done) return result.value; 4668}); 4669 4670// `Iterator.prototype.take` method 4671// https://tc39.es/ecma262/#sec-iterator.prototype.take 4672$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { 4673 take: function take(limit) { 4674 anObject(this); 4675 var remaining; 4676 try { 4677 remaining = toPositiveInteger(notANaN(+limit)); 4678 if (remaining > 0x1FFFFFFFFFFFFF && remaining !== $Infinity) { 4679 throw new $RangeError('The argument should be a safe integer'); 4680 } 4681 } catch (error) { 4682 iteratorClose(this, 'throw', error); 4683 } 4684 4685 if (takeWithoutClosingOnEarlyError) return call(takeWithoutClosingOnEarlyError, this, remaining); 4686 4687 return new IteratorProxy(getIteratorDirect(this), { 4688 remaining: remaining 4689 }); 4690 } 4691}); 4692 4693 4694/***/ }, 4695 4696/***/ 1806 4697(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4698 4699 4700var $ = __webpack_require__(6518); 4701var anObject = __webpack_require__(8551); 4702var createProperty = __webpack_require__(4659); 4703var iterate = __webpack_require__(2652); 4704var getIteratorDirect = __webpack_require__(1767); 4705 4706// `Iterator.prototype.toArray` method 4707// https://tc39.es/ecma262/#sec-iterator.prototype.toarray 4708$({ target: 'Iterator', proto: true, real: true }, { 4709 toArray: function toArray() { 4710 var result = []; 4711 var index = 0; 4712 iterate(getIteratorDirect(anObject(this)), function (element) { 4713 createProperty(result, index++, element); 4714 }, { IS_RECORD: true }); 4715 return result; 4716 } 4717}); 4718 4719 4720/***/ }, 4721 4722/***/ 9112 4723(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4724 4725 4726var $ = __webpack_require__(6518); 4727var DESCRIPTORS = __webpack_require__(3724); 4728var globalThis = __webpack_require__(4576); 4729var getBuiltIn = __webpack_require__(7751); 4730var uncurryThis = __webpack_require__(9504); 4731var call = __webpack_require__(9565); 4732var isCallable = __webpack_require__(4901); 4733var isObject = __webpack_require__(34); 4734var isArray = __webpack_require__(4376); 4735var hasOwn = __webpack_require__(9297); 4736var toString = __webpack_require__(655); 4737var lengthOfArrayLike = __webpack_require__(6198); 4738var createProperty = __webpack_require__(4659); 4739var fails = __webpack_require__(9039); 4740var parseJSONString = __webpack_require__(8235); 4741var NATIVE_SYMBOL = __webpack_require__(4495); 4742 4743var JSON = globalThis.JSON; 4744var Number = globalThis.Number; 4745var SyntaxError = globalThis.SyntaxError; 4746var nativeParse = JSON && JSON.parse; 4747var enumerableOwnProperties = getBuiltIn('Object', 'keys'); 4748// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 4749var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; 4750var at = uncurryThis(''.charAt); 4751var slice = uncurryThis(''.slice); 4752var exec = uncurryThis(/./.exec); 4753var push = uncurryThis([].push); 4754 4755var IS_DIGIT = /^\d$/; 4756var IS_NON_ZERO_DIGIT = /^[1-9]$/; 4757var IS_NUMBER_START = /^[\d-]$/; 4758var IS_WHITESPACE = /^[\t\n\r ]$/; 4759 4760var PRIMITIVE = 0; 4761var OBJECT = 1; 4762 4763var $parse = function (source, reviver) { 4764 source = toString(source); 4765 var context = new Context(source, 0); 4766 var root = context.parse(); 4767 var value = root.value; 4768 var endIndex = context.skip(IS_WHITESPACE, root.end); 4769 if (endIndex < source.length) { 4770 throw new SyntaxError('Unexpected extra character: "' + at(source, endIndex) + '" after the parsed data at: ' + endIndex); 4771 } 4772 return isCallable(reviver) ? internalize({ '': value }, '', reviver, root) : value; 4773}; 4774 4775var internalize = function (holder, name, reviver, node) { 4776 var val = holder[name]; 4777 var unmodified = node && val === node.value; 4778 var context = unmodified && typeof node.source == 'string' ? { source: node.source } : {}; 4779 var elementRecordsLen, keys, len, i, P; 4780 if (isObject(val)) { 4781 var nodeIsArray = isArray(val); 4782 var nodes = unmodified ? node.nodes : nodeIsArray ? [] : {}; 4783 if (nodeIsArray) { 4784 elementRecordsLen = nodes.length; 4785 len = lengthOfArrayLike(val); 4786 for (i = 0; i < len; i++) { 4787 internalizeProperty(val, i, internalize(val, '' + i, reviver, i < elementRecordsLen ? nodes[i] : undefined)); 4788 } 4789 } else { 4790 keys = enumerableOwnProperties(val); 4791 len = lengthOfArrayLike(keys); 4792 for (i = 0; i < len; i++) { 4793 P = keys[i]; 4794 internalizeProperty(val, P, internalize(val, P, reviver, hasOwn(nodes, P) ? nodes[P] : undefined)); 4795 } 4796 } 4797 } 4798 return call(reviver, holder, name, val, context); 4799}; 4800 4801var internalizeProperty = function (object, key, value) { 4802 if (DESCRIPTORS) { 4803 var descriptor = getOwnPropertyDescriptor(object, key); 4804 if (descriptor && !descriptor.configurable) return; 4805 } 4806 if (value === undefined) delete object[key]; 4807 else createProperty(object, key, value); 4808}; 4809 4810var Node = function (value, end, source, nodes) { 4811 this.value = value; 4812 this.end = end; 4813 this.source = source; 4814 this.nodes = nodes; 4815}; 4816 4817var Context = function (source, index) { 4818 this.source = source; 4819 this.index = index; 4820}; 4821 4822// https://www.json.org/json-en.html 4823Context.prototype = { 4824 fork: function (nextIndex) { 4825 return new Context(this.source, nextIndex); 4826 }, 4827 parse: function () { 4828 var source = this.source; 4829 var i = this.skip(IS_WHITESPACE, this.index); 4830 var fork = this.fork(i); 4831 var chr = at(source, i); 4832 if (exec(IS_NUMBER_START, chr)) return fork.number(); 4833 switch (chr) { 4834 case '{': 4835 return fork.object(); 4836 case '[': 4837 return fork.array(); 4838 case '"': 4839 return fork.string(); 4840 case 't': 4841 return fork.keyword(true); 4842 case 'f': 4843 return fork.keyword(false); 4844 case 'n': 4845 return fork.keyword(null); 4846 } throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i); 4847 }, 4848 node: function (type, value, start, end, nodes) { 4849 return new Node(value, end, type ? null : slice(this.source, start, end), nodes); 4850 }, 4851 object: function () { 4852 var source = this.source; 4853 var i = this.index + 1; 4854 var expectKeypair = false; 4855 var object = {}; 4856 var nodes = {}; 4857 var closed = false; 4858 while (i < source.length) { 4859 i = this.until(['"', '}'], i); 4860 if (at(source, i) === '}' && !expectKeypair) { 4861 i++; 4862 closed = true; 4863 break; 4864 } 4865 // Parsing the key 4866 var result = this.fork(i).string(); 4867 var key = result.value; 4868 i = result.end; 4869 i = this.until([':'], i) + 1; 4870 // Parsing value 4871 i = this.skip(IS_WHITESPACE, i); 4872 result = this.fork(i).parse(); 4873 createProperty(nodes, key, result); 4874 createProperty(object, key, result.value); 4875 i = this.until([',', '}'], result.end); 4876 var chr = at(source, i); 4877 if (chr === ',') { 4878 expectKeypair = true; 4879 i++; 4880 } else if (chr === '}') { 4881 i++; 4882 closed = true; 4883 break; 4884 } 4885 } 4886 if (!closed) throw new SyntaxError('Unterminated object at: ' + i); 4887 return this.node(OBJECT, object, this.index, i, nodes); 4888 }, 4889 array: function () { 4890 var source = this.source; 4891 var i = this.index + 1; 4892 var expectElement = false; 4893 var array = []; 4894 var nodes = []; 4895 var closed = false; 4896 while (i < source.length) { 4897 i = this.skip(IS_WHITESPACE, i); 4898 if (at(source, i) === ']' && !expectElement) { 4899 i++; 4900 closed = true; 4901 break; 4902 } 4903 var result = this.fork(i).parse(); 4904 push(nodes, result); 4905 push(array, result.value); 4906 i = this.until([',', ']'], result.end); 4907 if (at(source, i) === ',') { 4908 expectElement = true; 4909 i++; 4910 } else if (at(source, i) === ']') { 4911 i++; 4912 closed = true; 4913 break; 4914 } 4915 } 4916 if (!closed) throw new SyntaxError('Unterminated array at: ' + i); 4917 return this.node(OBJECT, array, this.index, i, nodes); 4918 }, 4919 string: function () { 4920 var index = this.index; 4921 var parsed = parseJSONString(this.source, this.index + 1); 4922 return this.node(PRIMITIVE, parsed.value, index, parsed.end); 4923 }, 4924 number: function () { 4925 var source = this.source; 4926 var startIndex = this.index; 4927 var i = startIndex; 4928 if (at(source, i) === '-') i++; 4929 if (at(source, i) === '0') i++; 4930 else if (exec(IS_NON_ZERO_DIGIT, at(source, i))) i = this.skip(IS_DIGIT, i + 1); 4931 else throw new SyntaxError('Failed to parse number at: ' + i); 4932 if (at(source, i) === '.') { 4933 var fractionStartIndex = i + 1; 4934 i = this.skip(IS_DIGIT, fractionStartIndex); 4935 if (fractionStartIndex === i) throw new SyntaxError("Failed to parse number's fraction at: " + i); 4936 } 4937 if (at(source, i) === 'e' || at(source, i) === 'E') { 4938 i++; 4939 if (at(source, i) === '+' || at(source, i) === '-') i++; 4940 var exponentStartIndex = i; 4941 i = this.skip(IS_DIGIT, i); 4942 if (exponentStartIndex === i) throw new SyntaxError("Failed to parse number's exponent value at: " + i); 4943 } 4944 return this.node(PRIMITIVE, Number(slice(source, startIndex, i)), startIndex, i); 4945 }, 4946 keyword: function (value) { 4947 var keyword = '' + value; 4948 var index = this.index; 4949 var endIndex = index + keyword.length; 4950 if (slice(this.source, index, endIndex) !== keyword) throw new SyntaxError('Failed to parse value at: ' + index); 4951 return this.node(PRIMITIVE, value, index, endIndex); 4952 }, 4953 skip: function (regex, i) { 4954 var source = this.source; 4955 for (; i < source.length; i++) if (!exec(regex, at(source, i))) break; 4956 return i; 4957 }, 4958 until: function (array, i) { 4959 i = this.skip(IS_WHITESPACE, i); 4960 var chr = at(this.source, i); 4961 for (var j = 0; j < array.length; j++) if (array[j] === chr) return i; 4962 throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i); 4963 } 4964}; 4965 4966var NO_SOURCE_SUPPORT = fails(function () { 4967 var unsafeInt = '9007199254740993'; 4968 var source; 4969 nativeParse(unsafeInt, function (key, value, context) { 4970 source = context.source; 4971 }); 4972 return source !== unsafeInt; 4973}); 4974 4975var PROPER_BASE_PARSE = NATIVE_SYMBOL && !fails(function () { 4976 // Safari 9 bug 4977 return 1 / nativeParse('-0 \t') !== -Infinity; 4978}); 4979 4980// `JSON.parse` method 4981// https://tc39.es/ecma262/#sec-json.parse 4982// https://github.com/tc39/proposal-json-parse-with-source 4983$({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, { 4984 parse: function parse(text, reviver) { 4985 return PROPER_BASE_PARSE && !isCallable(reviver) ? nativeParse(text) : $parse(text, reviver); 4986 } 4987}); 4988 4989 4990/***/ }, 4991 4992/***/ 3110 4993(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 4994 4995 4996var $ = __webpack_require__(6518); 4997var getBuiltIn = __webpack_require__(7751); 4998var call = __webpack_require__(9565); 4999var uncurryThis = __webpack_require__(9504); 5000var fails = __webpack_require__(9039); 5001var isArray = __webpack_require__(4376); 5002var isCallable = __webpack_require__(4901); 5003var isObject = __webpack_require__(34); 5004var create = __webpack_require__(2360); 5005var isRawJSON = __webpack_require__(5810); 5006var isSymbol = __webpack_require__(757); 5007var classof = __webpack_require__(2195); 5008var thisNumberValue = __webpack_require__(1240); 5009var includes = (__webpack_require__(9617).includes); 5010var hasOwn = __webpack_require__(9297); 5011var toString = __webpack_require__(655); 5012var parseJSONString = __webpack_require__(8235); 5013var uid = __webpack_require__(3392); 5014var NATIVE_SYMBOL = __webpack_require__(4495); 5015var NATIVE_RAW_JSON = __webpack_require__(7819); 5016 5017var $String = String; 5018var $TypeError = TypeError; 5019var $stringify = getBuiltIn('JSON', 'stringify'); 5020var $BigInt = getBuiltIn('BigInt'); 5021var stringValueOf = uncurryThis(''.valueOf); 5022var booleanValueOf = uncurryThis(true.valueOf); 5023var bigIntValueOf = $BigInt && uncurryThis($BigInt.prototype.valueOf); 5024var exec = uncurryThis(/./.exec); 5025var charAt = uncurryThis(''.charAt); 5026var charCodeAt = uncurryThis(''.charCodeAt); 5027var replace = uncurryThis(''.replace); 5028var slice = uncurryThis(''.slice); 5029var push = uncurryThis([].push); 5030var pop = uncurryThis([].pop); 5031var numberToString = uncurryThis(1.1.toString); 5032 5033var surrogates = /[\uD800-\uDFFF]/g; 5034var leadingSurrogates = /^[\uD800-\uDBFF]$/; 5035var trailingSurrogates = /^[\uDC00-\uDFFF]$/; 5036var digits = /^\d+$/; 5037 5038// a placeholder of a raw JSON value 5039var RAW_MARK = uid(); 5040// a prefix of keys of a reordered object, see `createOrderedObject` 5041var KEY_MARK = uid(); 5042// the last key of a reordered object, marks the end of its serialization 5043var END_MARK = uid(); 5044var RAW_MARK_LENGTH = RAW_MARK.length; 5045var KEY_MARK_LENGTH = KEY_MARK.length; 5046 5047var WRONG_SYMBOLS_CONVERSION = !NATIVE_SYMBOL || fails(function () { 5048 var symbol = getBuiltIn('Symbol')('stringify detection'); 5049 // MS Edge converts symbol values to JSON as {} 5050 return $stringify([symbol]) !== '[null]' 5051 // WebKit converts symbol values to JSON as null 5052 || $stringify({ a: symbol }) !== '{}' 5053 // V8 throws on boxed symbols 5054 || $stringify(Object(symbol)) !== '{}'; 5055}); 5056 5057// https://github.com/tc39/proposal-well-formed-stringify 5058var ILL_FORMED_UNICODE = fails(function () { 5059 return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' 5060 || $stringify('\uDEAD') !== '"\\udead"'; 5061}); 5062 5063var isRawJSONValue = NATIVE_RAW_JSON ? getBuiltIn('JSON', 'isRawJSON') : isRawJSON; 5064 5065var stringifyWithProperSymbolsConversion = WRONG_SYMBOLS_CONVERSION ? function (it, replacer, space) { 5066 return $stringify(it, function (key, value) { 5067 var replaced = call(replacer, this, key, value); 5068 if (!isSymbol(replaced)) return replaced; 5069 }, space); 5070} : $stringify; 5071 5072var fixIllFormedJSON = function (match, offset, string) { 5073 var prev = charAt(string, offset - 1); 5074 var next = charAt(string, offset + 1); 5075 if ( 5076 (exec(leadingSurrogates, match) && !exec(trailingSurrogates, next)) || 5077 (exec(trailingSurrogates, match) && !exec(leadingSurrogates, prev)) 5078 ) { 5079 return '\\u' + numberToString(charCodeAt(match, 0), 16); 5080 } return match; 5081}; 5082 5083// `PropertyList` of `JSON.stringify` 5084// https://tc39.es/ecma262/#sec-json.stringify 5085var getPropertyList = function (replacer) { 5086 if (!isArray(replacer)) return; 5087 var rawLength = replacer.length; 5088 var propertyList = []; 5089 // a null prototype object is used as a set of already added keys to keep the deduplication linear 5090 var addedKeys = create(null); 5091 for (var i = 0; i < rawLength; i++) { 5092 var element = replacer[i]; 5093 var key; 5094 if (typeof element == 'string') key = element; 5095 else if (typeof element == 'number' || classof(element) === 'Number' || classof(element) === 'String') key = toString(element); 5096 else continue; 5097 if (!hasOwn(addedKeys, key)) { 5098 addedKeys[key] = true; 5099 push(propertyList, key); 5100 } 5101 } 5102 return propertyList; 5103}; 5104 5105// values with such an internal slot are unwrapped by `SerializeJSONProperty` instead of being serialized as objects 5106var hasInternalSlot = function (valueOf, it) { 5107 try { 5108 valueOf(it); 5109 return true; 5110 } catch (error) { 5111 return false; 5112 } 5113}; 5114 5115// the slot check is expensive, so it's performed only for the kind reported by the value itself - 5116// a value lying about its kind via `Symbol.toStringTag` is serialized as an ordinary object 5117var isBoxedPrimitive = function (it) { 5118 var kind = classof(it); 5119 return (kind === 'Number' && hasInternalSlot(thisNumberValue, it)) 5120 || (kind === 'String' && hasInternalSlot(stringValueOf, it)) 5121 || (kind === 'Boolean' && hasInternalSlot(booleanValueOf, it)) 5122 || (!!bigIntValueOf && kind === 'BigInt' && hasInternalSlot(bigIntValueOf, it)); 5123}; 5124 5125// only objects serialized by `SerializeJSONObject` are affected by the property list 5126var isSerializedAsObject = function (it) { 5127 if (!isObject(it) || isCallable(it) || isArray(it)) return false; 5128 try { 5129 return !isBoxedPrimitive(it); 5130 // `classof` reads `Symbol.toStringTag`, so a proxy could throw - it has no internal slots anyway 5131 } catch (error) { 5132 return true; 5133 } 5134}; 5135 5136// the engine unwraps it in the same order as it would read the original property, 5137// so the property is read lazily and `toJSON` is called once and with the original key 5138var createElementHolder = function (holder, key) { 5139 return { 5140 toJSON: function () { 5141 var element = holder[key]; 5142 if (isObject(element) || typeof element == 'bigint') { 5143 var elementToJSON = element.toJSON; 5144 if (isCallable(elementToJSON)) element = call(elementToJSON, element, key); 5145 } return element; 5146 } 5147 }; 5148}; 5149 5150// own keys of objects are sorted - integer-like keys are moved to the beginning, 5151// so such keys should be marked and restored in the serialized string 5152var getKeyPrefix = function (propertyList) { 5153 for (var i = 0, length = propertyList.length; i < length; i++) { 5154 if (exec(digits, propertyList[i])) return KEY_MARK; 5155 } return ''; 5156}; 5157 5158// `SerializeJSONObject` iterates the property list, so the value is replaced with an object with keys in this order 5159var createOrderedObject = function (value, propertyList, keyPrefix) { 5160 // keys are not marked if the property list has no integer-like keys, so `Object.prototype` 5161 // with a setter, a non-writable property or `__proto__` should not intercept the assignment 5162 var ordered = create(null); 5163 for (var i = 0, length = propertyList.length; i < length; i++) { 5164 var key = propertyList[i]; 5165 ordered[keyPrefix + key] = createElementHolder(value, key); 5166 } 5167 ordered[END_MARK] = null; 5168 return ordered; 5169}; 5170 5171// `JSON.stringify` method 5172// https://tc39.es/ecma262/#sec-json.stringify 5173// https://github.com/tc39/proposal-json-parse-with-source 5174if ($stringify) $({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE || !NATIVE_RAW_JSON }, { 5175 stringify: function stringify(text, replacer, space) { 5176 var replacerFunction = isCallable(replacer) ? replacer : undefined; 5177 var propertyList = replacerFunction ? undefined : getPropertyList(replacer); 5178 var keyPrefix = propertyList && getKeyPrefix(propertyList); 5179 var rawStrings = []; 5180 var openObjects = []; 5181 var parentOrdered = []; 5182 var currentOrdered; 5183 var marked = false; 5184 var root = true; 5185 5186 var json = stringifyWithProperSymbolsConversion(text, function (key, value) { 5187 // some old implementations (like WebKit) could pass numbers as keys 5188 key = $String(key); 5189 5190 if (propertyList) { 5191 if (key === END_MARK) { 5192 pop(openObjects); 5193 currentOrdered = pop(parentOrdered); 5194 return; 5195 } 5196 if (root) root = false; 5197 // the innermost reordered object already contains only keys of the property list and arrays are not 5198 // affected by it, the rest of objects (like objects with a fake `Symbol.toStringTag`) are filtered here 5199 else if (this !== currentOrdered && !isArray(this) && !includes(propertyList, key)) return; 5200 } else if (replacerFunction) value = call(replacerFunction, this, key, value); 5201 5202 if (isRawJSONValue(value)) { 5203 if (NATIVE_RAW_JSON) return value; 5204 marked = true; 5205 return RAW_MARK + (push(rawStrings, value.rawJSON) - 1); 5206 } 5207 5208 if (propertyList && isSerializedAsObject(value)) { 5209 // reordered objects are new each time, so cycles should be detected before the engine does it 5210 if (includes(openObjects, value)) throw new $TypeError('Converting circular structure to JSON'); 5211 var ordered = createOrderedObject(value, propertyList, keyPrefix); 5212 push(openObjects, value); 5213 push(parentOrdered, currentOrdered); 5214 currentOrdered = ordered; 5215 if (keyPrefix) marked = true; 5216 return ordered; 5217 } 5218 5219 return value; 5220 }, space); 5221 5222 if (typeof json != 'string') return json; 5223 5224 if (ILL_FORMED_UNICODE) json = replace(json, surrogates, fixIllFormedJSON); 5225 5226 if (!marked) return json; 5227 5228 var result = ''; 5229 var length = json.length; 5230 5231 for (var i = 0; i < length; i++) { 5232 var chr = charAt(json, i); 5233 if (chr === '"') { 5234 var end = parseJSONString(json, ++i).end - 1; 5235 var string = slice(json, i, end); 5236 if (slice(string, 0, RAW_MARK_LENGTH) === RAW_MARK) result += rawStrings[slice(string, RAW_MARK_LENGTH)]; 5237 else if (slice(string, 0, KEY_MARK_LENGTH) === KEY_MARK) result += '"' + slice(string, KEY_MARK_LENGTH) + '"'; 5238 else result += '"' + string + '"'; 5239 i = end; 5240 } else result += chr; 5241 } 5242 5243 return result; 5244 } 5245}); 5246 5247 5248/***/ }, 5249 5250/***/ 2731 5251(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5252 5253 5254var $ = __webpack_require__(6518); 5255var aCallable = __webpack_require__(9306); 5256var MapHelpers = __webpack_require__(2248); 5257var IS_PURE = __webpack_require__(6395); 5258 5259var get = MapHelpers.get; 5260var has = MapHelpers.has; 5261var set = MapHelpers.set; 5262 5263// `Map.prototype.getOrInsertComputed` method 5264// https://tc39.es/ecma262/#sec-map.prototype.getorinsertcomputed 5265$({ target: 'Map', proto: true, real: true, forced: IS_PURE }, { 5266 getOrInsertComputed: function getOrInsertComputed(key, callbackfn) { 5267 var hasKey = has(this, key); 5268 aCallable(callbackfn); 5269 if (hasKey) return get(this, key); 5270 // CanonicalizeKeyedCollectionKey 5271 if (key === 0 && 1 / key === -Infinity) key = 0; 5272 var value = callbackfn(key); 5273 set(this, key, value); 5274 return value; 5275 } 5276}); 5277 5278 5279/***/ }, 5280 5281/***/ 5367 5282(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5283 5284 5285var $ = __webpack_require__(6518); 5286var MapHelpers = __webpack_require__(2248); 5287var IS_PURE = __webpack_require__(6395); 5288 5289var get = MapHelpers.get; 5290var has = MapHelpers.has; 5291var set = MapHelpers.set; 5292 5293// `Map.prototype.getOrInsert` method 5294// https://tc39.es/ecma262/#sec-map.prototype.getorinsert 5295$({ target: 'Map', proto: true, real: true, forced: IS_PURE }, { 5296 getOrInsert: function getOrInsert(key, value) { 5297 if (has(this, key)) return get(this, key); 5298 set(this, key, value); 5299 return value; 5300 } 5301}); 5302 5303 5304/***/ }, 5305 5306/***/ 3068 5307(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5308 5309 5310// based on Shewchuk's algorithm for exactly floating point addition 5311// adapted from https://github.com/tc39/proposal-math-sum/blob/3513d58323a1ae25560e8700aa5294500c6c9287/polyfill/polyfill.mjs 5312var $ = __webpack_require__(6518); 5313var uncurryThis = __webpack_require__(9504); 5314var iterate = __webpack_require__(2652); 5315 5316var $RangeError = RangeError; 5317var $TypeError = TypeError; 5318var $Infinity = Infinity; 5319var $NaN = NaN; 5320var abs = Math.abs; 5321var pow = Math.pow; 5322var push = uncurryThis([].push); 5323 5324var POW_2_1023 = pow(2, 1023); 5325var MAX_SAFE_INTEGER = pow(2, 53) - 1; // 2 ** 53 - 1 === 9007199254740991 5326var MAX_DOUBLE = Number.MAX_VALUE; // 2 ** 1024 - 2 ** (1023 - 52) === 1.79769313486231570815e+308 5327var MAX_ULP = pow(2, 971); // 2 ** (1023 - 52) === 1.99584030953471981166e+292 5328 5329var NOT_A_NUMBER = {}; 5330var MINUS_INFINITY = {}; 5331var PLUS_INFINITY = {}; 5332var MINUS_ZERO = {}; 5333var FINITE = {}; 5334 5335// prerequisite: abs(x) >= abs(y) 5336var twosum = function (x, y) { 5337 var hi = x + y; 5338 var lo = y - (hi - x); 5339 return { hi: hi, lo: lo }; 5340}; 5341 5342// `Math.sumPrecise` method 5343// https://tc39.es/ecma262/#sec-math.sumprecise 5344$({ target: 'Math', stat: true }, { 5345 // eslint-disable-next-line max-statements -- ok 5346 sumPrecise: function sumPrecise(items) { 5347 var numbers = []; 5348 var count = 0; 5349 var state = MINUS_ZERO; 5350 5351 iterate(items, function (n) { 5352 if (++count > MAX_SAFE_INTEGER) throw new $RangeError('Maximum allowed index exceeded'); 5353 if (typeof n != 'number') throw new $TypeError('Value is not a number'); 5354 if (state !== NOT_A_NUMBER) { 5355 // eslint-disable-next-line no-self-compare -- NaN check 5356 if (n !== n) state = NOT_A_NUMBER; 5357 else if (n === $Infinity) state = state === MINUS_INFINITY ? NOT_A_NUMBER : PLUS_INFINITY; 5358 else if (n === -$Infinity) state = state === PLUS_INFINITY ? NOT_A_NUMBER : MINUS_INFINITY; 5359 else if ((n !== 0 || (1 / n) === $Infinity) && (state === MINUS_ZERO || state === FINITE)) { 5360 state = FINITE; 5361 push(numbers, n); 5362 } 5363 } 5364 }); 5365 5366 switch (state) { 5367 case NOT_A_NUMBER: return $NaN; 5368 case MINUS_INFINITY: return -$Infinity; 5369 case PLUS_INFINITY: return $Infinity; 5370 case MINUS_ZERO: return -0; 5371 } 5372 5373 var partials = []; 5374 var overflow = 0; // conceptually 2 ** 1024 times this value; the final partial is biased by this amount 5375 var x, y, sum, hi, lo, tmp; 5376 5377 for (var i = 0; i < numbers.length; i++) { 5378 x = numbers[i]; 5379 var actuallyUsedPartials = 0; 5380 for (var j = 0; j < partials.length; j++) { 5381 y = partials[j]; 5382 if (abs(x) < abs(y)) { 5383 tmp = x; 5384 x = y; 5385 y = tmp; 5386 } 5387 sum = twosum(x, y); 5388 hi = sum.hi; 5389 lo = sum.lo; 5390 if (abs(hi) === $Infinity) { 5391 var sign = hi === $Infinity ? 1 : -1; 5392 overflow += sign; 5393 5394 x = (x - (sign * POW_2_1023)) - (sign * POW_2_1023); 5395 if (abs(x) < abs(y)) { 5396 tmp = x; 5397 x = y; 5398 y = tmp; 5399 } 5400 sum = twosum(x, y); 5401 hi = sum.hi; 5402 lo = sum.lo; 5403 } 5404 if (lo !== 0) partials[actuallyUsedPartials++] = lo; 5405 x = hi; 5406 } 5407 partials.length = actuallyUsedPartials; 5408 if (x !== 0) push(partials, x); 5409 } 5410 5411 // compute the exact sum of partials, stopping once we lose precision 5412 var n = partials.length - 1; 5413 hi = 0; 5414 lo = 0; 5415 5416 if (overflow !== 0) { 5417 var next = n >= 0 ? partials[n] : 0; 5418 n--; 5419 if (abs(overflow) > 1 || (overflow > 0 && next > 0) || (overflow < 0 && next < 0)) { 5420 return overflow > 0 ? $Infinity : -$Infinity; 5421 } 5422 // here we actually have to do the arithmetic 5423 // drop a factor of 2 so we can do it without overflow 5424 // assert(abs(overflow) === 1) 5425 sum = twosum(overflow * POW_2_1023, next / 2); 5426 hi = sum.hi; 5427 lo = sum.lo; 5428 lo *= 2; 5429 if (abs(2 * hi) === $Infinity) { 5430 // rounding to the maximum value 5431 if (hi > 0) { 5432 return (hi === POW_2_1023 && lo === -(MAX_ULP / 2) && n >= 0 && partials[n] < 0) ? MAX_DOUBLE : $Infinity; 5433 } return (hi === -POW_2_1023 && lo === (MAX_ULP / 2) && n >= 0 && partials[n] > 0) ? -MAX_DOUBLE : -$Infinity; 5434 } 5435 5436 if (lo !== 0) { 5437 partials[++n] = lo; 5438 lo = 0; 5439 } 5440 5441 hi *= 2; 5442 } 5443 5444 while (n >= 0) { 5445 sum = twosum(hi, partials[n--]); 5446 hi = sum.hi; 5447 lo = sum.lo; 5448 if (lo !== 0) break; 5449 } 5450 5451 if (n >= 0 && ((lo < 0 && partials[n] < 0) || (lo > 0 && partials[n] > 0))) { 5452 y = lo * 2; 5453 x = hi + y; 5454 if (y === x - hi) hi = x; 5455 } 5456 5457 return hi; 5458 } 5459}); 5460 5461 5462/***/ }, 5463 5464/***/ 1689 5465(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5466 5467 5468var $ = __webpack_require__(6518); 5469var globalThis = __webpack_require__(4576); 5470var apply = __webpack_require__(8745); 5471var slice = __webpack_require__(7680); 5472var promiseResolve = __webpack_require__(3438); 5473var newPromiseCapabilityModule = __webpack_require__(6043); 5474var aCallable = __webpack_require__(9306); 5475var perform = __webpack_require__(1103); 5476var fails = __webpack_require__(9039); 5477 5478var Promise = globalThis.Promise; 5479 5480var ACCEPT_ARGUMENTS = false; 5481var FORCED = !Promise || !Promise['try'] || fails(function () { 5482 var p = Promise.resolve(); 5483 return Promise['try'](function (argument) { 5484 // avoiding the use of polyfills of the previous iteration of this proposal 5485 // that does not accept arguments of the callback 5486 ACCEPT_ARGUMENTS = argument === 8; 5487 return p; 5488 // it should use `PromiseResolve` 5489 // https://github.com/tc39/ecma262/pull/3883 5490 }, 8) !== p; 5491}) || !ACCEPT_ARGUMENTS; 5492 5493// `Promise.try` method 5494// https://tc39.es/ecma262/#sec-promise.try 5495$({ target: 'Promise', stat: true, forced: FORCED }, { 5496 'try': function (callbackfn /* , ...args */) { 5497 var args = arguments.length > 1 ? slice(arguments, 1) : []; 5498 var result = perform(function () { 5499 return apply(aCallable(callbackfn), undefined, args); 5500 }); 5501 if (!result.error) return promiseResolve(this, result.value); 5502 var promiseCapability = newPromiseCapabilityModule.f(this); 5503 var reject = promiseCapability.reject; 5504 reject(result.value); 5505 return promiseCapability.promise; 5506 } 5507}); 5508 5509 5510/***/ }, 5511 5512/***/ 7642 5513(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5514 5515 5516var $ = __webpack_require__(6518); 5517var difference = __webpack_require__(3440); 5518var fails = __webpack_require__(9039); 5519var setMethodAcceptSetLike = __webpack_require__(4916); 5520 5521var SET_LIKE_INCORRECT_BEHAVIOR = !setMethodAcceptSetLike('difference', function (result) { 5522 return result.size === 0; 5523}); 5524 5525var FORCED = SET_LIKE_INCORRECT_BEHAVIOR || fails(function () { 5526 // https://bugs.webkit.org/show_bug.cgi?id=288595 5527 var setLike = { 5528 size: 1, 5529 has: function () { return true; }, 5530 keys: function () { 5531 var index = 0; 5532 return { 5533 next: function () { 5534 var done = index++ > 1; 5535 if (baseSet.has(1)) baseSet.clear(); 5536 return { done: done, value: 2 }; 5537 } 5538 }; 5539 } 5540 }; 5541 // eslint-disable-next-line es/no-set -- testing 5542 var baseSet = new Set([1, 2, 3, 4]); 5543 // eslint-disable-next-line es/no-set-prototype-difference -- testing 5544 return baseSet.difference(setLike).size !== 3; 5545}); 5546 5547// `Set.prototype.difference` method 5548// https://tc39.es/ecma262/#sec-set.prototype.difference 5549$({ target: 'Set', proto: true, real: true, forced: FORCED }, { 5550 difference: difference 5551}); 5552 5553 5554/***/ }, 5555 5556/***/ 8004 5557(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5558 5559 5560var $ = __webpack_require__(6518); 5561var fails = __webpack_require__(9039); 5562var intersection = __webpack_require__(8750); 5563var setMethodAcceptSetLike = __webpack_require__(4916); 5564 5565var INCORRECT = !setMethodAcceptSetLike('intersection', function (result) { 5566 return result.size === 2 && result.has(1) && result.has(2); 5567}) || fails(function () { 5568 // eslint-disable-next-line es/no-array-from, es/no-set, es/no-set-prototype-intersection -- testing 5569 return String(Array.from(new Set([1, 2, 3]).intersection(new Set([3, 2])))) !== '3,2'; 5570}); 5571 5572// `Set.prototype.intersection` method 5573// https://tc39.es/ecma262/#sec-set.prototype.intersection 5574$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { 5575 intersection: intersection 5576}); 5577 5578 5579/***/ }, 5580 5581/***/ 3853 5582(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5583 5584 5585var $ = __webpack_require__(6518); 5586var isDisjointFrom = __webpack_require__(4449); 5587var setMethodAcceptSetLike = __webpack_require__(4916); 5588 5589var INCORRECT = !setMethodAcceptSetLike('isDisjointFrom', function (result) { 5590 return !result; 5591}); 5592 5593// `Set.prototype.isDisjointFrom` method 5594// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom 5595$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { 5596 isDisjointFrom: isDisjointFrom 5597}); 5598 5599 5600/***/ }, 5601 5602/***/ 5876 5603(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5604 5605 5606var $ = __webpack_require__(6518); 5607var isSubsetOf = __webpack_require__(3838); 5608var setMethodAcceptSetLike = __webpack_require__(4916); 5609 5610var INCORRECT = !setMethodAcceptSetLike('isSubsetOf', function (result) { 5611 return result; 5612}); 5613 5614// `Set.prototype.isSubsetOf` method 5615// https://tc39.es/ecma262/#sec-set.prototype.issubsetof 5616$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { 5617 isSubsetOf: isSubsetOf 5618}); 5619 5620 5621/***/ }, 5622 5623/***/ 2475 5624(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5625 5626 5627var $ = __webpack_require__(6518); 5628var isSupersetOf = __webpack_require__(8527); 5629var setMethodAcceptSetLike = __webpack_require__(4916); 5630 5631var INCORRECT = !setMethodAcceptSetLike('isSupersetOf', function (result) { 5632 return !result; 5633}); 5634 5635// `Set.prototype.isSupersetOf` method 5636// https://tc39.es/ecma262/#sec-set.prototype.issupersetof 5637$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { 5638 isSupersetOf: isSupersetOf 5639}); 5640 5641 5642/***/ }, 5643 5644/***/ 5024 5645(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5646 5647 5648var $ = __webpack_require__(6518); 5649var symmetricDifference = __webpack_require__(3650); 5650var setMethodGetKeysBeforeCloning = __webpack_require__(9835); 5651var setMethodAcceptSetLike = __webpack_require__(4916); 5652 5653var FORCED = !setMethodAcceptSetLike('symmetricDifference') || !setMethodGetKeysBeforeCloning('symmetricDifference'); 5654 5655// `Set.prototype.symmetricDifference` method 5656// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference 5657$({ target: 'Set', proto: true, real: true, forced: FORCED }, { 5658 symmetricDifference: symmetricDifference 5659}); 5660 5661 5662/***/ }, 5663 5664/***/ 1698 5665(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5666 5667 5668var $ = __webpack_require__(6518); 5669var union = __webpack_require__(4204); 5670var setMethodGetKeysBeforeCloning = __webpack_require__(9835); 5671var setMethodAcceptSetLike = __webpack_require__(4916); 5672 5673var FORCED = !setMethodAcceptSetLike('union') || !setMethodGetKeysBeforeCloning('union'); 5674 5675// `Set.prototype.union` method 5676// https://tc39.es/ecma262/#sec-set.prototype.union 5677$({ target: 'Set', proto: true, real: true, forced: FORCED }, { 5678 union: union 5679}); 5680 5681 5682/***/ }, 5683 5684/***/ 9577 5685(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5686 5687 5688var ArrayBufferViewCore = __webpack_require__(4644); 5689var isBigIntArray = __webpack_require__(1108); 5690var lengthOfArrayLike = __webpack_require__(6198); 5691var toIntegerOrInfinity = __webpack_require__(1291); 5692var toBigInt = __webpack_require__(5854); 5693 5694var aTypedArray = ArrayBufferViewCore.aTypedArray; 5695var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; 5696var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; 5697 5698var $RangeError = RangeError; 5699 5700var PROPER_ORDER = function () { 5701 try { 5702 // eslint-disable-next-line no-throw-literal, es/no-typed-arrays, es/no-array-prototype-with -- required for testing 5703 new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } }); 5704 } catch (error) { 5705 // some early implementations, like WebKit, does not follow the final semantic 5706 // https://github.com/tc39/proposal-change-array-by-copy/pull/86 5707 return error === 8; 5708 } 5709}(); 5710 5711// Bug in WebKit. It should truncate a negative fractional index to zero, but instead throws an error 5712var THROW_ON_NEGATIVE_FRACTIONAL_INDEX = PROPER_ORDER && function () { 5713 try { 5714 // eslint-disable-next-line es/no-typed-arrays, es/no-array-prototype-with -- required for testing 5715 new Int8Array(1)['with'](-0.5, 1); 5716 } catch (error) { 5717 return true; 5718 } 5719}(); 5720 5721// `%TypedArray%.prototype.with` method 5722// https://tc39.es/ecma262/#sec-%typedarray%.prototype.with 5723exportTypedArrayMethod('with', { 'with': function (index, value) { 5724 var O = aTypedArray(this); 5725 var len = lengthOfArrayLike(O); 5726 var relativeIndex = toIntegerOrInfinity(index); 5727 var actualIndex = relativeIndex < 0 ? len + relativeIndex : relativeIndex; 5728 var numericValue = isBigIntArray(O) ? toBigInt(value) : +value; 5729 if (actualIndex >= len || actualIndex < 0) throw new $RangeError('Incorrect index'); 5730 var A = new (getTypedArrayConstructor(O))(len); 5731 var k = 0; 5732 for (; k < len; k++) A[k] = k === actualIndex ? numericValue : O[k]; 5733 return A; 5734} }['with'], !PROPER_ORDER || THROW_ON_NEGATIVE_FRACTIONAL_INDEX); 5735 5736 5737/***/ }, 5738 5739/***/ 5213 5740(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5741 5742 5743var $ = __webpack_require__(6518); 5744var globalThis = __webpack_require__(4576); 5745var arrayFromConstructorAndList = __webpack_require__(5370); 5746var $fromBase64 = __webpack_require__(9143); 5747 5748var Uint8Array = globalThis.Uint8Array; 5749 5750var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.fromBase64 || !function () { 5751 // Webkit not throw an error on odd length string 5752 try { 5753 Uint8Array.fromBase64('a'); 5754 return; 5755 } catch (error) { /* empty */ } 5756 try { 5757 Uint8Array.fromBase64('', null); 5758 } catch (error) { 5759 return true; 5760 } 5761}(); 5762 5763// `Uint8Array.fromBase64` method 5764// https://tc39.es/ecma262/#sec-uint8array.frombase64 5765if (Uint8Array) $({ target: 'Uint8Array', stat: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { 5766 fromBase64: function fromBase64(string /* , options */) { 5767 var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, null, 0x1FFFFFFFFFFFFF); 5768 return arrayFromConstructorAndList(Uint8Array, result.bytes); 5769 } 5770}); 5771 5772 5773/***/ }, 5774 5775/***/ 6632 5776(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5777 5778 5779var $ = __webpack_require__(6518); 5780var globalThis = __webpack_require__(4576); 5781var $fromBase64 = __webpack_require__(9143); 5782var anUint8Array = __webpack_require__(4154); 5783 5784var Uint8Array = globalThis.Uint8Array; 5785 5786var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.setFromBase64 || !function () { 5787 var target = new Uint8Array([255, 255, 255, 255, 255]); 5788 try { 5789 target.setFromBase64('', null); 5790 return; 5791 } catch (error) { /* empty */ } 5792 // Webkit not throw an error on odd length string 5793 try { 5794 target.setFromBase64('a'); 5795 return; 5796 } catch (error) { /* empty */ } 5797 try { 5798 target.setFromBase64('MjYyZg==='); 5799 } catch (error) { 5800 return target[0] === 50 && target[1] === 54 && target[2] === 50 && target[3] === 255 && target[4] === 255; 5801 } 5802}(); 5803 5804// `Uint8Array.prototype.setFromBase64` method 5805// https://tc39.es/ecma262/#sec-uint8array.prototype.setfrombase64 5806if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { 5807 setFromBase64: function setFromBase64(string /* , options */) { 5808 anUint8Array(this); 5809 5810 var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, this, this.length); 5811 5812 return { read: result.read, written: result.written }; 5813 } 5814}); 5815 5816 5817/***/ }, 5818 5819/***/ 4226 5820(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5821 5822 5823var $ = __webpack_require__(6518); 5824var globalThis = __webpack_require__(4576); 5825var aString = __webpack_require__(3463); 5826var anUint8Array = __webpack_require__(4154); 5827var notDetached = __webpack_require__(5169); 5828var $fromHex = __webpack_require__(2303); 5829 5830// Should not throw an error on length-tracking views over ResizableArrayBuffer 5831// https://issues.chromium.org/issues/454630441 5832function throwsOnLengthTrackingView() { 5833 try { 5834 // eslint-disable-next-line es/no-resizable-and-growable-arraybuffers -- required for testing 5835 var rab = new ArrayBuffer(16, { maxByteLength: 1024 }); 5836 // eslint-disable-next-line es/no-uint8array-prototype-setfromhex, es/no-typed-arrays -- required for testing 5837 new Uint8Array(rab).setFromHex('cafed00d'); 5838 } catch (error) { 5839 return true; 5840 } 5841} 5842 5843// `Uint8Array.prototype.setFromHex` method 5844// https://tc39.es/ecma262/#sec-uint8array.prototype.setfromhex 5845if (globalThis.Uint8Array) $({ target: 'Uint8Array', proto: true, forced: throwsOnLengthTrackingView() }, { 5846 setFromHex: function setFromHex(string) { 5847 anUint8Array(this); 5848 aString(string); 5849 notDetached(this.buffer); 5850 var read = $fromHex(string, this).read; 5851 return { read: read, written: read / 2 }; 5852 } 5853}); 5854 5855 5856/***/ }, 5857 5858/***/ 9486 5859(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5860 5861 5862/* eslint-disable no-useless-assignment -- false positive for [index++] syntax */ 5863var $ = __webpack_require__(6518); 5864var globalThis = __webpack_require__(4576); 5865var uncurryThis = __webpack_require__(9504); 5866var anObjectOrUndefined = __webpack_require__(3972); 5867var anUint8Array = __webpack_require__(4154); 5868var notDetached = __webpack_require__(5169); 5869var base64Map = __webpack_require__(2804); 5870var getAlphabetOption = __webpack_require__(944); 5871 5872var base64Alphabet = base64Map.i2c; 5873var base64UrlAlphabet = base64Map.i2cUrl; 5874var $floor = Math.floor; 5875var $ceil = Math.ceil; 5876 5877var charAt = uncurryThis(''.charAt); 5878 5879var Uint8Array = globalThis.Uint8Array; 5880var $Array = globalThis.Array; 5881var join = uncurryThis([].join); 5882 5883var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.toBase64 || !function () { 5884 try { 5885 var target = new Uint8Array(); 5886 target.toBase64(null); 5887 } catch (error) { 5888 return true; 5889 } 5890}(); 5891 5892// `Uint8Array.prototype.toBase64` method 5893// https://tc39.es/ecma262/#sec-uint8array.prototype.tobase64 5894if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { 5895 toBase64: function toBase64(/* options */) { 5896 var array = anUint8Array(this); 5897 var options = arguments.length ? anObjectOrUndefined(arguments[0]) : undefined; 5898 var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; 5899 var omitPadding = !!options && !!options.omitPadding; 5900 notDetached(this.buffer); 5901 5902 var i = 0; 5903 var length = array.length; 5904 var result = $Array(omitPadding ? $floor(length / 3) * 4 + (length % 3 ? length % 3 + 1 : 0) : $ceil(length / 3) * 4); 5905 var written = 0; 5906 var triplet; 5907 5908 var at = function (shift) { 5909 return charAt(alphabet, (triplet >> (6 * shift)) & 63); 5910 }; 5911 5912 for (; i + 2 < length; i += 3) { 5913 triplet = (array[i] << 16) + (array[i + 1] << 8) + array[i + 2]; 5914 result[written++] = at(3); 5915 result[written++] = at(2); 5916 result[written++] = at(1); 5917 result[written++] = at(0); 5918 } 5919 if (i + 2 === length) { 5920 triplet = (array[i] << 16) + (array[i + 1] << 8); 5921 result[written++] = at(3); 5922 result[written++] = at(2); 5923 result[written++] = at(1); 5924 if (!omitPadding) result[written++] = '='; 5925 } else if (i + 1 === length) { 5926 triplet = array[i] << 16; 5927 result[written++] = at(3); 5928 result[written++] = at(2); 5929 if (!omitPadding) { 5930 result[written++] = '='; 5931 result[written++] = '='; 5932 } 5933 } 5934 5935 return join(result, ''); 5936 } 5937}); 5938 5939 5940/***/ }, 5941 5942/***/ 456 5943(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5944 5945 5946var $ = __webpack_require__(6518); 5947var globalThis = __webpack_require__(4576); 5948var uncurryThis = __webpack_require__(9504); 5949var anUint8Array = __webpack_require__(4154); 5950var notDetached = __webpack_require__(5169); 5951 5952var numberToString = uncurryThis(1.1.toString); 5953var join = uncurryThis([].join); 5954var $Array = Array; 5955 5956var Uint8Array = globalThis.Uint8Array; 5957 5958var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.toHex || !(function () { 5959 try { 5960 var target = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]); 5961 return target.toHex() === 'ffffffffffffffff'; 5962 } catch (error) { 5963 return false; 5964 } 5965})(); 5966 5967// `Uint8Array.prototype.toHex` method 5968// https://tc39.es/ecma262/#sec-uint8array.prototype.tohex 5969if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { 5970 toHex: function toHex() { 5971 anUint8Array(this); 5972 notDetached(this.buffer); 5973 var result = $Array(this.length); 5974 for (var i = 0, length = this.length; i < length; i++) { 5975 var hex = numberToString(this[i], 16); 5976 result[i] = hex.length === 1 ? '0' + hex : hex; 5977 } 5978 return join(result, ''); 5979 } 5980}); 5981 5982 5983/***/ }, 5984 5985/***/ 9452 5986(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 5987 5988 5989var $ = __webpack_require__(6518); 5990var aCallable = __webpack_require__(9306); 5991var aWeakMap = __webpack_require__(6557); 5992var aWeakKey = __webpack_require__(4328); 5993var WeakMapHelpers = __webpack_require__(4995); 5994var IS_PURE = __webpack_require__(6395); 5995 5996var get = WeakMapHelpers.get; 5997var has = WeakMapHelpers.has; 5998var set = WeakMapHelpers.set; 5999 6000var FORCED = IS_PURE || !function () { 6001 try { 6002 // eslint-disable-next-line es/no-weak-map, no-throw-literal -- testing 6003 if (WeakMap.prototype.getOrInsertComputed) new WeakMap().getOrInsertComputed(1, function () { throw 1; }); 6004 } catch (error) { 6005 // FF144 Nightly - Beta 3 bug 6006 // https://bugzilla.mozilla.org/show_bug.cgi?id=1988369 6007 return error instanceof TypeError; 6008 } 6009}(); 6010 6011// `WeakMap.prototype.getOrInsertComputed` method 6012// https://tc39.es/ecma262/#sec-weakmap.prototype.getorinsertcomputed 6013$({ target: 'WeakMap', proto: true, real: true, forced: FORCED }, { 6014 getOrInsertComputed: function getOrInsertComputed(key, callbackfn) { 6015 if (!IS_PURE) aWeakMap(this); 6016 aWeakKey(key); 6017 aCallable(callbackfn); 6018 if (has(this, key)) return get(this, key); 6019 var value = callbackfn(key); 6020 set(this, key, value); 6021 return value; 6022 } 6023}); 6024 6025 6026/***/ }, 6027 6028/***/ 8454 6029(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 6030 6031 6032var $ = __webpack_require__(6518); 6033var WeakMapHelpers = __webpack_require__(4995); 6034var IS_PURE = __webpack_require__(6395); 6035 6036var get = WeakMapHelpers.get; 6037var has = WeakMapHelpers.has; 6038var set = WeakMapHelpers.set; 6039 6040// `WeakMap.prototype.getOrInsert` method 6041// https://tc39.es/ecma262/#sec-weakmap.prototype.getorinsert 6042$({ target: 'WeakMap', proto: true, real: true, forced: IS_PURE }, { 6043 getOrInsert: function getOrInsert(key, value) { 6044 if (has(this, key)) return get(this, key); 6045 set(this, key, value); 6046 return value; 6047 } 6048}); 6049 6050 6051/***/ }, 6052 6053/***/ 4979 6054(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 6055 6056 6057var $ = __webpack_require__(6518); 6058var globalThis = __webpack_require__(4576); 6059var getBuiltIn = __webpack_require__(7751); 6060var createPropertyDescriptor = __webpack_require__(6980); 6061var defineProperty = (__webpack_require__(4913).f); 6062var hasOwn = __webpack_require__(9297); 6063var anInstance = __webpack_require__(679); 6064var inheritIfRequired = __webpack_require__(3167); 6065var normalizeStringArgument = __webpack_require__(2603); 6066var DOMExceptionConstants = __webpack_require__(5002); 6067var clearErrorStack = __webpack_require__(6193
vendor: 2,533 bytes, lines 6067-6126
6067); 6068var DESCRIPTORS = __webpack_require__(3724); 6069var IS_PURE = __webpack_require__(6395); 6070 6071var DOM_EXCEPTION = 'DOMException'; 6072var Error = getBuiltIn('Error'); 6073var NativeDOMException = getBuiltIn(DOM_EXCEPTION); 6074 6075var $DOMException = function DOMException() { 6076 anInstance(this, DOMExceptionPrototype); 6077 var argumentsLength = arguments.length; 6078 var message = normalizeStringArgument(argumentsLength < 1 ? undefined : arguments[0]); 6079 var name = normalizeStringArgument(argumentsLength < 2 ? undefined : arguments[1], 'Error'); 6080 var that = new NativeDOMException(message, name); 6081 var error = new Error(message); 6082 error.name = DOM_EXCEPTION; 6083 defineProperty(that, 'stack', createPropertyDescriptor(1, clearErrorStack(error.stack, 1))); 6084 inheritIfRequired(that, this, $DOMException); 6085 return that; 6086}; 6087 6088var DOMExceptionPrototype = $DOMException.prototype = NativeDOMException.prototype; 6089 6090var ERROR_HAS_STACK = 'stack' in new Error(DOM_EXCEPTION); 6091var DOM_EXCEPTION_HAS_STACK = 'stack' in new NativeDOMException(1, 2); 6092 6093// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe 6094var descriptor = NativeDOMException && DESCRIPTORS && Object.getOwnPropertyDescriptor(globalThis, DOM_EXCEPTION); 6095 6096// Bun ~ 0.1.1 DOMException have incorrect descriptor and we can't redefine it 6097// https://github.com/Jarred-Sumner/bun/issues/399 6098var BUGGY_DESCRIPTOR = !!descriptor && !(descriptor.writable && descriptor.configurable); 6099 6100var FORCED_CONSTRUCTOR = ERROR_HAS_STACK && !BUGGY_DESCRIPTOR && !DOM_EXCEPTION_HAS_STACK; 6101 6102// `DOMException` constructor patch for `.stack` where it's required 6103// https://webidl.spec.whatwg.org/#es-DOMException-specialness 6104$({ global: true, constructor: true, forced: IS_PURE || FORCED_CONSTRUCTOR }, { // TODO: fix export logic 6105 DOMException: FORCED_CONSTRUCTOR ? $DOMException : NativeDOMException 6106}); 6107 6108var PolyfilledDOMException = getBuiltIn(DOM_EXCEPTION); 6109var PolyfilledDOMExceptionPrototype = PolyfilledDOMException.prototype; 6110 6111if (PolyfilledDOMExceptionPrototype.constructor !== PolyfilledDOMException) { 6112 if (!IS_PURE) { 6113 defineProperty(PolyfilledDOMExceptionPrototype, 'constructor', createPropertyDescriptor(1, PolyfilledDOMException)); 6114 } 6115 6116 for (var key in DOMExceptionConstants) if (hasOwn(DOMExceptionConstants, key)) { 6117 var constant = DOMExceptionConstants[key]; 6118 var constantName = constant.s; 6119 if (!hasOwn(PolyfilledDOMException, constantName)) { 6120 defineProperty(PolyfilledDOMException, constantName, createPropertyDescriptor(6, constant.c)); 6121 } 6122 } 6123} 6124 6125 6126/***/ }
6126, 6127 6128/***/ 5781 6129(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 6130 6131 6132var $ = __webpack_require__(6518); 6133var getBuiltIn = __webpack_require__(7751); 6134var validateArgumentsLength = __webpack_require__(2812); 6135var toString = __webpack_require__(655); 6136var USE_NATIVE_URL = __webpack_require__(7416); 6137 6138var URL = getBuiltIn('URL'); 6139 6140// `URL.parse` method 6141// https://url.spec.whatwg.org/#dom-url-parse 6142$({ target: 'URL', stat: true, forced: !USE_NATIVE_URL }, { 6143 parse: function parse(url) { 6144 var length = validateArgumentsLength(arguments.length, 1); 6145 var urlString = toString(url); 6146 var base = length < 2 || arguments[1] === undefined ? undefined : toString(arguments[1]); 6147 try { 6148 return new URL(urlString, base); 6149 } catch (error) { 6150 return null; 6151 } 6152 } 6153}); 6154 6155 6156/***/ } 6157 6158/******/ }); 6159/************************************************************************/ 6160/******/ // The module cache 6161/******/ const __webpack_module_cache__ = {}; 6162/******/ 6163/******/ // The require function 6164/******/ function __webpack_require__(moduleId) { 6165/******/ // Check if module is in cache 6166/******/ const cachedModule = __webpack_module_cache__[moduleId]; 6167/******/ if (cachedModule !== undefined) { 6168/******/ return cachedModule.exports; 6169/******/ } 6170/******/ // Create a new module (and put it into the cache) 6171/******/ const module = __webpack_module_cache__[moduleId] = { 6172/******/ // no module.id needed 6173/******/ // no module.loaded needed 6174/******/ exports: {} 6175/******/ }; 6176/******/ 6177/******/ // Execute the module function 6178/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 6179/******/ 6180/******/ // Return the exports of the module 6181/******/ return module.exports; 6182/******/ } 6183/******/ 6184/************************************************************************/ 6185/******/ /* webpack/runtime/define property getters */ 6186/******/ (() => { 6187/******/ // define getter/value functions for harmony exports 6188/******/ __webpack_require__.d = (exports, definition) => { 6189/******/ if(Array.isArray(definition)) { 6190/******/ var i = 0; 6191/******/ while(i < definition.length) { 6192/******/ var key = definition[i++]; 6193/******/ var binding = definition[i++]; 6194/******/ if(!__webpack_require__.o(exports, key)) { 6195/******/ if(binding === 0) { 6196/******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] }); 6197/******/ } else { 6198/******/ Object.defineProperty(exports, key, { enumerable: true, get: binding }); 6199/******/ } 6200/******/ } else if(binding === 0) { i++; } 6201/******/ } 6202/******/ } else { 6203/******/ for(var key in definition) { 6204/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 6205/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 6206/******/ } 6207/******/ } 6208/******/ } 6209/******/ }; 6210/******/ })(); 6211/******/ 6212/******/ /* webpack/runtime/hasOwnProperty shorthand */ 6213/******/ (() => { 6214/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 6215/******/ })(); 6216/******/ 6217/************************************************************************/ 6218 6219// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.includes.js 6220var es_array_includes = __webpack_require__(4423); 6221// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js 6222var es_array_push = __webpack_require__(4114); 6223// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.constructor.js 6224var es_iterator_constructor = __webpack_require__(8111); 6225// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.filter.js 6226var es_iterator_filter = __webpack_require__(2489); 6227// EXTERNAL MODULE: ./node_modules/core-js/modules/es.map.get-or-insert.js 6228var es_map_get_or_insert = __webpack_require__(5367); 6229// EXTERNAL MODULE: ./node_modules/core-js/modules/es.map.get-or-insert-computed.js 6230var es_map_get_or_insert_computed = __webpack_require__(2731); 6231// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.difference.v2.js 6232var es_set_difference_v2 = __webpack_require__(7642); 6233// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.intersection.v2.js 6234var es_set_intersection_v2 = __webpack_require__(8004); 6235// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.is-disjoint-from.v2.js 6236var es_set_is_disjoint_from_v2 = __webpack_require__(3853); 6237// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.is-subset-of.v2.js 6238var es_set_is_subset_of_v2 = __webpack_require__(5876); 6239// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.is-superset-of.v2.js 6240var es_set_is_superset_of_v2 = __webpack_require__(2475); 6241// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.symmetric-difference.v2.js 6242var es_set_symmetric_difference_v2 = __webpack_require__(5024); 6243// EXTERNAL MODULE: ./node_modules/core-js/modules/es.set.union.v2.js 6244var es_set_union_v2 = __webpack_require__(1698); 6245// EXTERNAL MODULE: ./node_modules/core-js/modules/es.typed-array.with.js 6246var es_typed_array_with = __webpack_require__(9577); 6247// EXTERNAL MODULE: ./node_modules/core-js/modules/es.uint8-array.set-from-base64.js 6248var es_uint8_array_set_from_base64 = __webpack_require__(6632); 6249// EXTERNAL MODULE: ./node_modules/core-js/modules/es.uint8-array.set-from-hex.js 6250var es_uint8_array_set_from_hex = __webpack_require__(4226); 6251// EXTERNAL MODULE: ./node_modules/core-js/modules/es.uint8-array.to-base64.js 6252var es_uint8_array_to_base64 = __webpack_require__(9486); 6253// EXTERNAL MODULE: ./node_modules/core-js/modules/es.uint8-array.to-hex.js 6254var es_uint8_array_to_hex = __webpack_require__(456); 6255// EXTERNAL MODULE: ./node_modules/core-js/modules/web.url.parse.js 6256var web_url_parse = __webpack_require__(5781); 6257;// ./src/shared/util.js 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275
vendor: 20,869 bytes, lines 6276-7045
6276 6277const isNodeJS = typeof process === "object" && process + "" === "[object process]" && !process.versions.nw && !(process.versions.electron && process.type && process.type !== "browser"); 6278const BBOX_INIT = [Infinity, Infinity, -Infinity, -Infinity]; 6279const F32_BBOX_INIT = new Float32Array(BBOX_INIT); 6280const FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0]; 6281const LINE_FACTOR = 1.35; 6282const LINE_DESCENT_FACTOR = 0.35; 6283const BASELINE_FACTOR = (/* unused pure expression or super */ null && (LINE_DESCENT_FACTOR / LINE_FACTOR)); 6284const SVG_NS = "http://www.w3.org/2000/svg"; 6285const RenderingIntentFlag = { 6286 ANY: 0x01, 6287 DISPLAY: 0x02, 6288 PRINT: 0x04, 6289 SAVE: 0x08, 6290 ANNOTATIONS_FORMS: 0x10, 6291 ANNOTATIONS_STORAGE: 0x20, 6292 ANNOTATIONS_DISABLE: 0x40, 6293 IS_EDITING: 0x80, 6294 OPLIST: 0x100 6295}; 6296const AnnotationMode = { 6297 DISABLE: 0, 6298 ENABLE: 1, 6299 ENABLE_FORMS: 2, 6300 ENABLE_STORAGE: 3 6301}; 6302const AnnotationPrefix = "pdfjs_internal_id_"; 6303const AnnotationEditorPrefix = "pdfjs_internal_editor_"; 6304const AnnotationEditorType = { 6305 DISABLE: -1, 6306 NONE: 0, 6307 FREETEXT: 3, 6308 HIGHLIGHT: 9, 6309 STAMP: 13, 6310 INK: 15, 6311 POPUP: 16, 6312 SIGNATURE: 101, 6313 COMMENT: 102 6314}; 6315const AnnotationEditorParamsType = { 6316 RESIZE: 1, 6317 CREATE: 2, 6318 FREETEXT_SIZE: 11, 6319 FREETEXT_COLOR: 12, 6320 FREETEXT_OPACITY: 13, 6321 INK_COLOR: 21, 6322 INK_THICKNESS: 22, 6323 INK_OPACITY: 23, 6324 INK_COLOR_AND_OPACITY: 24, 6325 HIGHLIGHT_COLOR: 31, 6326 HIGHLIGHT_THICKNESS: 32, 6327 HIGHLIGHT_FREE: 33, 6328 HIGHLIGHT_SHOW_ALL: 34, 6329 DRAW_STEP: 41 6330}; 6331const PermissionFlag = { 6332 PRINT: 0x04, 6333 MODIFY_CONTENTS: 0x08, 6334 COPY: 0x10, 6335 MODIFY_ANNOTATIONS: 0x20, 6336 FILL_INTERACTIVE_FORMS: 0x100, 6337 COPY_FOR_ACCESSIBILITY: 0x200, 6338 ASSEMBLE: 0x400, 6339 PRINT_HIGH_QUALITY: 0x800 6340}; 6341const MeshFigureType = (/* unused pure expression or super */ null && ({ 6342 TRIANGLES: 1, 6343 LATTICE: 2, 6344 PATCH: 3 6345})); 6346const TextRenderingMode = { 6347 FILL: 0, 6348 STROKE: 1, 6349 FILL_STROKE: 2, 6350 INVISIBLE: 3, 6351 FILL_ADD_TO_PATH: 4, 6352 STROKE_ADD_TO_PATH: 5, 6353 FILL_STROKE_ADD_TO_PATH: 6, 6354 ADD_TO_PATH: 7, 6355 FILL_STROKE_MASK: 3, 6356 ADD_TO_PATH_FLAG: 4 6357}; 6358const ImageKind = { 6359 GRAYSCALE_1BPP: 1, 6360 RGB_24BPP: 2, 6361 RGBA_32BPP: 3 6362}; 6363const AnnotationType = { 6364 TEXT: 1, 6365 LINK: 2, 6366 FREETEXT: 3, 6367 LINE: 4, 6368 SQUARE: 5, 6369 CIRCLE: 6, 6370 POLYGON: 7, 6371 POLYLINE: 8, 6372 HIGHLIGHT: 9, 6373 UNDERLINE: 10, 6374 SQUIGGLY: 11, 6375 STRIKEOUT: 12, 6376 STAMP: 13, 6377 CARET: 14, 6378 INK: 15, 6379 POPUP: 16, 6380 FILEATTACHMENT: 17, 6381 SOUND: 18, 6382 MOVIE: 19, 6383 WIDGET: 20, 6384 SCREEN: 21, 6385 PRINTERMARK: 22, 6386 TRAPNET: 23, 6387 WATERMARK: 24, 6388 THREED: 25, 6389 REDACT: 26, 6390 RICHMEDIA: 27 6391}; 6392const AnnotationReplyType = (/* unused pure expression or super */ null && ({ 6393 GROUP: "Group", 6394 REPLY: "R" 6395})); 6396const AnnotationRenditionOperation = (/* unused pure expression or super */ null && ({ 6397 PLAY_OR_RESUME: 0, 6398 STOP: 1, 6399 PAUSE: 2, 6400 RESUME: 3, 6401 PLAY: 4 6402})); 6403const AnnotationFlag = (/* unused pure expression or super */ null && ({ 6404 INVISIBLE: 0x01, 6405 HIDDEN: 0x02, 6406 PRINT: 0x04, 6407 NOZOOM: 0x08, 6408 NOROTATE: 0x10, 6409 NOVIEW: 0x20, 6410 READONLY: 0x40, 6411 LOCKED: 0x80, 6412 TOGGLENOVIEW: 0x100, 6413 LOCKEDCONTENTS: 0x200 6414})); 6415const AnnotationFieldFlag = (/* unused pure expression or super */ null && ({ 6416 READONLY: 0x0000001, 6417 REQUIRED: 0x0000002, 6418 NOEXPORT: 0x0000004, 6419 MULTILINE: 0x0001000, 6420 PASSWORD: 0x0002000, 6421 NOTOGGLETOOFF: 0x0004000, 6422 RADIO: 0x0008000, 6423 PUSHBUTTON: 0x0010000, 6424 COMBO: 0x0020000, 6425 EDIT: 0x0040000, 6426 SORT: 0x0080000, 6427 FILESELECT: 0x0100000, 6428 MULTISELECT: 0x0200000, 6429 DONOTSPELLCHECK: 0x0400000, 6430 DONOTSCROLL: 0x0800000, 6431 COMB: 0x1000000, 6432 RICHTEXT: 0x2000000, 6433 RADIOSINUNISON: 0x2000000, 6434 COMMITONSELCHANGE: 0x4000000 6435})); 6436const AnnotationBorderStyleType = { 6437 SOLID: 1, 6438 DASHED: 2, 6439 BEVELED: 3, 6440 INSET: 4, 6441 UNDERLINE: 5 6442}; 6443const AnnotationActionEventType = (/* unused pure expression or super */ null && ({ 6444 E: "Mouse Enter", 6445 X: "Mouse Exit", 6446 D: "Mouse Down", 6447 U: "Mouse Up", 6448 Fo: "Focus", 6449 Bl: "Blur", 6450 PO: "PageOpen", 6451 PC: "PageClose", 6452 PV: "PageVisible", 6453 PI: "PageInvisible", 6454 K: "Keystroke", 6455 F: "Format", 6456 V: "Validate", 6457 C: "Calculate" 6458})); 6459const DocumentActionEventType = (/* unused pure expression or super */ null && ({ 6460 WC: "WillClose", 6461 WS: "WillSave", 6462 DS: "DidSave", 6463 WP: "WillPrint", 6464 DP: "DidPrint" 6465})); 6466const PageActionEventType = (/* unused pure expression or super */ null && ({ 6467 O: "PageOpen", 6468 C: "PageClose" 6469})); 6470const VerbosityLevel = { 6471 ERRORS: 0, 6472 WARNINGS: 1, 6473 INFOS: 5 6474}; 6475const OPS = { 6476 dependency: 1, 6477 setLineWidth: 2, 6478 setLineCap: 3, 6479 setLineJoin: 4, 6480 setMiterLimit: 5, 6481 setDash: 6, 6482 setRenderingIntent: 7, 6483 setFlatness: 8, 6484 setGState: 9, 6485 save: 10, 6486 restore: 11, 6487 transform: 12, 6488 moveTo: 13, 6489 lineTo: 14, 6490 curveTo: 15, 6491 curveTo2: 16, 6492 curveTo3: 17, 6493 closePath: 18, 6494 rectangle: 19, 6495 stroke: 20, 6496 closeStroke: 21, 6497 fill: 22, 6498 eoFill: 23, 6499 fillStroke: 24, 6500 eoFillStroke: 25, 6501 closeFillStroke: 26, 6502 closeEOFillStroke: 27, 6503 endPath: 28, 6504 clip: 29, 6505 eoClip: 30, 6506 beginText: 31, 6507 endText: 32, 6508 setCharSpacing: 33, 6509 setWordSpacing: 34, 6510 setHScale: 35, 6511 setLeading: 36, 6512 setFont: 37, 6513 setTextRenderingMode: 38, 6514 setTextRise: 39, 6515 moveText: 40, 6516 setLeadingMoveText: 41, 6517 setTextMatrix: 42, 6518 nextLine: 43, 6519 showText: 44, 6520 showSpacedText: 45, 6521 nextLineShowText: 46, 6522 nextLineSetSpacingShowText: 47, 6523 setCharWidth: 48, 6524 setCharWidthAndBounds: 49, 6525 setStrokeColorSpace: 50, 6526 setFillColorSpace: 51, 6527 setStrokeColor: 52, 6528 setStrokeColorN: 53, 6529 setFillColor: 54, 6530 setFillColorN: 55, 6531 setStrokeGray: 56, 6532 setFillGray: 57, 6533 setStrokeRGBColor: 58, 6534 setFillRGBColor: 59, 6535 setStrokeCMYKColor: 60, 6536 setFillCMYKColor: 61, 6537 shadingFill: 62, 6538 beginInlineImage: 63, 6539 beginImageData: 64, 6540 endInlineImage: 65, 6541 paintXObject: 66, 6542 markPoint: 67, 6543 markPointProps: 68, 6544 beginMarkedContent: 69, 6545 beginMarkedContentProps: 70, 6546 endMarkedContent: 71, 6547 beginCompat: 72, 6548 endCompat: 73, 6549 paintFormXObjectBegin: 74, 6550 paintFormXObjectEnd: 75, 6551 beginGroup: 76, 6552 endGroup: 77, 6553 beginAnnotation: 80, 6554 endAnnotation: 81, 6555 paintImageMaskXObject: 83, 6556 paintImageMaskXObjectGroup: 84, 6557 paintImageXObject: 85, 6558 paintInlineImageXObject: 86, 6559 paintInlineImageXObjectGroup: 87, 6560 paintImageXObjectRepeat: 88, 6561 paintImageMaskXObjectRepeat: 89, 6562 paintSolidColorImageMask: 90, 6563 constructPath: 91, 6564 setStrokeTransparent: 92, 6565 setFillTransparent: 93, 6566 rawFillPath: 94 6567}; 6568const DrawOPS = { 6569 moveTo: 0, 6570 lineTo: 1, 6571 curveTo: 2, 6572 quadraticCurveTo: 3, 6573 closePath: 4 6574}; 6575const PasswordResponses = { 6576 NEED_PASSWORD: 1, 6577 INCORRECT_PASSWORD: 2 6578}; 6579let verbosity = VerbosityLevel.WARNINGS; 6580function setVerbosityLevel(level) { 6581 if (Number.isInteger(level)) { 6582 verbosity = level; 6583 } 6584} 6585function getVerbosityLevel() { 6586 return verbosity; 6587} 6588function info(msg) { 6589 if (verbosity >= VerbosityLevel.INFOS) { 6590 console.info(`Info: ${msg}`); 6591 } 6592} 6593function warn(msg) { 6594 if (verbosity >= VerbosityLevel.WARNINGS) { 6595 console.warn(`Warning: ${msg}`); 6596 } 6597} 6598function unreachable(msg) { 6599 throw new Error(msg); 6600} 6601function assert(cond, msg) { 6602 if (!cond) { 6603 unreachable(msg); 6604 } 6605} 6606function _isValidProtocol(url) { 6607 switch (url?.protocol) { 6608 case "http:": 6609 case "https:": 6610 case "ftp:": 6611 case "mailto:": 6612 case "tel:": 6613 return true; 6614 default: 6615 return false; 6616 } 6617} 6618function createValidAbsoluteUrl(url, baseUrl = null, options = null) { 6619 if (!url) { 6620 return null; 6621 } 6622 if (options && typeof url === "string") { 6623 if (options.addDefaultProtocol && url.startsWith("www.")) { 6624 const dots = url.match(/\./g); 6625 if (dots?.length >= 2) { 6626 url = `http://${url}`; 6627 } 6628 } 6629 if (options.tryConvertEncoding) { 6630 try { 6631 url = stringToUTF8String(url); 6632 } catch {} 6633 } 6634 } 6635 const absoluteUrl = baseUrl ? URL.parse(url, baseUrl) : URL.parse(url); 6636 return _isValidProtocol(absoluteUrl) ? absoluteUrl : null; 6637} 6638function updateUrlHash(url, hash, allowRel = false) { 6639 const res = URL.parse(url); 6640 if (res) { 6641 res.hash = hash; 6642 return res.href; 6643 } 6644 if (allowRel && createValidAbsoluteUrl(url, "http://example.com")) { 6645 return url.split("#", 1)[0] + `${hash ? `#${hash}` : ""}`; 6646 } 6647 return ""; 6648} 6649function stripPath(str) { 6650 return str.substring(str.lastIndexOf("/") + 1); 6651} 6652function shadow(obj, prop, value, nonSerializable = false) { 6653 Object.defineProperty(obj, prop, { 6654 value, 6655 enumerable: !nonSerializable, 6656 configurable: true, 6657 writable: false 6658 }); 6659 return value; 6660} 6661const BaseException = function BaseExceptionClosure() { 6662 function BaseException(message, name) { 6663 this.message = message; 6664 this.name = name; 6665 } 6666 BaseException.prototype = new Error(); 6667 BaseException.constructor = BaseException; 6668 return BaseException; 6669}(); 6670class PasswordException extends BaseException { 6671 constructor(msg, code) { 6672 super(msg, "PasswordException"); 6673 this.code = code; 6674 } 6675} 6676class UnknownErrorException extends BaseException { 6677 constructor(msg, details) { 6678 super(msg, "UnknownErrorException"); 6679 this.details = details; 6680 } 6681} 6682class InvalidPDFException extends BaseException { 6683 constructor(msg) { 6684 super(msg, "InvalidPDFException"); 6685 } 6686} 6687class ResponseException extends BaseException { 6688 constructor(msg, status, missing) { 6689 super(msg, "ResponseException"); 6690 this.status = status; 6691 this.missing = missing; 6692 } 6693} 6694class FormatError extends BaseException { 6695 constructor(msg) { 6696 super(msg, "FormatError"); 6697 } 6698} 6699class AbortException extends BaseException { 6700 constructor(msg) { 6701 super(msg, "AbortException"); 6702 } 6703} 6704function bytesToString(bytes) { 6705 if (typeof bytes !== "object" || bytes?.length === undefined) { 6706 unreachable("Invalid argument for bytesToString"); 6707 } 6708 const length = bytes.length; 6709 const MAX_ARGUMENT_COUNT = 8192; 6710 if (length < MAX_ARGUMENT_COUNT) { 6711 return String.fromCharCode.apply(null, bytes); 6712 } 6713 const strBuf = []; 6714 for (let i = 0; i < length; i += MAX_ARGUMENT_COUNT) { 6715 const chunkEnd = Math.min(i + MAX_ARGUMENT_COUNT, length); 6716 const chunk = bytes.subarray(i, chunkEnd); 6717 strBuf.push(String.fromCharCode.apply(null, chunk)); 6718 } 6719 return strBuf.join(""); 6720} 6721function stringToBytes(str) { 6722 if (typeof str !== "string") { 6723 unreachable("Invalid argument for stringToBytes"); 6724 } 6725 const length = str.length; 6726 const bytes = new Uint8Array(length); 6727 for (let i = 0; i < length; ++i) { 6728 bytes[i] = str.charCodeAt(i) & 0xff; 6729 } 6730 return bytes; 6731} 6732class FeatureTest { 6733 static get isLittleEndian() { 6734 const buffer8 = new Uint8Array(4); 6735 buffer8[0] = 1; 6736 const view32 = new Uint32Array(buffer8.buffer, 0, 1); 6737 return shadow(this, "isLittleEndian", view32[0] === 1); 6738 } 6739 static get isOffscreenCanvasSupported() { 6740 return shadow(this, "isOffscreenCanvasSupported", typeof OffscreenCanvas !== "undefined"); 6741 } 6742 static get isImageDecoderSupported() { 6743 return shadow(this, "isImageDecoderSupported", typeof ImageDecoder !== "undefined"); 6744 } 6745 static get isFloat16ArraySupported() { 6746 return shadow(this, "isFloat16ArraySupported", typeof Float16Array !== "undefined"); 6747 } 6748 static get isSanitizerSupported() { 6749 return shadow(this, "isSanitizerSupported", typeof Sanitizer !== "undefined"); 6750 } 6751 static get platform() { 6752 const { 6753 platform, 6754 userAgent 6755 } = navigator; 6756 return shadow(this, "platform", { 6757 isAndroid: userAgent.includes("Android"), 6758 isLinux: platform.includes("Linux"), 6759 isMac: platform.includes("Mac"), 6760 isWindows: platform.includes("Win"), 6761 isFirefox: userAgent.includes("Firefox") 6762 }); 6763 } 6764 static get isCanvasFilterSupported() { 6765 let ctx; 6766 if (this.isOffscreenCanvasSupported) { 6767 ctx = new OffscreenCanvas(1, 1).getContext("2d"); 6768 } else if (typeof document !== "undefined") { 6769 ctx = document.createElement("canvas").getContext("2d"); 6770 } 6771 return shadow(this, "isCanvasFilterSupported", ctx?.filter !== undefined); 6772 } 6773 static get isAlphaColorInputSupported() { 6774 if (typeof document === "undefined") { 6775 return shadow(this, "isAlphaColorInputSupported", false); 6776 } 6777 const input = document.createElement("input"); 6778 input.type = "color"; 6779 input.setAttribute("alpha", ""); 6780 input.value = "#ff000080"; 6781 return shadow(this, "isAlphaColorInputSupported", input.value !== "#ff0000"); 6782 } 6783 static get isBackdropFilterSupported() { 6784 return shadow(this, "isBackdropFilterSupported", typeof CSS !== "undefined" && CSS.supports("backdrop-filter", "blur(1px)")); 6785 } 6786} 6787class Util { 6788 static get hexNums() { 6789 return shadow(this, "hexNums", Array.from({ 6790 length: 256 6791 }, (_, n) => n.toString(16).padStart(2, "0"))); 6792 } 6793 static makeHexColor(r, g, b) { 6794 return `#${this.hexNums[r]}${this.hexNums[g]}${this.hexNums[b]}`; 6795 } 6796 static transform(m1, m2) { 6797 return [m1[0] * m2[0] + m1[2] * m2[1], m1[1] * m2[0] + m1[3] * m2[1], m1[0] * m2[2] + m1[2] * m2[3], m1[1] * m2[2] + m1[3] * m2[3], m1[0] * m2[4] + m1[2] * m2[5] + m1[4], m1[1] * m2[4] + m1[3] * m2[5] + m1[5]]; 6798 } 6799 static multiplyByDOMMatrix(m, md) { 6800 return [m[0] * md.a + m[2] * md.b, m[1] * md.a + m[3] * md.b, m[0] * md.c + m[2] * md.d, m[1] * md.c + m[3] * md.d, m[0] * md.e + m[2] * md.f + m[4], m[1] * md.e + m[3] * md.f + m[5]]; 6801 } 6802 static applyTransform(p, m, pos = 0) { 6803 const p0 = p[pos]; 6804 const p1 = p[pos + 1]; 6805 p[pos] = p0 * m[0] + p1 * m[2] + m[4]; 6806 p[pos + 1] = p0 * m[1] + p1 * m[3] + m[5]; 6807 } 6808 static applyTransformToBezier(p, transform, pos = 0) { 6809 const m0 = transform[0]; 6810 const m1 = transform[1]; 6811 const m2 = transform[2]; 6812 const m3 = transform[3]; 6813 const m4 = transform[4]; 6814 const m5 = transform[5]; 6815 for (let i = 0; i < 6; i += 2) { 6816 const pI = p[pos + i]; 6817 const pI1 = p[pos + i + 1]; 6818 p[pos + i] = pI * m0 + pI1 * m2 + m4; 6819 p[pos + i + 1] = pI * m1 + pI1 * m3 + m5; 6820 } 6821 } 6822 static applyInverseTransform(p, m) { 6823 const p0 = p[0]; 6824 const p1 = p[1]; 6825 const d = m[0] * m[3] - m[1] * m[2]; 6826 p[0] = (p0 * m[3] - p1 * m[2] + m[2] * m[5] - m[4] * m[3]) / d; 6827 p[1] = (-p0 * m[1] + p1 * m[0] + m[4] * m[1] - m[5] * m[0]) / d; 6828 } 6829 static axialAlignedBoundingBox(rect, transform, output) { 6830 const m0 = transform[0]; 6831 const m1 = transform[1]; 6832 const m2 = transform[2]; 6833 const m3 = transform[3]; 6834 const m4 = transform[4]; 6835 const m5 = transform[5]; 6836 const r0 = rect[0]; 6837 const r1 = rect[1]; 6838 const r2 = rect[2]; 6839 const r3 = rect[3]; 6840 let a0 = m0 * r0 + m4; 6841 let a2 = a0; 6842 let a1 = m0 * r2 + m4; 6843 let a3 = a1; 6844 let b0 = m3 * r1 + m5; 6845 let b2 = b0; 6846 let b1 = m3 * r3 + m5; 6847 let b3 = b1; 6848 if (m1 !== 0 || m2 !== 0) { 6849 const m1r0 = m1 * r0; 6850 const m1r2 = m1 * r2; 6851 const m2r1 = m2 * r1; 6852 const m2r3 = m2 * r3; 6853 a0 += m2r1; 6854 a3 += m2r1; 6855 a1 += m2r3; 6856 a2 += m2r3; 6857 b0 += m1r0; 6858 b3 += m1r0; 6859 b1 += m1r2; 6860 b2 += m1r2; 6861 } 6862 output[0] = Math.min(output[0], a0, a1, a2, a3); 6863 output[1] = Math.min(output[1], b0, b1, b2, b3); 6864 output[2] = Math.max(output[2], a0, a1, a2, a3); 6865 output[3] = Math.max(output[3], b0, b1, b2, b3); 6866 } 6867 static inverseTransform(m) { 6868 const d = m[0] * m[3] - m[1] * m[2]; 6869 return [m[3] / d, -m[1] / d, -m[2] / d, m[0] / d, (m[2] * m[5] - m[4] * m[3]) / d, (m[4] * m[1] - m[5] * m[0]) / d]; 6870 } 6871 static singularValueDecompose2dScale(matrix, output) { 6872 const m0 = matrix[0]; 6873 const m1 = matrix[1]; 6874 const m2 = matrix[2]; 6875 const m3 = matrix[3]; 6876 const a = m0 ** 2 + m1 ** 2; 6877 const b = m0 * m2 + m1 * m3; 6878 const c = m2 ** 2 + m3 ** 2; 6879 const first = (a + c) / 2; 6880 const second = Math.sqrt(first ** 2 - (a * c - b ** 2)); 6881 output[0] = Math.sqrt(first + second || 1); 6882 output[1] = Math.sqrt(first - second || 1); 6883 } 6884 static normalizeRect(rect) { 6885 const r = rect.slice(0); 6886 if (rect[0] > rect[2]) { 6887 r[0] = rect[2]; 6888 r[2] = rect[0]; 6889 } 6890 if (rect[1] > rect[3]) { 6891 r[1] = rect[3]; 6892 r[3] = rect[1]; 6893 } 6894 return r; 6895 } 6896 static intersect(rect1, rect2) { 6897 const xLow = Math.max(Math.min(rect1[0], rect1[2]), Math.min(rect2[0], rect2[2])); 6898 const xHigh = Math.min(Math.max(rect1[0], rect1[2]), Math.max(rect2[0], rect2[2])); 6899 if (xLow > xHigh) { 6900 return null; 6901 } 6902 const yLow = Math.max(Math.min(rect1[1], rect1[3]), Math.min(rect2[1], rect2[3])); 6903 const yHigh = Math.min(Math.max(rect1[1], rect1[3]), Math.max(rect2[1], rect2[3])); 6904 if (yLow > yHigh) { 6905 return null; 6906 } 6907 return [xLow, yLow, xHigh, yHigh]; 6908 } 6909 static pointBoundingBox(x, y, minMax) { 6910 minMax[0] = Math.min(minMax[0], x); 6911 minMax[1] = Math.min(minMax[1], y); 6912 minMax[2] = Math.max(minMax[2], x); 6913 minMax[3] = Math.max(minMax[3], y); 6914 } 6915 static rectBoundingBox(x0, y0, x1, y1, minMax) { 6916 minMax[0] = Math.min(minMax[0], x0, x1); 6917 minMax[1] = Math.min(minMax[1], y0, y1); 6918 minMax[2] = Math.max(minMax[2], x0, x1); 6919 minMax[3] = Math.max(minMax[3], y0, y1); 6920 } 6921 static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) { 6922 if (t <= 0 || t >= 1) { 6923 return; 6924 } 6925 const mt = 1 - t; 6926 const tt = t * t; 6927 const ttt = tt * t; 6928 const x = mt * (mt * (mt * x0 + 3 * t * x1) + 3 * tt * x2) + ttt * x3; 6929 const y = mt * (mt * (mt * y0 + 3 * t * y1) + 3 * tt * y2) + ttt * y3; 6930 minMax[0] = Math.min(minMax[0], x); 6931 minMax[1] = Math.min(minMax[1], y); 6932 minMax[2] = Math.max(minMax[2], x); 6933 minMax[3] = Math.max(minMax[3], y); 6934 } 6935 static #getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, a, b, c, minMax) { 6936 if (Math.abs(a) < 1e-12) { 6937 if (Math.abs(b) >= 1e-12) { 6938 this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, -c / b, minMax); 6939 } 6940 return; 6941 } 6942 const delta = b ** 2 - 4 * c * a; 6943 if (delta < 0) { 6944 return; 6945 } 6946 const sqrtDelta = Math.sqrt(delta); 6947 const a2 = 2 * a; 6948 this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b + sqrtDelta) / a2, minMax); 6949 this.#getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, (-b - sqrtDelta) / a2, minMax); 6950 } 6951 static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) { 6952 minMax[0] = Math.min(minMax[0], x0, x3); 6953 minMax[1] = Math.min(minMax[1], y0, y3); 6954 minMax[2] = Math.max(minMax[2], x0, x3); 6955 minMax[3] = Math.max(minMax[3], y0, y3); 6956 this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-x0 + 3 * (x1 - x2) + x3), 6 * (x0 - 2 * x1 + x2), 3 * (x1 - x0), minMax); 6957 this.#getExtremum(x0, x1, x2, x3, y0, y1, y2, y3, 3 * (-y0 + 3 * (y1 - y2) + y3), 6 * (y0 - 2 * y1 + y2), 3 * (y1 - y0), minMax); 6958 } 6959} 6960function stringToUTF8String(str) { 6961 return decodeURIComponent(escape(str)); 6962} 6963function utf8StringToString(str) { 6964 return unescape(encodeURIComponent(str)); 6965} 6966function isArrayEqual(arr1, arr2) { 6967 if (arr1.length !== arr2.length) { 6968 return false; 6969 } 6970 for (let i = 0, ii = arr1.length; i < ii; i++) { 6971 if (arr1[i] !== arr2[i]) { 6972 return false; 6973 } 6974 } 6975 return true; 6976} 6977let NormalizeRegex = null; 6978let NormalizationMap = null; 6979function normalizeUnicode(str) { 6980 if (!NormalizeRegex) { 6981 NormalizeRegex = /([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu; 6982 NormalizationMap = new Map([["ï¬ ", "Å¿t"]]); 6983 } 6984 return str.replaceAll(NormalizeRegex, (_, p1, p2) => p1 ? p1.normalize("NFKC") : NormalizationMap.get(p2)); 6985} 6986function getUuid() { 6987 if (typeof crypto.randomUUID === "function") { 6988 return crypto.randomUUID(); 6989 } 6990 const buf = new Uint8Array(32); 6991 crypto.getRandomValues(buf); 6992 return bytesToString(buf); 6993} 6994function _isValidExplicitDest(validRef, validName, dest) { 6995 if (!Array.isArray(dest) || dest.length < 2) { 6996 return false; 6997 } 6998 const [page, zoom, ...args] = dest; 6999 if (!validRef(page) && !Number.isInteger(page)) { 7000 return false; 7001 } 7002 if (!validName(zoom)) { 7003 return false; 7004 } 7005 const argsLen = args.length; 7006 let allowNull = true; 7007 switch (zoom.name) { 7008 case "XYZ": 7009 if (argsLen < 2 || argsLen > 3) { 7010 return false; 7011 } 7012 break; 7013 case "Fit": 7014 case "FitB": 7015 return argsLen === 0; 7016 case "FitH": 7017 case "FitBH": 7018 case "FitV": 7019 case "FitBV": 7020 if (argsLen > 1) { 7021 return false; 7022 } 7023 break; 7024 case "FitR": 7025 if (argsLen !== 4) { 7026 return false; 7027 } 7028 allowNull = false; 7029 break; 7030 default: 7031 return false; 7032 } 7033 for (const arg of args) { 7034 if (typeof arg === "number" || allowNull && arg === null) { 7035 continue; 7036 } 7037 return false; 7038 } 7039 return true; 7040} 7041const makeArr = () => []; 7042const makeMap = () => new Map(); 7043const makeObj = () => Object.create(null); 7044const makeSet = () => new Set(); 7045if (typeof
vendor: 13,342 bytes, lines 7045-7486
7045Blob.prototype.bytes !== "function") { 7046 Blob.prototype.bytes = async function () { 7047 return new Uint8Array(await this.arrayBuffer()); 7048 }; 7049} 7050if (typeof Response.prototype.bytes !== "function") { 7051 Response.prototype.bytes = async function () { 7052 return new Uint8Array(await this.arrayBuffer()); 7053 }; 7054} 7055if (typeof Iterator.prototype.join !== "function") { 7056 Iterator.prototype.join = function (separator) { 7057 return [...this].join(separator); 7058 }; 7059} 7060 7061// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.map.js 7062var es_iterator_map = __webpack_require__(1701); 7063;// ./src/shared/math_clamp.js 7064function MathClamp(v, min, max) { 7065 return Math.min(Math.max(v, min), max); 7066} 7067 7068;// ./src/display/page_viewport.js 7069 7070class PageViewport { 7071 constructor({ 7072 viewBox, 7073 userUnit, 7074 scale, 7075 rotation, 7076 offsetX = 0, 7077 offsetY = 0, 7078 dontFlip = false 7079 }) { 7080 this.viewBox = viewBox; 7081 this.userUnit = userUnit; 7082 this.scale = scale; 7083 this.rotation = rotation; 7084 this.offsetX = offsetX; 7085 this.offsetY = offsetY; 7086 scale *= userUnit; 7087 const centerX = (viewBox[2] + viewBox[0]) / 2; 7088 const centerY = (viewBox[3] + viewBox[1]) / 2; 7089 let rotateA, rotateB, rotateC, rotateD; 7090 rotation %= 360; 7091 if (rotation < 0) { 7092 rotation += 360; 7093 } 7094 switch (rotation) { 7095 case 180: 7096 rotateA = -1; 7097 rotateB = 0; 7098 rotateC = 0; 7099 rotateD = 1; 7100 break; 7101 case 90: 7102 rotateA = 0; 7103 rotateB = 1; 7104 rotateC = 1; 7105 rotateD = 0; 7106 break; 7107 case 270: 7108 rotateA = 0; 7109 rotateB = -1; 7110 rotateC = -1; 7111 rotateD = 0; 7112 break; 7113 case 0: 7114 rotateA = 1; 7115 rotateB = 0; 7116 rotateC = 0; 7117 rotateD = -1; 7118 break; 7119 default: 7120 throw new Error("PageViewport: Invalid rotation, must be a multiple of 90 degrees."); 7121 } 7122 if (dontFlip) { 7123 rotateC = -rotateC; 7124 rotateD = -rotateD; 7125 } 7126 let offsetCanvasX, offsetCanvasY; 7127 let width, height; 7128 if (rotateA === 0) { 7129 offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX; 7130 offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY; 7131 width = (viewBox[3] - viewBox[1]) * scale; 7132 height = (viewBox[2] - viewBox[0]) * scale; 7133 } else { 7134 offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX; 7135 offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY; 7136 width = (viewBox[2] - viewBox[0]) * scale; 7137 height = (viewBox[3] - viewBox[1]) * scale; 7138 } 7139 this.transform = [rotateA * scale, rotateB * scale, rotateC * scale, rotateD * scale, offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY, offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY]; 7140 this.width = width; 7141 this.height = height; 7142 } 7143 get rawDims() { 7144 const dims = this.viewBox; 7145 return shadow(this, "rawDims", { 7146 pageWidth: dims[2] - dims[0], 7147 pageHeight: dims[3] - dims[1], 7148 pageX: dims[0], 7149 pageY: dims[1] 7150 }); 7151 } 7152 clone({ 7153 scale = this.scale, 7154 rotation = this.rotation, 7155 offsetX = this.offsetX, 7156 offsetY = this.offsetY, 7157 dontFlip = false 7158 } = {}) { 7159 return new PageViewport({ 7160 viewBox: this.viewBox.slice(), 7161 userUnit: this.userUnit, 7162 scale, 7163 rotation, 7164 offsetX, 7165 offsetY, 7166 dontFlip 7167 }); 7168 } 7169 convertToViewportPoint(x, y) { 7170 const p = [x, y]; 7171 Util.applyTransform(p, this.transform); 7172 return p; 7173 } 7174 convertToPdfPoint(x, y) { 7175 const p = [x, y]; 7176 Util.applyInverseTransform(p, this.transform); 7177 return p; 7178 } 7179} 7180 7181;// ./src/display/xfa_text.js 7182 7183class XfaText { 7184 static textContent(xfa) { 7185 const items = []; 7186 const output = { 7187 items, 7188 styles: Object.create(null) 7189 }; 7190 function walk(node) { 7191 if (!node) { 7192 return; 7193 } 7194 let str = null; 7195 const name = node.name; 7196 if (name === "#text") { 7197 str = node.value; 7198 } else if (!XfaText.shouldBuildText(name)) { 7199 return; 7200 } else if (node?.attributes?.textContent) { 7201 str = node.attributes.textContent; 7202 } else if (node.value) { 7203 str = node.value; 7204 } 7205 if (str !== null) { 7206 items.push({ 7207 str 7208 }); 7209 } 7210 if (!node.children) { 7211 return; 7212 } 7213 for (const child of node.children) { 7214 walk(child); 7215 } 7216 } 7217 walk(xfa); 7218 return output; 7219 } 7220 static shouldBuildText(name) { 7221 return !(name === "textarea" || name === "input" || name === "option" || name === "select"); 7222 } 7223} 7224 7225;// ./src/display/xfa_layer.js 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237const disallowedRichTextStyleRegExp = /url\(|image-set\(/i; 7238const disallowedEventHandlerAttrRegExp = /^on/i; 7239class XfaLayer { 7240 static get _allowedHtmlElements() { 7241 return shadow(this, "_allowedHtmlElements", new Set(["a", "b", "br", "button", "div", "i", "img", "input", "label", "li", "ol", "option", "p", "select", "span", "sub", "sup", "textarea", "ul"])); 7242 } 7243 static get _allowedSvgElements() { 7244 return shadow(this, "_allowedSvgElements", new Set(["ellipse", "line", "path", "rect", "svg"])); 7245 } 7246 static get _allowedRichTextElements() { 7247 return shadow(this, "_allowedRichTextElements", new Set(["a", "b", "br", "div", "i", "li", "ol", "p", "span", "sub", "sup", "ul"])); 7248 } 7249 static get _allowedRichTextAttributes() { 7250 return shadow(this, "_allowedRichTextAttributes", new Set(["class", "dir", "style"])); 7251 } 7252 static get _allowedRichTextStyles() { 7253 return shadow(this, "_allowedRichTextStyles", new Set(["color", "font", "fontFamily", "fontSize", "fontStretch", "fontStyle", "fontWeight", "kerningMode", "letterSpacing", "lineHeight", "margin", "marginBottom", "marginLeft", "marginRight", "marginTop", "orphans", "paddingLeft", "paddingRight", "breakAfter", "breakBefore", "breakInside", "tabInterval", "tabStop", "textAlign", "textDecoration", "textIndent", "transform", "verticalAlign", "widows"])); 7254 } 7255 static setupStorage(html, id, element, storage, intent) { 7256 const storedData = storage.getValue(id, { 7257 value: null 7258 }); 7259 switch (element.name) { 7260 case "textarea": 7261 if (storedData.value !== null) { 7262 html.textContent = storedData.value; 7263 } 7264 if (intent === "print") { 7265 break; 7266 } 7267 html.addEventListener("input", event => { 7268 storage.setValue(id, { 7269 value: event.target.value 7270 }); 7271 }); 7272 break; 7273 case "input": 7274 if (element.attributes.type === "radio" || element.attributes.type === "checkbox") { 7275 if (storedData.value === element.attributes.xfaOn) { 7276 html.setAttribute("checked", true); 7277 } else if (storedData.value === element.attributes.xfaOff) { 7278 html.removeAttribute("checked"); 7279 } 7280 if (intent === "print") { 7281 break; 7282 } 7283 html.addEventListener("change", event => { 7284 storage.setValue(id, { 7285 value: event.target.checked ? event.target.getAttribute("xfaOn") : event.target.getAttribute("xfaOff") 7286 }); 7287 }); 7288 } else { 7289 if (storedData.value !== null) { 7290 html.setAttribute("value", storedData.value); 7291 } 7292 if (intent === "print") { 7293 break; 7294 } 7295 html.addEventListener("input", event => { 7296 storage.setValue(id, { 7297 value: event.target.value 7298 }); 7299 }); 7300 } 7301 break; 7302 case "select": 7303 if (storedData.value !== null) { 7304 html.setAttribute("value", storedData.value); 7305 for (const option of element.children) { 7306 if (option.attributes.value === storedData.value) { 7307 option.attributes.selected = true; 7308 } else if (Object.hasOwn(option.attributes, "selected")) { 7309 delete option.attributes.selected; 7310 } 7311 } 7312 } 7313 html.addEventListener("input", event => { 7314 const options = event.target.options; 7315 const value = options.selectedIndex === -1 ? "" : options[options.selectedIndex].value; 7316 storage.setValue(id, { 7317 value 7318 }); 7319 }); 7320 break; 7321 } 7322 } 7323 static setAttributes({ 7324 html, 7325 element, 7326 storage = null, 7327 intent, 7328 linkService 7329 }) { 7330 const { 7331 attributes 7332 } = element; 7333 const isHTMLAnchorElement = html instanceof HTMLAnchorElement; 7334 if (attributes.type === "radio") { 7335 attributes.name = `${attributes.name}-${intent}`; 7336 } 7337 for (const [key, value] of Object.entries(attributes)) { 7338 if (value === null || value === undefined) { 7339 continue; 7340 } 7341 if (disallowedEventHandlerAttrRegExp.test(key)) { 7342 continue; 7343 } 7344 if (intent === "richText" && !this._allowedRichTextAttributes.has(key)) { 7345 continue; 7346 } 7347 switch (key) { 7348 case "class": 7349 if (value.length) { 7350 html.setAttribute(key, value.join(" ")); 7351 } 7352 break; 7353 case "dataId": 7354 break; 7355 case "id": 7356 html.setAttribute("data-element-id", value); 7357 break; 7358 case "style": 7359 if (intent === "richText") { 7360 const allowedStyles = this._allowedRichTextStyles; 7361 for (const [styleName, styleValue] of Object.entries(value)) { 7362 if (allowedStyles.has(styleName) && !disallowedRichTextStyleRegExp.test(styleValue)) { 7363 html.style[styleName] = styleValue; 7364 } 7365 } 7366 } else { 7367 Object.assign(html.style, value); 7368 } 7369 break; 7370 case "textContent": 7371 html.textContent = value; 7372 break; 7373 default: 7374 if (!isHTMLAnchorElement || key !== "href" && key !== "newWindow") { 7375 html.setAttribute(key, value); 7376 } 7377 } 7378 } 7379 if (isHTMLAnchorElement) { 7380 linkService?.addLinkAttributes(html, attributes.href, attributes.newWindow); 7381 } 7382 if (storage && attributes.dataId) { 7383 this.setupStorage(html, attributes.dataId, element, storage); 7384 } 7385 } 7386 static #createElement(name, xmlns, intent) { 7387 if (intent === "richText") { 7388 return !xmlns && this._allowedRichTextElements.has(name) ? document.createElement(name) : null; 7389 } 7390 if (xmlns) { 7391 return xmlns === SVG_NS && this._allowedSvgElements.has(name) ? document.createElementNS(SVG_NS, name) : null; 7392 } 7393 return this._allowedHtmlElements.has(name) ? document.createElement(name) : null; 7394 } 7395 static render(parameters) { 7396 const storage = parameters.annotationStorage; 7397 const linkService = parameters.linkService; 7398 const root = parameters.xfaHtml; 7399 const intent = parameters.intent || "display"; 7400 const rootHtml = this.#createElement(root.name, root.attributes?.xmlns, intent) ?? document.createElement("div"); 7401 if (root.attributes) { 7402 this.setAttributes({ 7403 html: rootHtml, 7404 element: root, 7405 intent, 7406 linkService 7407 }); 7408 } 7409 const isNotForRichText = intent !== "richText"; 7410 const rootDiv = parameters.div; 7411 rootDiv.append(rootHtml); 7412 if (parameters.viewport) { 7413 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 7414 rootDiv.style.transform = transform; 7415 } 7416 if (isNotForRichText) { 7417 rootDiv.setAttribute("class", "xfaLayer xfaFont"); 7418 } 7419 const textDivs = []; 7420 if (root.children.length === 0) { 7421 if (root.value) { 7422 const node = document.createTextNode(root.value); 7423 rootHtml.append(node); 7424 if (isNotForRichText && XfaText.shouldBuildText(root.name)) { 7425 textDivs.push(node); 7426 } 7427 } 7428 return { 7429 textDivs 7430 }; 7431 } 7432 const stack = [[root, -1, rootHtml]]; 7433 while (stack.length > 0) { 7434 const [parent, i, html] = stack.at(-1); 7435 if (i + 1 === parent.children.length) { 7436 stack.pop(); 7437 continue; 7438 } 7439 const child = parent.children[++stack.at(-1)[1]]; 7440 if (child === null) { 7441 continue; 7442 } 7443 const { 7444 name 7445 } = child; 7446 if (name === "#text") { 7447 const node = document.createTextNode(child.value); 7448 textDivs.push(node); 7449 html.append(node); 7450 continue; 7451 } 7452 const childHtml = this.#createElement(name, child.attributes?.xmlns, intent); 7453 if (!childHtml) { 7454 continue; 7455 } 7456 html.append(childHtml); 7457 if (child.attributes) { 7458 this.setAttributes({ 7459 html: childHtml, 7460 element: child, 7461 storage, 7462 intent, 7463 linkService 7464 }); 7465 } 7466 if (child.children?.length > 0) { 7467 stack.push([child, -1, childHtml]); 7468 } else if (child.value) { 7469 const node = document.createTextNode(child.value); 7470 if (isNotForRichText && XfaText.shouldBuildText(name)) { 7471 textDivs.push(node); 7472 } 7473 childHtml.append(node); 7474 } 7475 } 7476 for (const el of rootDiv.querySelectorAll(".xfaNonInteractive input, .xfaNonInteractive textarea")) { 7477 el.setAttribute("readOnly", true); 7478 } 7479 return { 7480 textDivs 7481 }; 7482 } 7483 static update(parameters) { 7484 const transform = `matrix(${parameters.viewport.transform.join(",")})`; 7485 parameters.div.style.transform = transform; 7486 parameters.div.hidden = false;
7487 } 7488 static getPageViewport(xfaPage, { 7489 scale = 1, 7490 rotation = 0 7491 }) { 7492 const { 7493 width, 7494 height 7495 } = xfaPage.attributes.style; 7496 return new PageViewport({ 7497 viewBox: [0, 0, parseInt(width, 10), parseInt(height, 10)], 7498 userUnit: 1, 7499 scale, 7500 rotation 7501 }); 7502 } 7503} 7504 7505;// ./src/display/display_utils.js 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516
vendor: 16,270 bytes, lines 7517-8079
7517 7518 7519 7520 7521 7522class PixelsPerInch { 7523 static CSS = 96.0; 7524 static PDF = 72.0; 7525 static PDF_TO_CSS_UNITS = this.CSS / this.PDF; 7526} 7527async function fetchData(url, type = "text") { 7528 if (isValidFetchUrl(url, document.baseURI)) { 7529 const response = await fetch(url); 7530 if (!response.ok) { 7531 throw new Error(response.statusText); 7532 } 7533 switch (type) { 7534 case "blob": 7535 return response.blob(); 7536 case "bytes": 7537 return response.bytes(); 7538 case "json": 7539 return response.json(); 7540 } 7541 return response.text(); 7542 } 7543 return new Promise((resolve, reject) => { 7544 const request = new XMLHttpRequest(); 7545 request.open("GET", url, true); 7546 request.responseType = type === "bytes" ? "arraybuffer" : type; 7547 request.onreadystatechange = () => { 7548 if (request.readyState !== XMLHttpRequest.DONE) { 7549 return; 7550 } 7551 if (request.status === 200 || request.status === 0) { 7552 switch (type) { 7553 case "bytes": 7554 resolve(new Uint8Array(request.response)); 7555 return; 7556 case "blob": 7557 case "json": 7558 resolve(request.response); 7559 return; 7560 } 7561 resolve(request.responseText); 7562 return; 7563 } 7564 reject(new Error(request.statusText)); 7565 }; 7566 request.send(null); 7567 }); 7568} 7569class RenderingCancelledException extends BaseException { 7570 constructor(msg, extraDelay = 0) { 7571 super(msg, "RenderingCancelledException"); 7572 this.extraDelay = extraDelay; 7573 } 7574} 7575function isDataScheme(url) { 7576 const ii = url.length; 7577 let i = 0; 7578 while (i < ii && url[i].trim() === "") { 7579 i++; 7580 } 7581 return url.substring(i, i + 5).toLowerCase() === "data:"; 7582} 7583function isPdfFile(filename) { 7584 return typeof filename === "string" && /\.pdf$/i.test(filename); 7585} 7586function getFilenameFromUrl(url) { 7587 [url] = url.split(/[#?]/, 1); 7588 return stripPath(url); 7589} 7590function getPdfFilenameFromUrl(url, defaultFilename = "document.pdf") { 7591 if (typeof url !== "string") { 7592 return defaultFilename; 7593 } 7594 if (isDataScheme(url)) { 7595 warn('getPdfFilenameFromUrl: ignore "data:"-URL for performance reasons.'); 7596 return defaultFilename; 7597 } 7598 const getURL = urlString => { 7599 try { 7600 return new URL(urlString); 7601 } catch {} 7602 try { 7603 return new URL(decodeURIComponent(urlString)); 7604 } catch {} 7605 try { 7606 return new URL(urlString, "https://foo.bar"); 7607 } catch {} 7608 try { 7609 return new URL(decodeURIComponent(urlString), "https://foo.bar"); 7610 } catch {} 7611 return null; 7612 }; 7613 const newURL = getURL(url); 7614 if (!newURL) { 7615 return defaultFilename; 7616 } 7617 const decode = name => { 7618 try { 7619 let decoded = decodeURIComponent(name); 7620 if (decoded.includes("/")) { 7621 decoded = stripPath(decoded); 7622 if (decoded.length === 4 && pdfRegex.test(decoded)) { 7623 return name; 7624 } 7625 } 7626 return decoded; 7627 } catch { 7628 return name; 7629 } 7630 }; 7631 const pdfRegex = /\.pdf$/i; 7632 const filename = stripPath(newURL.pathname); 7633 if (pdfRegex.test(filename)) { 7634 return decode(filename); 7635 } 7636 if (newURL.searchParams.size > 0) { 7637 const getLast = iterator => [...iterator].findLast(v => pdfRegex.test(v)); 7638 const name = getLast(newURL.searchParams.values()) ?? getLast(newURL.searchParams.keys()); 7639 if (name) { 7640 return decode(name); 7641 } 7642 } 7643 if (newURL.hash) { 7644 const { 7645 hash 7646 } = newURL; 7647 let extensionStart = -1; 7648 for (const { 7649 index 7650 } of hash.matchAll(/\.pdf\b/gi)) { 7651 extensionStart = index; 7652 } 7653 if (extensionStart > 0) { 7654 let filenameStart = extensionStart; 7655 while (filenameStart > 0 && !"/?#=".includes(hash[filenameStart - 1])) { 7656 filenameStart--; 7657 } 7658 if (filenameStart < extensionStart) { 7659 return decode(hash.slice(filenameStart, extensionStart + 4)); 7660 } 7661 } 7662 } 7663 return defaultFilename; 7664} 7665class StatTimer { 7666 #started = new Map(); 7667 times = []; 7668 time(name) { 7669 if (this.#started.has(name)) { 7670 warn(`Timer is already running for ${name}`); 7671 } 7672 this.#started.set(name, Date.now()); 7673 } 7674 timeEnd(name) { 7675 if (!this.#started.has(name)) { 7676 warn(`Timer has not been started for ${name}`); 7677 } 7678 this.times.push({ 7679 name, 7680 start: this.#started.get(name), 7681 end: Date.now() 7682 }); 7683 this.#started.delete(name); 7684 } 7685 toString() { 7686 const longest = Math.max(...this.times.map(t => t.name.length)); 7687 return this.times.map(t => `${t.name.padEnd(longest)} ${t.end - t.start}ms\n`).join(""); 7688 } 7689} 7690function isValidFetchUrl(url, baseUrl) { 7691 const res = baseUrl ? URL.parse(url, baseUrl) : URL.parse(url); 7692 return /https?:/.test(res?.protocol ?? ""); 7693} 7694function noContextMenu(e) { 7695 e.preventDefault(); 7696} 7697function stopEvent(e) { 7698 e.preventDefault(); 7699 e.stopPropagation(); 7700} 7701function deprecated(details) { 7702 console.log("Deprecated API usage: " + details); 7703} 7704class PDFDateString { 7705 static #regex; 7706 static toDateObject(input) { 7707 if (input instanceof Date) { 7708 return input; 7709 } 7710 if (!input || typeof input !== "string") { 7711 return null; 7712 } 7713 this.#regex ||= new RegExp("^D:" + "(\\d{4})" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "(\\d{2})?" + "([Z|+\\-])?" + "(\\d{2})?" + "'?" + "(\\d{2})?" + "'?"); 7714 const matches = this.#regex.exec(input); 7715 if (!matches) { 7716 return null; 7717 } 7718 const year = parseInt(matches[1], 10); 7719 let month = parseInt(matches[2], 10); 7720 month = month >= 1 && month <= 12 ? month - 1 : 0; 7721 let day = parseInt(matches[3], 10); 7722 day = day >= 1 && day <= 31 ? day : 1; 7723 let hour = parseInt(matches[4], 10); 7724 hour = hour >= 0 && hour <= 23 ? hour : 0; 7725 let minute = parseInt(matches[5], 10); 7726 minute = minute >= 0 && minute <= 59 ? minute : 0; 7727 let second = parseInt(matches[6], 10); 7728 second = second >= 0 && second <= 59 ? second : 0; 7729 const universalTimeRelation = matches[7] || "Z"; 7730 let offsetHour = parseInt(matches[8], 10); 7731 offsetHour = offsetHour >= 0 && offsetHour <= 23 ? offsetHour : 0; 7732 let offsetMinute = parseInt(matches[9], 10) || 0; 7733 offsetMinute = offsetMinute >= 0 && offsetMinute <= 59 ? offsetMinute : 0; 7734 if (universalTimeRelation === "-") { 7735 hour += offsetHour; 7736 minute += offsetMinute; 7737 } else if (universalTimeRelation === "+") { 7738 hour -= offsetHour; 7739 minute -= offsetMinute; 7740 } 7741 return new Date(Date.UTC(year, month, day, hour, minute, second)); 7742 } 7743} 7744function getRGBA(color) { 7745 if (color.startsWith("#")) { 7746 const hex = color.slice(1); 7747 return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16), hex.length >= 8 ? parseInt(hex.slice(6, 8), 16) / 255 : 1]; 7748 } 7749 if (color.startsWith("rgb(")) { 7750 const [r, g, b] = color.slice(4, -1).split(",").map(x => parseInt(x, 10)); 7751 return [r, g, b, 1]; 7752 } 7753 if (color.startsWith("rgba(")) { 7754 const parts = color.slice(5, -1).split(","); 7755 return [parseInt(parts[0], 10), parseInt(parts[1], 10), parseInt(parts[2], 10), parseFloat(parts[3])]; 7756 } 7757 const m = color.match(/^color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+|none))?\)$/); 7758 if (m) { 7759 return [Math.round(parseFloat(m[1]) * 255), Math.round(parseFloat(m[2]) * 255), Math.round(parseFloat(m[3]) * 255), m[4] !== undefined && m[4] !== "none" ? parseFloat(m[4]) : 1]; 7760 } 7761 return null; 7762} 7763function getRGB(color) { 7764 const rgba = getRGBA(color); 7765 if (!rgba) { 7766 warn(`Not a valid color format: "${color}"`); 7767 return [0, 0, 0]; 7768 } 7769 return rgba.slice(0, 3); 7770} 7771function getColorValues(colors) { 7772 const span = document.createElement("span"); 7773 span.style.visibility = "hidden"; 7774 span.style.colorScheme = "only light"; 7775 document.body.append(span); 7776 for (const name of colors.keys()) { 7777 span.style.color = name; 7778 const computedColor = window.getComputedStyle(span).color; 7779 colors.set(name, getRGB(computedColor)); 7780 } 7781 span.remove(); 7782} 7783function getCurrentTransform(ctx) { 7784 const { 7785 a, 7786 b, 7787 c, 7788 d, 7789 e, 7790 f 7791 } = ctx.getTransform(); 7792 return [a, b, c, d, e, f]; 7793} 7794function getCurrentTransformInverse(ctx) { 7795 const { 7796 a, 7797 b, 7798 c, 7799 d, 7800 e, 7801 f 7802 } = ctx.getTransform().invertSelf(); 7803 return [a, b, c, d, e, f]; 7804} 7805function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) { 7806 if (viewport instanceof PageViewport) { 7807 const { 7808 pageWidth, 7809 pageHeight 7810 } = viewport.rawDims; 7811 const { 7812 style 7813 } = div; 7814 const widthStr = `round(down, var(--total-scale-factor) * ${pageWidth}px, var(--scale-round-x))`, 7815 heightStr = `round(down, var(--total-scale-factor) * ${pageHeight}px, var(--scale-round-y))`; 7816 if (!mustFlip || viewport.rotation % 180 === 0) { 7817 style.width = widthStr; 7818 style.height = heightStr; 7819 } else { 7820 style.width = heightStr; 7821 style.height = widthStr; 7822 } 7823 } 7824 if (mustRotate) { 7825 div.setAttribute("data-main-rotation", viewport.rotation); 7826 } 7827} 7828class OutputScale { 7829 constructor() { 7830 const { 7831 pixelRatio 7832 } = OutputScale; 7833 this.sx = pixelRatio; 7834 this.sy = pixelRatio; 7835 } 7836 get scaled() { 7837 return this.sx !== 1 || this.sy !== 1; 7838 } 7839 get symmetric() { 7840 return this.sx === this.sy; 7841 } 7842 limitCanvas(width, height, maxPixels, maxDim, capAreaFactor = -1) { 7843 let maxAreaScale = Infinity, 7844 maxWidthScale = Infinity, 7845 maxHeightScale = Infinity; 7846 maxPixels = OutputScale.capPixels(maxPixels, capAreaFactor); 7847 if (maxPixels > 0) { 7848 maxAreaScale = Math.sqrt(maxPixels / (width * height)); 7849 } 7850 if (maxDim !== -1) { 7851 maxWidthScale = maxDim / width; 7852 maxHeightScale = maxDim / height; 7853 } 7854 const maxScale = Math.min(maxAreaScale, maxWidthScale, maxHeightScale); 7855 if (this.sx > maxScale || this.sy > maxScale) { 7856 this.sx = maxScale; 7857 this.sy = maxScale; 7858 return true; 7859 } 7860 return false; 7861 } 7862 static get pixelRatio() { 7863 return globalThis.devicePixelRatio || 1; 7864 } 7865 static capPixels(maxPixels, capAreaFactor) { 7866 if (capAreaFactor >= 0) { 7867 const winPixels = Math.ceil(window.screen.availWidth * window.screen.availHeight * this.pixelRatio ** 2 * (1 + capAreaFactor / 100)); 7868 return maxPixels > 0 ? Math.min(maxPixels, winPixels) : winPixels; 7869 } 7870 return maxPixels; 7871 } 7872} 7873const SupportedImageMimeTypes = ["image/apng", "image/avif", "image/bmp", "image/gif", "image/jpeg", "image/png", "image/svg+xml", "image/webp", "image/x-icon"]; 7874class ColorScheme { 7875 static get isDarkMode() { 7876 return shadow(this, "isDarkMode", !!window?.matchMedia?.("(prefers-color-scheme: dark)").matches); 7877 } 7878} 7879class CSSConstants { 7880 static get commentForegroundColor() { 7881 const element = document.createElement("span"); 7882 element.classList.add("comment", "sidebar"); 7883 const { 7884 style 7885 } = element; 7886 style.width = style.height = "0"; 7887 style.display = "none"; 7888 style.color = "var(--comment-fg-color)"; 7889 document.body.append(element); 7890 const { 7891 color 7892 } = window.getComputedStyle(element); 7893 element.remove(); 7894 return shadow(this, "commentForegroundColor", getRGB(color)); 7895 } 7896} 7897function applyOpacity(color, opacity) { 7898 opacity = MathClamp(opacity ?? 1, 0, 1); 7899 const white = 255 * (1 - opacity); 7900 return color.map(c => Math.round(c * opacity + white)); 7901} 7902function RGBToHSL(rgb, output) { 7903 const r = rgb[0] / 255; 7904 const g = rgb[1] / 255; 7905 const b = rgb[2] / 255; 7906 const max = Math.max(r, g, b); 7907 const min = Math.min(r, g, b); 7908 const l = (max + min) / 2; 7909 if (max === min) { 7910 output[0] = output[1] = 0; 7911 } else { 7912 const d = max - min; 7913 output[1] = l < 0.5 ? d / (max + min) : d / (2 - max - min); 7914 switch (max) { 7915 case r: 7916 output[0] = ((g - b) / d + (g < b ? 6 : 0)) * 60; 7917 break; 7918 case g: 7919 output[0] = ((b - r) / d + 2) * 60; 7920 break; 7921 case b: 7922 output[0] = ((r - g) / d + 4) * 60; 7923 break; 7924 } 7925 } 7926 output[2] = l; 7927} 7928function HSLToRGB(hsl, output) { 7929 const h = hsl[0]; 7930 const s = hsl[1]; 7931 const l = hsl[2]; 7932 const c = (1 - Math.abs(2 * l - 1)) * s; 7933 const x = c * (1 - Math.abs(h / 60 % 2 - 1)); 7934 const m = l - c / 2; 7935 switch (Math.floor(h / 60)) { 7936 case 0: 7937 output[0] = c + m; 7938 output[1] = x + m; 7939 output[2] = m; 7940 break; 7941 case 1: 7942 output[0] = x + m; 7943 output[1] = c + m; 7944 output[2] = m; 7945 break; 7946 case 2: 7947 output[0] = m; 7948 output[1] = c + m; 7949 output[2] = x + m; 7950 break; 7951 case 3: 7952 output[0] = m; 7953 output[1] = x + m; 7954 output[2] = c + m; 7955 break; 7956 case 4: 7957 output[0] = x + m; 7958 output[1] = m; 7959 output[2] = c + m; 7960 break; 7961 case 5: 7962 case 6: 7963 output[0] = c + m; 7964 output[1] = m; 7965 output[2] = x + m; 7966 break; 7967 } 7968} 7969function computeLuminance(x) { 7970 return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4; 7971} 7972function contrastRatio(hsl1, hsl2, output) { 7973 HSLToRGB(hsl1, output); 7974 output.map(computeLuminance); 7975 const lum1 = 0.2126 * output[0] + 0.7152 * output[1] + 0.0722 * output[2]; 7976 HSLToRGB(hsl2, output); 7977 output.map(computeLuminance); 7978 const lum2 = 0.2126 * output[0] + 0.7152 * output[1] + 0.0722 * output[2]; 7979 return lum1 > lum2 ? (lum1 + 0.05) / (lum2 + 0.05) : (lum2 + 0.05) / (lum1 + 0.05); 7980} 7981const contrastCache = new Map(); 7982function findContrastColor(baseColor, fixedColor) { 7983 const key = baseColor[0] + baseColor[1] * 0x100 + baseColor[2] * 0x10000 + fixedColor[0] * 0x1000000 + fixedColor[1] * 0x100000000 + fixedColor[2] * 0x10000000000; 7984 let cachedValue = contrastCache.get(key); 7985 if (cachedValue) { 7986 return cachedValue; 7987 } 7988 const array = new Float32Array(9); 7989 const output = array.subarray(0, 3); 7990 const baseHSL = array.subarray(3, 6); 7991 RGBToHSL(baseColor, baseHSL); 7992 const fixedHSL = array.subarray(6, 9); 7993 RGBToHSL(fixedColor, fixedHSL); 7994 const isFixedColorDark = fixedHSL[2] < 0.5; 7995 const minContrast = isFixedColorDark ? 12 : 4.5; 7996 baseHSL[2] = isFixedColorDark ? Math.sqrt(baseHSL[2]) : 1 - Math.sqrt(1 - baseHSL[2]); 7997 if (contrastRatio(baseHSL, fixedHSL, output) < minContrast) { 7998 let start, end; 7999 if (isFixedColorDark) { 8000 start = baseHSL[2]; 8001 end = 1; 8002 } else { 8003 start = 0; 8004 end = baseHSL[2]; 8005 } 8006 const PRECISION = 0.005; 8007 while (end - start > PRECISION) { 8008 const mid = baseHSL[2] = (start + end) / 2; 8009 if (isFixedColorDark === contrastRatio(baseHSL, fixedHSL, output) < minContrast) { 8010 start = mid; 8011 } else { 8012 end = mid; 8013 } 8014 } 8015 baseHSL[2] = isFixedColorDark ? end : start; 8016 } 8017 HSLToRGB(baseHSL, output); 8018 cachedValue = Util.makeHexColor(Math.round(output[0] * 255), Math.round(output[1] * 255), Math.round(output[2] * 255)); 8019 contrastCache.set(key, cachedValue); 8020 return cachedValue; 8021} 8022function renderRichText({ 8023 html, 8024 dir, 8025 className 8026}, container) { 8027 const fragment = document.createDocumentFragment(); 8028 if (typeof html === "string") { 8029 const p = document.createElement("p"); 8030 p.dir = dir || "auto"; 8031 const lines = html.split(/\r\n?|\n/); 8032 for (let i = 0, ii = lines.length; i < ii; ++i) { 8033 const line = lines[i]; 8034 p.append(document.createTextNode(line)); 8035 if (i < ii - 1) { 8036 p.append(document.createElement("br")); 8037 } 8038 } 8039 fragment.append(p); 8040 } else { 8041 XfaLayer.render({ 8042 xfaHtml: html, 8043 div: fragment, 8044 intent: "richText" 8045 }); 8046 } 8047 fragment.firstElementChild.classList.add("richText", className); 8048 container.append(fragment); 8049} 8050function makePathFromDrawOPS(data) { 8051 const path = new Path2D(); 8052 if (!data) { 8053 return path; 8054 } 8055 for (let i = 0, ii = data.length; i < ii;) { 8056 switch (data[i++]) { 8057 case DrawOPS.moveTo: 8058 path.moveTo(data[i++], data[i++]); 8059 break; 8060 case DrawOPS.lineTo: 8061 path.lineTo(data[i++], data[i++]); 8062 break; 8063 case DrawOPS.curveTo: 8064 path.bezierCurveTo(data[i++], data[i++], data[i++], data[i++], data[i++], data[i++]); 8065 break; 8066 case DrawOPS.quadraticCurveTo: 8067 path.quadraticCurveTo(data[i++], data[i++], data[i++], data[i++]); 8068 break; 8069 case DrawOPS.closePath: 8070 path.closePath(); 8071 break; 8072 default: 8073 warn(`Unrecognized drawing path operator: ${data[i - 1]}`); 8074 break; 8075 } 8076 } 8077 return path; 8078} 8079
vendor: 10,198 bytes, lines 8080-8425
8080// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.take.js 8081var es_iterator_take = __webpack_require__(4972); 8082// EXTERNAL MODULE: ./node_modules/core-js/modules/es.weak-map.get-or-insert.js 8083var es_weak_map_get_or_insert = __webpack_require__(8454); 8084// EXTERNAL MODULE: ./node_modules/core-js/modules/es.weak-map.get-or-insert-computed.js 8085var es_weak_map_get_or_insert_computed = __webpack_require__(9452); 8086// EXTERNAL MODULE: ./node_modules/core-js/modules/web.dom-exception.stack.js 8087var web_dom_exception_stack = __webpack_require__(4979); 8088// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.some.js 8089var es_iterator_some = __webpack_require__(3579); 8090// EXTERNAL MODULE: ./node_modules/core-js/modules/es.json.stringify.js 8091var es_json_stringify = __webpack_require__(3110); 8092// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.drop.js 8093var es_iterator_drop = __webpack_require__(9314); 8094// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.every.js 8095var es_iterator_every = __webpack_require__(1148); 8096// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.find.js 8097var es_iterator_find = __webpack_require__(116); 8098// EXTERNAL MODULE: ./node_modules/core-js/modules/es.json.parse.js 8099var es_json_parse = __webpack_require__(9112); 8100;// ./src/display/editor/toolbar.js 8101 8102class EditorToolbar { 8103 #toolbar = null; 8104 #colorPicker = null; 8105 #editor; 8106 #buttons = null; 8107 #altText = null; 8108 #comment = null; 8109 #commentButtonDivider = null; 8110 #signatureDescriptionButton = null; 8111 static #l10nRemove = null; 8112 constructor(editor) { 8113 this.#editor = editor; 8114 EditorToolbar.#l10nRemove ||= Object.freeze({ 8115 freetext: "pdfjs-editor-remove-freetext-button", 8116 highlight: "pdfjs-editor-remove-highlight-button", 8117 ink: "pdfjs-editor-remove-ink-button", 8118 stamp: "pdfjs-editor-remove-stamp-button", 8119 signature: "pdfjs-editor-remove-signature-button" 8120 }); 8121 } 8122 render() { 8123 const editToolbar = this.#toolbar = document.createElement("div"); 8124 editToolbar.classList.add("editToolbar", "hidden"); 8125 editToolbar.setAttribute("role", "toolbar"); 8126 const signal = this.#editor._uiManager._signal; 8127 if (signal instanceof AbortSignal && !signal.aborted) { 8128 editToolbar.addEventListener("contextmenu", noContextMenu, { 8129 signal 8130 }); 8131 editToolbar.addEventListener("pointerdown", EditorToolbar.#pointerDown, { 8132 signal 8133 }); 8134 } 8135 const buttons = this.#buttons = document.createElement("div"); 8136 buttons.className = "buttons"; 8137 editToolbar.append(buttons); 8138 const position = this.#editor.toolbarPosition; 8139 if (position) { 8140 const { 8141 style 8142 } = editToolbar; 8143 const x = this.#editor._uiManager.direction === "ltr" ? 1 - position[0] : position[0]; 8144 style.insetInlineEnd = `${100 * x}%`; 8145 style.top = `calc(${100 * position[1]}% + var(--editor-toolbar-vert-offset))`; 8146 } 8147 return editToolbar; 8148 } 8149 get div() { 8150 return this.#toolbar; 8151 } 8152 static #pointerDown(e) { 8153 e.stopPropagation(); 8154 } 8155 #focusIn(e) { 8156 this.#editor._focusEventsAllowed = false; 8157 stopEvent(e); 8158 } 8159 #focusOut(e) { 8160 this.#editor._focusEventsAllowed = true; 8161 stopEvent(e); 8162 } 8163 #addListenersToElement(element) { 8164 const signal = this.#editor._uiManager._signal; 8165 if (!(signal instanceof AbortSignal) || signal.aborted) { 8166 return false; 8167 } 8168 element.addEventListener("focusin", this.#focusIn.bind(this), { 8169 capture: true, 8170 signal 8171 }); 8172 element.addEventListener("focusout", this.#focusOut.bind(this), { 8173 capture: true, 8174 signal 8175 }); 8176 element.addEventListener("contextmenu", noContextMenu, { 8177 signal 8178 }); 8179 return true; 8180 } 8181 hide() { 8182 this.#toolbar.classList.add("hidden"); 8183 this.#colorPicker?.hideDropdown(); 8184 } 8185 show() { 8186 this.#toolbar.classList.remove("hidden"); 8187 this.#altText?.shown(); 8188 this.#comment?.shown(); 8189 } 8190 addDeleteButton() { 8191 const { 8192 editorType, 8193 _uiManager 8194 } = this.#editor; 8195 const button = document.createElement("button"); 8196 button.classList.add("basic", "deleteButton"); 8197 button.tabIndex = 0; 8198 button.setAttribute("data-l10n-id", EditorToolbar.#l10nRemove[editorType]); 8199 if (this.#addListenersToElement(button)) { 8200 button.addEventListener("click", e => { 8201 _uiManager.delete(); 8202 }, { 8203 signal: _uiManager._signal 8204 }); 8205 } 8206 this.#buttons.append(button); 8207 } 8208 get #divider() { 8209 const divider = document.createElement("div"); 8210 divider.className = "divider"; 8211 return divider; 8212 } 8213 async addAltText(altText) { 8214 const button = await altText.render(); 8215 this.#addListenersToElement(button); 8216 this.#buttons.append(button, this.#divider); 8217 this.#altText = altText; 8218 } 8219 addComment(comment, beforeElement = null) { 8220 if (this.#comment) { 8221 return; 8222 } 8223 const button = comment.renderForToolbar(); 8224 if (!button) { 8225 return; 8226 } 8227 this.#addListenersToElement(button); 8228 const divider = this.#commentButtonDivider = this.#divider; 8229 if (!beforeElement) { 8230 this.#buttons.append(button, divider); 8231 } else { 8232 this.#buttons.insertBefore(button, beforeElement); 8233 this.#buttons.insertBefore(divider, beforeElement); 8234 } 8235 this.#comment = comment; 8236 comment.toolbar = this; 8237 } 8238 addColorPicker(colorPicker) { 8239 if (this.#colorPicker) { 8240 return; 8241 } 8242 this.#colorPicker = colorPicker; 8243 const button = colorPicker.renderButton(); 8244 this.#addListenersToElement(button); 8245 this.#buttons.append(button, this.#divider); 8246 } 8247 async addEditSignatureButton(signatureManager) { 8248 const button = this.#signatureDescriptionButton = await signatureManager.renderEditButton(this.#editor); 8249 this.#addListenersToElement(button); 8250 this.#buttons.append(button, this.#divider); 8251 } 8252 removeButton(name) { 8253 switch (name) { 8254 case "comment": 8255 this.#comment?.removeToolbarCommentButton(); 8256 this.#comment = null; 8257 this.#commentButtonDivider?.remove(); 8258 this.#commentButtonDivider = null; 8259 break; 8260 } 8261 } 8262 async addButton(name, tool) { 8263 switch (name) { 8264 case "colorPicker": 8265 if (tool) { 8266 this.addColorPicker(tool); 8267 } 8268 break; 8269 case "altText": 8270 if (tool) { 8271 await this.addAltText(tool); 8272 } 8273 break; 8274 case "editSignature": 8275 if (tool) { 8276 await this.addEditSignatureButton(tool); 8277 } 8278 break; 8279 case "delete": 8280 this.addDeleteButton(); 8281 break; 8282 case "comment": 8283 if (tool) { 8284 this.addComment(tool); 8285 } 8286 break; 8287 } 8288 } 8289 async addButtonBefore(name, tool, beforeSelector) { 8290 if (!tool && name === "comment") { 8291 return; 8292 } 8293 const beforeElement = this.#buttons.querySelector(beforeSelector); 8294 if (!beforeElement) { 8295 return; 8296 } 8297 if (name === "comment") { 8298 this.addComment(tool, beforeElement); 8299 } 8300 } 8301 updateEditSignatureButton(description) { 8302 if (this.#signatureDescriptionButton) { 8303 this.#signatureDescriptionButton.title = description; 8304 } 8305 } 8306 remove() { 8307 this.#toolbar.remove(); 8308 this.#colorPicker?.destroy(); 8309 this.#colorPicker = null; 8310 } 8311} 8312class FloatingToolbar { 8313 #buttons = null; 8314 #toolbar = null; 8315 #uiManager; 8316 constructor(uiManager) { 8317 this.#uiManager = uiManager; 8318 } 8319 #render() { 8320 const editToolbar = this.#toolbar = document.createElement("div"); 8321 editToolbar.className = "editToolbar"; 8322 editToolbar.setAttribute("role", "toolbar"); 8323 editToolbar.dir = this.#uiManager.direction; 8324 const signal = this.#uiManager._signal; 8325 if (signal instanceof AbortSignal && !signal.aborted) { 8326 editToolbar.addEventListener("contextmenu", noContextMenu, { 8327 signal 8328 }); 8329 } 8330 const buttons = this.#buttons = document.createElement("div"); 8331 buttons.className = "buttons"; 8332 editToolbar.append(buttons); 8333 if (this.#uiManager.hasCommentManager()) { 8334 this.#makeButton("commentButton", `pdfjs-comment-floating-button`, "pdfjs-comment-floating-button-label", () => { 8335 this.#uiManager.commentSelection("floating_button"); 8336 }); 8337 } 8338 this.#makeButton("highlightButton", `pdfjs-highlight-floating-button1`, "pdfjs-highlight-floating-button-label", () => { 8339 this.#uiManager.highlightSelection("floating_button"); 8340 }); 8341 return editToolbar; 8342 } 8343 #getLastPoint(boxes, isLTR) { 8344 let lastY = 0; 8345 let lastX = 0; 8346 for (const box of boxes) { 8347 const y = box.y + box.height; 8348 if (y < lastY) { 8349 continue; 8350 } 8351 const x = box.x + (isLTR ? box.width : 0); 8352 if (y > lastY) { 8353 lastX = x; 8354 lastY = y; 8355 continue; 8356 } 8357 if (isLTR) { 8358 if (x > lastX) { 8359 lastX = x; 8360 } 8361 } else if (x < lastX) { 8362 lastX = x; 8363 } 8364 } 8365 return [isLTR ? 1 - lastX : lastX, lastY]; 8366 } 8367 show(parent, boxes, isLTR) { 8368 const [x, y] = this.#getLastPoint(boxes, isLTR); 8369 const { 8370 style 8371 } = this.#toolbar ||= this.#render(); 8372 parent.append(this.#toolbar); 8373 style.insetInlineEnd = `${100 * x}%`; 8374 style.top = `calc(${100 * y}% + var(--editor-toolbar-vert-offset))`; 8375 } 8376 hide() { 8377 this.#toolbar.remove(); 8378 } 8379 #makeButton(buttonClass, l10nId, labelL10nId, clickHandler) { 8380 const button = document.createElement("button"); 8381 button.classList.add("basic", buttonClass); 8382 button.tabIndex = 0; 8383 button.setAttribute("data-l10n-id", l10nId); 8384 const span = document.createElement("span"); 8385 button.append(span); 8386 span.className = "visuallyHidden"; 8387 span.setAttribute("data-l10n-id", labelL10nId); 8388 const signal = this.#uiManager._signal; 8389 if (signal instanceof AbortSignal && !signal.aborted) { 8390 button.addEventListener("contextmenu", noContextMenu, { 8391 signal 8392 }); 8393 button.addEventListener("click", clickHandler, { 8394 signal 8395 }); 8396 } 8397 this.#buttons.append(button); 8398 } 8399} 8400 8401;// ./src/shared/internal_evt.js 8402const INTERNAL_EVT = "e4c8307e-183e-4bf3-b76e-4ccdfc3f885a"; 8403const internalOpt = Object.freeze({ 8404 internal: INTERNAL_EVT 8405}); 8406 8407;// ./src/display/editor/tools.js 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425
vendor: 77,581 bytes, lines 8426-11140
8426 8427 8428 8429 8430 8431function bindEvents(obj, element, names) { 8432 for (const name of names) { 8433 element.addEventListener(name, obj[name].bind(obj)); 8434 } 8435} 8436class CurrentPointers { 8437 static #pointerId = NaN; 8438 static #pointerIds = null; 8439 static #moveTimestamp = NaN; 8440 static #pointerType = null; 8441 static initializeAndAddPointerId(pointerId) { 8442 (CurrentPointers.#pointerIds ||= new Set()).add(pointerId); 8443 } 8444 static setPointer(pointerType, pointerId) { 8445 CurrentPointers.#pointerId ||= pointerId; 8446 CurrentPointers.#pointerType ??= pointerType; 8447 } 8448 static setTimeStamp(timeStamp) { 8449 CurrentPointers.#moveTimestamp = timeStamp; 8450 } 8451 static isSamePointerId(pointerId) { 8452 return CurrentPointers.#pointerId === pointerId; 8453 } 8454 static isSamePointerIdOrRemove(pointerId) { 8455 if (CurrentPointers.#pointerId === pointerId) { 8456 return true; 8457 } 8458 CurrentPointers.#pointerIds?.delete(pointerId); 8459 return false; 8460 } 8461 static isSamePointerType(pointerType) { 8462 return CurrentPointers.#pointerType === pointerType; 8463 } 8464 static isInitializedAndDifferentPointerType(pointerType) { 8465 return CurrentPointers.#pointerType !== null && !CurrentPointers.isSamePointerType(pointerType); 8466 } 8467 static isSameTimeStamp(timeStamp) { 8468 return CurrentPointers.#moveTimestamp === timeStamp; 8469 } 8470 static isUsingMultiplePointers() { 8471 return CurrentPointers.#pointerIds?.size >= 1; 8472 } 8473 static clearPointerType() { 8474 CurrentPointers.#pointerType = null; 8475 } 8476 static clearPointerIds() { 8477 CurrentPointers.#pointerId = NaN; 8478 CurrentPointers.#pointerIds = null; 8479 } 8480 static clearTimeStamp() { 8481 CurrentPointers.#moveTimestamp = NaN; 8482 } 8483} 8484class IdManager { 8485 #id = 0; 8486 get id() { 8487 return `${AnnotationEditorPrefix}${this.#id++}`; 8488 } 8489} 8490class ImageManager { 8491 #baseId = getUuid(); 8492 #id = 0; 8493 #cache = null; 8494 static get _isSVGFittingCanvas() { 8495 const svg = `data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 1 1" width="1" height="1" xmlns="${SVG_NS}"><rect width="1" height="1" style="fill:red;"/></svg>`; 8496 const canvas = new OffscreenCanvas(1, 3); 8497 const ctx = canvas.getContext("2d", { 8498 willReadFrequently: true 8499 }); 8500 const image = new Image(); 8501 image.src = svg; 8502 const promise = image.decode().then(() => { 8503 ctx.drawImage(image, 0, 0, 1, 1, 0, 0, 1, 3); 8504 return new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer)[0] === 0; 8505 }); 8506 return shadow(this, "_isSVGFittingCanvas", promise); 8507 } 8508 async #get(key, rawData) { 8509 this.#cache ||= new Map(); 8510 let data = this.#cache.get(key); 8511 if (data === null) { 8512 return null; 8513 } 8514 if (data?.bitmap) { 8515 data.refCounter += 1; 8516 return data; 8517 } 8518 try { 8519 data ||= { 8520 bitmap: null, 8521 id: `image_${this.#baseId}_${this.#id++}`, 8522 refCounter: 0, 8523 isSvg: false 8524 }; 8525 let image; 8526 if (typeof rawData === "string") { 8527 data.url = rawData; 8528 image = await fetchData(rawData, "blob"); 8529 } else if (rawData instanceof File) { 8530 image = data.file = rawData; 8531 } else if (rawData instanceof Blob) { 8532 image = rawData; 8533 } 8534 if (image.type === "image/svg+xml") { 8535 const mustRemoveAspectRatioPromise = ImageManager._isSVGFittingCanvas; 8536 const fileReader = new FileReader(); 8537 const imageElement = new Image(); 8538 const imagePromise = new Promise((resolve, reject) => { 8539 imageElement.onload = () => { 8540 data.bitmap = imageElement; 8541 data.isSvg = true; 8542 resolve(); 8543 }; 8544 fileReader.onload = async () => { 8545 const url = data.svgUrl = fileReader.result; 8546 imageElement.src = (await mustRemoveAspectRatioPromise) ? `${url}#svgView(preserveAspectRatio(none))` : url; 8547 }; 8548 imageElement.onerror = fileReader.onerror = reject; 8549 }); 8550 fileReader.readAsDataURL(image); 8551 await imagePromise; 8552 } else { 8553 data.bitmap = await createImageBitmap(image); 8554 } 8555 data.refCounter = 1; 8556 } catch (e) { 8557 warn(e); 8558 data = null; 8559 } 8560 this.#cache.set(key, data); 8561 if (data) { 8562 this.#cache.set(data.id, data); 8563 } 8564 return data; 8565 } 8566 async getFromFile(file) { 8567 const { 8568 lastModified, 8569 name, 8570 size, 8571 type 8572 } = file; 8573 return this.#get(`${lastModified}_${name}_${size}_${type}`, file); 8574 } 8575 async getFromUrl(url) { 8576 return this.#get(url, url); 8577 } 8578 async getFromBlob(id, blobPromise) { 8579 const blob = await blobPromise; 8580 return this.#get(id, blob); 8581 } 8582 async getFromId(id) { 8583 this.#cache ||= new Map(); 8584 const data = this.#cache.get(id); 8585 if (!data) { 8586 return null; 8587 } 8588 if (data.bitmap) { 8589 data.refCounter += 1; 8590 return data; 8591 } 8592 if (data.file) { 8593 return this.getFromFile(data.file); 8594 } 8595 if (data.blobPromise) { 8596 const { 8597 blobPromise 8598 } = data; 8599 delete data.blobPromise; 8600 return this.getFromBlob(data.id, blobPromise); 8601 } 8602 return this.getFromUrl(data.url); 8603 } 8604 getFromCanvas(id, canvas) { 8605 this.#cache ||= new Map(); 8606 let data = this.#cache.get(id); 8607 if (data?.bitmap) { 8608 data.refCounter += 1; 8609 return data; 8610 } 8611 const offscreen = new OffscreenCanvas(canvas.width, canvas.height); 8612 const ctx = offscreen.getContext("2d"); 8613 ctx.drawImage(canvas, 0, 0); 8614 data = { 8615 bitmap: offscreen.transferToImageBitmap(), 8616 id: `image_${this.#baseId}_${this.#id++}`, 8617 refCounter: 1, 8618 isSvg: false 8619 }; 8620 this.#cache.set(id, data); 8621 this.#cache.set(data.id, data); 8622 return data; 8623 } 8624 getSvgUrl(id) { 8625 const data = this.#cache.get(id); 8626 if (!data?.isSvg) { 8627 return null; 8628 } 8629 return data.svgUrl; 8630 } 8631 deleteId(id) { 8632 this.#cache ||= new Map(); 8633 const data = this.#cache.get(id); 8634 if (!data) { 8635 return; 8636 } 8637 data.refCounter -= 1; 8638 if (data.refCounter !== 0) { 8639 return; 8640 } 8641 const { 8642 bitmap 8643 } = data; 8644 if (!data.url && !data.file) { 8645 const canvas = new OffscreenCanvas(bitmap.width, bitmap.height); 8646 const ctx = canvas.getContext("bitmaprenderer"); 8647 ctx.transferFromImageBitmap(bitmap); 8648 data.blobPromise = canvas.convertToBlob(); 8649 } 8650 bitmap.close?.(); 8651 data.bitmap = null; 8652 } 8653 isValidId(id) { 8654 return id.startsWith(`image_${this.#baseId}_`); 8655 } 8656} 8657class CommandManager { 8658 #commands = []; 8659 #locked = false; 8660 #maxSize; 8661 #position = -1; 8662 constructor(maxSize = 128) { 8663 this.#maxSize = maxSize; 8664 } 8665 add({ 8666 cmd, 8667 undo, 8668 post, 8669 mustExec, 8670 type = NaN, 8671 overwriteIfSameType = false, 8672 keepUndo = false 8673 }) { 8674 if (mustExec) { 8675 cmd(); 8676 } 8677 if (this.#locked) { 8678 return; 8679 } 8680 const save = { 8681 cmd, 8682 undo, 8683 post, 8684 type 8685 }; 8686 if (this.#position === -1) { 8687 if (this.#commands.length > 0) { 8688 this.#commands.length = 0; 8689 } 8690 this.#position = 0; 8691 this.#commands.push(save); 8692 return; 8693 } 8694 if (overwriteIfSameType && this.#commands[this.#position].type === type) { 8695 if (keepUndo) { 8696 save.undo = this.#commands[this.#position].undo; 8697 } 8698 this.#commands[this.#position] = save; 8699 return; 8700 } 8701 const next = this.#position + 1; 8702 if (next === this.#maxSize) { 8703 this.#commands.splice(0, 1); 8704 } else { 8705 this.#position = next; 8706 if (next < this.#commands.length) { 8707 this.#commands.splice(next); 8708 } 8709 } 8710 this.#commands.push(save); 8711 } 8712 undo() { 8713 if (this.#position === -1) { 8714 return; 8715 } 8716 this.#locked = true; 8717 const { 8718 undo, 8719 post 8720 } = this.#commands[this.#position]; 8721 undo(); 8722 post?.(); 8723 this.#locked = false; 8724 this.#position -= 1; 8725 } 8726 redo() { 8727 if (this.#position < this.#commands.length - 1) { 8728 this.#position += 1; 8729 this.#locked = true; 8730 const { 8731 cmd, 8732 post 8733 } = this.#commands[this.#position]; 8734 cmd(); 8735 post?.(); 8736 this.#locked = false; 8737 } 8738 } 8739 hasSomethingToUndo() { 8740 return this.#position !== -1; 8741 } 8742 hasSomethingToRedo() { 8743 return this.#position < this.#commands.length - 1; 8744 } 8745 cleanType(type) { 8746 if (this.#position === -1) { 8747 return; 8748 } 8749 for (let i = this.#position; i >= 0; i--) { 8750 if (this.#commands[i].type !== type) { 8751 this.#commands.splice(i + 1, this.#position - i); 8752 this.#position = i; 8753 return; 8754 } 8755 } 8756 this.#commands.length = 0; 8757 this.#position = -1; 8758 } 8759 destroy() { 8760 this.#commands = null; 8761 } 8762} 8763class KeyboardManager { 8764 static ALT = 0x1; 8765 static CTRL = 0x2; 8766 static META = 0x4; 8767 static SHIFT = 0x8; 8768 constructor(callbacks) { 8769 this.callbacks = new Map(); 8770 const { 8771 isMac 8772 } = FeatureTest.platform; 8773 for (const [keys, callback, options = {}] of callbacks) { 8774 const hasMacOverride = keys.some(k => k.startsWith("mac+")); 8775 for (const key of keys) { 8776 let shortcut = key; 8777 if (hasMacOverride) { 8778 const isMacKey = key.startsWith("mac+"); 8779 if (isMac !== isMacKey) { 8780 continue; 8781 } 8782 if (isMacKey) { 8783 shortcut = key.slice(4); 8784 } 8785 } 8786 const [keyName, modifiers] = KeyboardManager.#parseShortcut(shortcut); 8787 if (keyName === null) { 8788 continue; 8789 } 8790 this.callbacks.getOrInsertComputed(keyName, makeArr).push({ 8791 callback, 8792 options, 8793 modifiers 8794 }); 8795 } 8796 } 8797 } 8798 static #parseShortcut(value) { 8799 let keyPart = null; 8800 let modifiers = 0; 8801 for (let part of value.split("+")) { 8802 part = part.trim(); 8803 if (!part) { 8804 continue; 8805 } 8806 const upper = part.toUpperCase(); 8807 const modifier = KeyboardManager[upper]; 8808 if (modifier) { 8809 modifiers |= modifier; 8810 continue; 8811 } 8812 if (keyPart !== null) { 8813 warn(`KeyboardManager: multiple keys in shortcut "${value}"`); 8814 break; 8815 } 8816 keyPart = upper === "SPACE" ? " " : part; 8817 } 8818 if (keyPart === null) { 8819 warn(`KeyboardManager: no key found in shortcut "${value}"`); 8820 } 8821 return [keyPart, modifiers]; 8822 } 8823 static #codeToKey(code) { 8824 const match = /^(?:Key([A-Z])|(?:Digit|Numpad)(\d))$/.exec(code); 8825 if (!match) { 8826 return null; 8827 } 8828 return match[1]?.toLowerCase() ?? match[2]; 8829 } 8830 exec(self, event) { 8831 let shortcuts = this.callbacks.get(event.key); 8832 if (!shortcuts) { 8833 if (/^[a-z]$/i.test(event.key)) { 8834 return; 8835 } 8836 const fallback = KeyboardManager.#codeToKey(event.code); 8837 if (fallback === null || fallback === event.key) { 8838 return; 8839 } 8840 shortcuts = this.callbacks.get(fallback); 8841 if (!shortcuts) { 8842 return; 8843 } 8844 } 8845 const eventModifiers = (event.altKey ? KeyboardManager.ALT : 0) | (event.ctrlKey ? KeyboardManager.CTRL : 0) | (event.metaKey ? KeyboardManager.META : 0) | (event.shiftKey ? KeyboardManager.SHIFT : 0); 8846 const info = shortcuts.find(shortcut => shortcut.modifiers === eventModifiers); 8847 if (!info) { 8848 return; 8849 } 8850 const { 8851 callback, 8852 options: { 8853 bubbles = false, 8854 args = [], 8855 checker = null 8856 } 8857 } = info; 8858 if (checker && !checker(self, event)) { 8859 return; 8860 } 8861 callback.bind(self, ...args, event)(); 8862 if (!bubbles) { 8863 stopEvent(event); 8864 } 8865 } 8866} 8867class ColorManager { 8868 static _colorsMapping = new Map([["CanvasText", [0, 0, 0]], ["Canvas", [255, 255, 255]]]); 8869 get _colors() { 8870 const colors = new Map([["CanvasText", null], ["Canvas", null]]); 8871 getColorValues(colors); 8872 return shadow(this, "_colors", colors); 8873 } 8874 convert(color) { 8875 const rgb = getRGB(color); 8876 if (!window.matchMedia("(forced-colors: active)").matches) { 8877 return rgb; 8878 } 8879 for (const [name, RGB] of this._colors) { 8880 if (RGB.every((x, i) => x === rgb[i])) { 8881 return ColorManager._colorsMapping.get(name); 8882 } 8883 } 8884 return rgb; 8885 } 8886 getHexCode(name) { 8887 const rgb = this._colors.get(name); 8888 if (!rgb) { 8889 return name; 8890 } 8891 return Util.makeHexColor(...rgb); 8892 } 8893} 8894class AnnotationEditorUIManager { 8895 #abortController = new AbortController(); 8896 #activeEditor = null; 8897 #allEditableAnnotations = null; 8898 #allEditors = new Map(); 8899 #allLayers = new Map(); 8900 #savedAllLayers = null; 8901 #savedEditorsByPage = null; 8902 #altTextManager = null; 8903 #annotationStorage = null; 8904 #changedExistingAnnotations = null; 8905 #commandManager = new CommandManager(); 8906 #commentManager = null; 8907 #copyPasteAC = null; 8908 #currentDrawingSession = null; 8909 #currentPageIndex = 0; 8910 #deletedAnnotationsElementIds = new Set(); 8911 #draggingEditors = null; 8912 #editorTypes = null; 8913 #editorsToRescale = new Set(); 8914 _editorUndoBar = null; 8915 #enableHighlightFloatingButton = false; 8916 #enableUpdatedAddImage = false; 8917 #enableNewAltTextWhenAddingImage = false; 8918 #filterFactory = null; 8919 #focusMainContainerTimeoutId = null; 8920 #focusManagerAC = null; 8921 #highlightColors = null; 8922 #highlightWhenShiftUp = false; 8923 #floatingToolbar = null; 8924 #idManager = new IdManager(); 8925 #isEnabled = false; 8926 #isPointerDown = false; 8927 #isWaiting = false; 8928 #keyboardManagerAC = null; 8929 #lastActiveElement = null; 8930 #mainHighlightColorPicker = null; 8931 #missingCanvases = null; 8932 #mlManager = null; 8933 #mode = AnnotationEditorType.NONE; 8934 #selectedEditors = new Set(); 8935 #selectedTextNode = null; 8936 #signatureManager = null; 8937 #pageColors = null; 8938 #showAllStates = null; 8939 #pdfDocument = null; 8940 #previousStates = { 8941 isEditing: false, 8942 isEmpty: true, 8943 hasSomethingToUndo: false, 8944 hasSomethingToRedo: false, 8945 hasSelectedEditor: false, 8946 hasSelectedText: false 8947 }; 8948 #translation = [0, 0]; 8949 #translationTimeoutId = null; 8950 #container = null; 8951 #viewer = null; 8952 #viewerAlert = null; 8953 #updateModeCapability = null; 8954 static TRANSLATE_SMALL = 1; 8955 static TRANSLATE_BIG = 10; 8956 static get _keyboardManager() { 8957 const proto = AnnotationEditorUIManager.prototype; 8958 const arrowChecker = self => self.#container.contains(document.activeElement) && document.activeElement.tagName !== "BUTTON" && self.hasSomethingToControl(); 8959 const textInputChecker = (_self, { 8960 target: el 8961 }) => { 8962 if (el instanceof HTMLInputElement) { 8963 const { 8964 type 8965 } = el; 8966 return type !== "text" && type !== "number"; 8967 } 8968 return true; 8969 }; 8970 const small = this.TRANSLATE_SMALL; 8971 const big = this.TRANSLATE_BIG; 8972 return shadow(this, "_keyboardManager", new KeyboardManager([[["ctrl+a", "mac+meta+a"], proto.selectAll, { 8973 checker: textInputChecker 8974 }], [["ctrl+z", "mac+meta+z"], proto.undo, { 8975 checker: textInputChecker 8976 }], [["ctrl+y", "ctrl+shift+z", "mac+meta+shift+z", "ctrl+shift+Z", "mac+meta+shift+Z"], proto.redo, { 8977 checker: textInputChecker 8978 }], [["Backspace", "alt+Backspace", "ctrl+Backspace", "shift+Backspace", "mac+Backspace", "mac+alt+Backspace", "mac+ctrl+Backspace", "Delete", "ctrl+Delete", "shift+Delete", "mac+Delete"], proto.delete, { 8979 checker: textInputChecker 8980 }], [["Enter"], proto.addNewEditorFromKeyboard, { 8981 checker: (self, { 8982 target: el 8983 }) => !(el instanceof HTMLButtonElement) && self.#container.contains(el) && !self.isEnterHandled 8984 }], [["Space"], proto.addNewEditorFromKeyboard, { 8985 checker: (self, { 8986 target: el 8987 }) => !(el instanceof HTMLButtonElement) && self.#container.contains(document.activeElement) 8988 }], [["Escape"], proto.unselectAll], [["ArrowLeft"], proto.translateSelectedEditors, { 8989 args: [-small, 0], 8990 checker: arrowChecker 8991 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto.translateSelectedEditors, { 8992 args: [-big, 0], 8993 checker: arrowChecker 8994 }], [["ArrowRight"], proto.translateSelectedEditors, { 8995 args: [small, 0], 8996 checker: arrowChecker 8997 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto.translateSelectedEditors, { 8998 args: [big, 0], 8999 checker: arrowChecker 9000 }], [["ArrowUp"], proto.translateSelectedEditors, { 9001 args: [0, -small], 9002 checker: arrowChecker 9003 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto.translateSelectedEditors, { 9004 args: [0, -big], 9005 checker: arrowChecker 9006 }], [["ArrowDown"], proto.translateSelectedEditors, { 9007 args: [0, small], 9008 checker: arrowChecker 9009 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto.translateSelectedEditors, { 9010 args: [0, big], 9011 checker: arrowChecker 9012 }]])); 9013 } 9014 constructor(container, viewer, viewerAlert, altTextManager, commentManager, signatureManager, eventBus, pdfDocument, pageColors, highlightColors, enableHighlightFloatingButton, enableUpdatedAddImage, enableNewAltTextWhenAddingImage, mlManager, editorUndoBar, supportsPinchToZoom) { 9015 const signal = this._signal = this.#abortController.signal; 9016 this.#container = container; 9017 this.#viewer = viewer; 9018 this.#viewerAlert = viewerAlert; 9019 this.#altTextManager = altTextManager; 9020 this.#commentManager = commentManager; 9021 this.#signatureManager = signatureManager; 9022 this.#pdfDocument = pdfDocument; 9023 this._eventBus = eventBus; 9024 const evtOpts = { 9025 signal, 9026 ...internalOpt 9027 }; 9028 eventBus.on("editingaction", this.onEditingAction.bind(this), evtOpts); 9029 eventBus.on("pagechanging", this.onPageChanging.bind(this), evtOpts); 9030 eventBus.on("scalechanging", this.onScaleChanging.bind(this), evtOpts); 9031 eventBus.on("rotationchanging", this.onRotationChanging.bind(this), evtOpts); 9032 eventBus.on("setpreference", this.onSetPreference.bind(this), evtOpts); 9033 eventBus.on("switchannotationeditorparams", evt => this.updateParams(evt.type, evt.value), evtOpts); 9034 window.addEventListener("pointerdown", () => { 9035 this.#isPointerDown = true; 9036 }, { 9037 capture: true, 9038 signal 9039 }); 9040 window.addEventListener("pointerup", () => { 9041 this.#isPointerDown = false; 9042 }, { 9043 capture: true, 9044 signal 9045 }); 9046 window.addEventListener("beforeunload", this.endCurrentEditing.bind(this), { 9047 capture: true, 9048 signal 9049 }); 9050 this.#addSelectionListener(); 9051 this.#addDragAndDropListeners(); 9052 this.#addKeyboardManager(); 9053 this.#annotationStorage = pdfDocument.annotationStorage; 9054 this.#filterFactory = pdfDocument.filterFactory; 9055 this.#pageColors = pageColors; 9056 this.#highlightColors = highlightColors || null; 9057 this.#enableHighlightFloatingButton = enableHighlightFloatingButton; 9058 this.#enableUpdatedAddImage = enableUpdatedAddImage; 9059 this.#enableNewAltTextWhenAddingImage = enableNewAltTextWhenAddingImage; 9060 this.#mlManager = mlManager || null; 9061 this.viewParameters = { 9062 realScale: PixelsPerInch.PDF_TO_CSS_UNITS, 9063 rotation: 0 9064 }; 9065 this.isShiftKeyDown = false; 9066 this._editorUndoBar = editorUndoBar || null; 9067 this._supportsPinchToZoom = supportsPinchToZoom !== false; 9068 commentManager?.setSidebarUiManager(this); 9069 } 9070 destroy() { 9071 this.#updateModeCapability?.resolve(); 9072 this.#updateModeCapability = null; 9073 this.#abortController?.abort(); 9074 this.#abortController = null; 9075 this._signal = null; 9076 for (const layer of this.#allLayers.values()) { 9077 layer.destroy(); 9078 } 9079 this.#allLayers.clear(); 9080 this.#allEditors.clear(); 9081 this.#editorsToRescale.clear(); 9082 this.#missingCanvases?.clear(); 9083 this.#activeEditor = null; 9084 this.#selectedEditors.clear(); 9085 this.#commandManager.destroy(); 9086 this.#altTextManager?.destroy(); 9087 this.#commentManager?.destroy(); 9088 this.#signatureManager?.destroy(); 9089 this.#floatingToolbar?.hide(); 9090 this.#floatingToolbar = null; 9091 this.#mainHighlightColorPicker?.destroy(); 9092 this.#mainHighlightColorPicker = null; 9093 this.#allEditableAnnotations = null; 9094 if (this.#focusMainContainerTimeoutId) { 9095 clearTimeout(this.#focusMainContainerTimeoutId); 9096 this.#focusMainContainerTimeoutId = null; 9097 } 9098 if (this.#translationTimeoutId) { 9099 clearTimeout(this.#translationTimeoutId); 9100 this.#translationTimeoutId = null; 9101 } 9102 this._editorUndoBar?.destroy(); 9103 this.#pdfDocument = null; 9104 } 9105 combinedSignal(ac) { 9106 return AbortSignal.any([this._signal, ac.signal]); 9107 } 9108 get mlManager() { 9109 return this.#mlManager; 9110 } 9111 get useNewAltTextFlow() { 9112 return this.#enableUpdatedAddImage; 9113 } 9114 get useNewAltTextWhenAddingImage() { 9115 return this.#enableNewAltTextWhenAddingImage; 9116 } 9117 get hcmFilter() { 9118 return shadow(this, "hcmFilter", this.#pageColors ? this.#filterFactory.addHCMFilter(this.#pageColors.foreground, this.#pageColors.background) : "none"); 9119 } 9120 get direction() { 9121 return shadow(this, "direction", getComputedStyle(this.#container).direction); 9122 } 9123 get _highlightColors() { 9124 return shadow(this, "_highlightColors", this.#highlightColors ? new Map(this.#highlightColors.split(",").map(pair => { 9125 pair = pair.split("=").map(x => x.trim()); 9126 pair[1] = pair[1].toUpperCase(); 9127 return pair; 9128 })) : null); 9129 } 9130 get highlightColors() { 9131 const { 9132 _highlightColors 9133 } = this; 9134 if (!_highlightColors) { 9135 return shadow(this, "highlightColors", null); 9136 } 9137 const map = new Map(); 9138 const hasHCM = !!this.#pageColors; 9139 for (const [name, color] of _highlightColors) { 9140 const isNameForHCM = name.endsWith("_HCM"); 9141 if (hasHCM && isNameForHCM) { 9142 map.set(name.replace("_HCM", ""), color); 9143 continue; 9144 } 9145 if (!hasHCM && !isNameForHCM) { 9146 map.set(name, color); 9147 } 9148 } 9149 return shadow(this, "highlightColors", map); 9150 } 9151 get highlightColorNames() { 9152 return shadow(this, "highlightColorNames", this.highlightColors ? new Map(Array.from(this.highlightColors, e => e.reverse())) : null); 9153 } 9154 getNonHCMColor(color) { 9155 if (!this._highlightColors) { 9156 return color; 9157 } 9158 const colorName = this.highlightColorNames.get(color); 9159 return this._highlightColors.get(colorName) || color; 9160 } 9161 getNonHCMColorName(color) { 9162 return this.highlightColorNames.get(color) || color; 9163 } 9164 setCurrentDrawingSession(layer) { 9165 if (layer) { 9166 this.unselectAll(); 9167 this.disableUserSelect(true); 9168 } else { 9169 this.disableUserSelect(false); 9170 } 9171 this.#currentDrawingSession = layer; 9172 } 9173 setMainHighlightColorPicker(colorPicker) { 9174 this.#mainHighlightColorPicker = colorPicker; 9175 } 9176 editAltText(editor, firstTime = false) { 9177 this.#altTextManager?.editAltText(this, editor, firstTime); 9178 } 9179 hasCommentManager() { 9180 return !!this.#commentManager; 9181 } 9182 editComment(editor, posX, posY, options) { 9183 this.#commentManager?.showDialog(this, editor, posX, posY, options); 9184 } 9185 selectComment(pageIndex, uid) { 9186 const layer = this.#allLayers.get(pageIndex); 9187 const editor = layer?.getEditorByUID(uid); 9188 editor?.toggleComment(true, true); 9189 } 9190 updateComment(editor) { 9191 this.#commentManager?.updateComment(editor.getData()); 9192 } 9193 updatePopupColor(editor) { 9194 this.#commentManager?.updatePopupColor(editor); 9195 } 9196 removeComment(editor) { 9197 this.#commentManager?.removeComments([editor.uid]); 9198 } 9199 deleteComment(editor, savedData) { 9200 const undo = () => { 9201 editor.comment = savedData; 9202 }; 9203 const cmd = () => { 9204 this._editorUndoBar?.show(undo, "comment"); 9205 this.toggleComment(null); 9206 editor.comment = null; 9207 }; 9208 this.addCommands({ 9209 cmd, 9210 undo, 9211 mustExec: true 9212 }); 9213 } 9214 toggleComment(editor, isSelected, visibility = undefined) { 9215 this.#commentManager?.toggleCommentPopup(editor, isSelected, visibility); 9216 } 9217 makeCommentColor(color, opacity) { 9218 return color && this.#commentManager?.makeCommentColor(color, opacity) || null; 9219 } 9220 getCommentDialogElement() { 9221 return this.#commentManager?.dialogElement || null; 9222 } 9223 async waitForEditorsRendered(pageNumber) { 9224 if (this.#allLayers.has(pageNumber - 1)) { 9225 return; 9226 } 9227 const { 9228 resolve, 9229 promise 9230 } = Promise.withResolvers(); 9231 const onEditorsRendered = evt => { 9232 if (evt.pageNumber === pageNumber) { 9233 this._eventBus.off("editorsrendered", onEditorsRendered); 9234 resolve(); 9235 } 9236 }; 9237 this._eventBus.on("editorsrendered", onEditorsRendered, internalOpt); 9238 await promise; 9239 } 9240 getSignature(editor) { 9241 this.#signatureManager?.getSignature({ 9242 uiManager: this, 9243 editor 9244 }); 9245 } 9246 get signatureManager() { 9247 return this.#signatureManager; 9248 } 9249 switchToMode(mode, callback) { 9250 this._eventBus.on("annotationeditormodechanged", callback, { 9251 once: true, 9252 signal: this._signal, 9253 ...internalOpt 9254 }); 9255 this._eventBus.dispatch("showannotationeditorui", { 9256 source: this, 9257 mode 9258 }); 9259 } 9260 setPreference(name, value) { 9261 this._eventBus.dispatch("setpreference", { 9262 source: this, 9263 name, 9264 value 9265 }); 9266 } 9267 onSetPreference({ 9268 name, 9269 value 9270 }) { 9271 switch (name) { 9272 case "enableNewAltTextWhenAddingImage": 9273 this.#enableNewAltTextWhenAddingImage = value; 9274 break; 9275 } 9276 } 9277 onPageChanging({ 9278 pageNumber 9279 }) { 9280 this.#currentPageIndex = pageNumber - 1; 9281 } 9282 deletePage(id) { 9283 for (const editor of this.getEditors(id)) { 9284 editor.remove(); 9285 } 9286 this.#allLayers.delete(id); 9287 if (this.#currentPageIndex === id) { 9288 this.#currentPageIndex = 0; 9289 } 9290 } 9291 focusMainContainer() { 9292 this.#container.focus(); 9293 } 9294 findParent(x, y) { 9295 for (const layer of this.#allLayers.values()) { 9296 const { 9297 x: layerX, 9298 y: layerY, 9299 width, 9300 height 9301 } = layer.div.getBoundingClientRect(); 9302 if (x >= layerX && x <= layerX + width && y >= layerY && y <= layerY + height) { 9303 return layer; 9304 } 9305 } 9306 return null; 9307 } 9308 disableUserSelect(value = false) { 9309 this.#viewer.classList.toggle("noUserSelect", value); 9310 } 9311 addShouldRescale(editor) { 9312 this.#editorsToRescale.add(editor); 9313 } 9314 removeShouldRescale(editor) { 9315 this.#editorsToRescale.delete(editor); 9316 } 9317 onScaleChanging({ 9318 scale 9319 }) { 9320 this.commitOrRemove(); 9321 this.viewParameters.realScale = scale * PixelsPerInch.PDF_TO_CSS_UNITS; 9322 for (const editor of this.#editorsToRescale) { 9323 editor.onScaleChanging(); 9324 } 9325 this.#currentDrawingSession?.onScaleChanging(); 9326 } 9327 onRotationChanging({ 9328 pagesRotation 9329 }) { 9330 this.commitOrRemove(); 9331 this.viewParameters.rotation = pagesRotation; 9332 } 9333 #getAnchorElementForSelection({ 9334 anchorNode 9335 }) { 9336 return anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode; 9337 } 9338 #getLayerForTextLayer(textLayer) { 9339 const { 9340 currentLayer 9341 } = this; 9342 if (currentLayer.hasTextLayer(textLayer)) { 9343 return currentLayer; 9344 } 9345 for (const layer of this.#allLayers.values()) { 9346 if (layer.hasTextLayer(textLayer)) { 9347 return layer; 9348 } 9349 } 9350 return null; 9351 } 9352 highlightSelection(methodOfCreation = "", comment = false) { 9353 const selection = document.getSelection(); 9354 if (!selection || selection.isCollapsed) { 9355 return; 9356 } 9357 const { 9358 anchorNode, 9359 anchorOffset, 9360 focusNode, 9361 focusOffset 9362 } = selection; 9363 const text = selection.toString(); 9364 const anchorElement = this.#getAnchorElementForSelection(selection); 9365 const textLayer = anchorElement.closest(".textLayer"); 9366 const boxes = this.getSelectionBoxes(textLayer); 9367 if (!boxes) { 9368 return; 9369 } 9370 selection.empty(); 9371 const layer = this.#getLayerForTextLayer(textLayer); 9372 const isNoneMode = this.#mode === AnnotationEditorType.NONE; 9373 const callback = () => { 9374 const editor = layer?.createAndAddNewEditor({ 9375 x: 0, 9376 y: 0 9377 }, false, { 9378 methodOfCreation, 9379 boxes, 9380 anchorNode, 9381 anchorOffset, 9382 focusNode, 9383 focusOffset, 9384 text 9385 }); 9386 if (isNoneMode) { 9387 this.showAllEditors("highlight", true, true); 9388 } 9389 if (comment) { 9390 editor?.editComment(); 9391 } 9392 }; 9393 if (isNoneMode) { 9394 this.switchToMode(AnnotationEditorType.HIGHLIGHT, callback); 9395 return; 9396 } 9397 callback(); 9398 } 9399 commentSelection(methodOfCreation = "") { 9400 this.highlightSelection(methodOfCreation, true); 9401 } 9402 endCurrentEditing() { 9403 this.commitOrRemove(); 9404 this.currentLayer?.endDrawingSession(false); 9405 } 9406 #displayFloatingToolbar() { 9407 const selection = document.getSelection(); 9408 if (!selection || selection.isCollapsed) { 9409 return; 9410 } 9411 const anchorElement = this.#getAnchorElementForSelection(selection); 9412 const textLayer = anchorElement.closest(".textLayer"); 9413 const boxes = this.getSelectionBoxes(textLayer); 9414 if (!boxes) { 9415 return; 9416 } 9417 this.#floatingToolbar ||= new FloatingToolbar(this); 9418 this.#floatingToolbar.show(textLayer, boxes, this.direction === "ltr"); 9419 } 9420 getAndRemoveDataFromAnnotationStorage(annotationId) { 9421 if (!this.#annotationStorage) { 9422 return null; 9423 } 9424 const key = `${AnnotationEditorPrefix}${annotationId}`; 9425 const storedValue = this.#annotationStorage.getRawValue(key); 9426 if (storedValue) { 9427 this.#annotationStorage.remove(key); 9428 } 9429 return storedValue; 9430 } 9431 addToAnnotationStorage(editor) { 9432 if (!editor.isEmpty() && this.#annotationStorage && !this.#annotationStorage.has(editor.id)) { 9433 this.#annotationStorage.setValue(editor.id, editor); 9434 } 9435 } 9436 a11yAlert(messageId, args = null) { 9437 const viewerAlert = this.#viewerAlert; 9438 if (!viewerAlert) { 9439 return; 9440 } 9441 viewerAlert.setAttribute("data-l10n-id", messageId); 9442 if (args) { 9443 viewerAlert.setAttribute("data-l10n-args", JSON.stringify(args)); 9444 } else { 9445 viewerAlert.removeAttribute("data-l10n-args"); 9446 } 9447 } 9448 #selectionChange() { 9449 const selection = document.getSelection(); 9450 if (!selection || selection.isCollapsed) { 9451 if (this.#selectedTextNode) { 9452 this.#floatingToolbar?.hide(); 9453 this.#selectedTextNode = null; 9454 this.#dispatchUpdateStates({ 9455 hasSelectedText: false 9456 }); 9457 } 9458 return; 9459 } 9460 const { 9461 anchorNode 9462 } = selection; 9463 if (anchorNode === this.#selectedTextNode) { 9464 return; 9465 } 9466 const anchorElement = this.#getAnchorElementForSelection(selection); 9467 const textLayer = anchorElement.closest(".textLayer"); 9468 if (!textLayer) { 9469 if (this.#selectedTextNode) { 9470 this.#floatingToolbar?.hide(); 9471 this.#selectedTextNode = null; 9472 this.#dispatchUpdateStates({ 9473 hasSelectedText: false 9474 }); 9475 } 9476 return; 9477 } 9478 this.#floatingToolbar?.hide(); 9479 this.#selectedTextNode = anchorNode; 9480 this.#dispatchUpdateStates({ 9481 hasSelectedText: true 9482 }); 9483 if (this.#mode !== AnnotationEditorType.HIGHLIGHT && this.#mode !== AnnotationEditorType.NONE) { 9484 return; 9485 } 9486 if (this.#mode === AnnotationEditorType.HIGHLIGHT) { 9487 this.showAllEditors("highlight", true, true); 9488 } 9489 this.#highlightWhenShiftUp = this.isShiftKeyDown; 9490 if (!this.isShiftKeyDown) { 9491 const activeLayer = this.#mode === AnnotationEditorType.HIGHLIGHT ? this.#getLayerForTextLayer(textLayer) : null; 9492 activeLayer?.toggleDrawing(); 9493 if (this.#isPointerDown) { 9494 const ac = new AbortController(); 9495 const signal = this.combinedSignal(ac); 9496 const pointerup = e => { 9497 if (e.type === "pointerup" && e.button !== 0) { 9498 return; 9499 } 9500 ac.abort(); 9501 activeLayer?.toggleDrawing(true); 9502 if (e.type === "pointerup") { 9503 this.#onSelectEnd("main_toolbar"); 9504 } 9505 }; 9506 window.addEventListener("pointerup", pointerup, { 9507 signal 9508 }); 9509 window.addEventListener("blur", pointerup, { 9510 signal 9511 }); 9512 } else { 9513 activeLayer?.toggleDrawing(true); 9514 this.#onSelectEnd("main_toolbar"); 9515 } 9516 } 9517 } 9518 #onSelectEnd(methodOfCreation = "") { 9519 if (this.#mode === AnnotationEditorType.HIGHLIGHT) { 9520 this.highlightSelection(methodOfCreation); 9521 } else if (this.#enableHighlightFloatingButton) { 9522 this.#displayFloatingToolbar(); 9523 } 9524 } 9525 #addSelectionListener() { 9526 document.addEventListener("selectionchange", this.#selectionChange.bind(this), { 9527 signal: this._signal 9528 }); 9529 } 9530 #addFocusManager() { 9531 if (this.#focusManagerAC) { 9532 return; 9533 } 9534 this.#focusManagerAC = new AbortController(); 9535 const signal = this.combinedSignal(this.#focusManagerAC); 9536 window.addEventListener("focus", this.focus.bind(this), { 9537 signal 9538 }); 9539 window.addEventListener("blur", this.blur.bind(this), { 9540 signal 9541 }); 9542 } 9543 #removeFocusManager() { 9544 this.#focusManagerAC?.abort(); 9545 this.#focusManagerAC = null; 9546 } 9547 blur() { 9548 this.isShiftKeyDown = false; 9549 if (this.#highlightWhenShiftUp) { 9550 this.#highlightWhenShiftUp = false; 9551 this.#onSelectEnd("main_toolbar"); 9552 } 9553 if (!this.hasSelection) { 9554 return; 9555 } 9556 const { 9557 activeElement 9558 } = document; 9559 for (const editor of this.#selectedEditors) { 9560 if (editor.div.contains(activeElement)) { 9561 this.#lastActiveElement = [editor, activeElement]; 9562 editor._focusEventsAllowed = false; 9563 break; 9564 } 9565 } 9566 } 9567 focus() { 9568 if (!this.#lastActiveElement) { 9569 return; 9570 } 9571 const [lastEditor, lastActiveElement] = this.#lastActiveElement; 9572 this.#lastActiveElement = null; 9573 lastActiveElement.addEventListener("focusin", () => { 9574 lastEditor._focusEventsAllowed = true; 9575 }, { 9576 once: true, 9577 signal: this._signal 9578 }); 9579 lastActiveElement.focus(); 9580 } 9581 #addKeyboardManager() { 9582 if (this.#keyboardManagerAC) { 9583 return; 9584 } 9585 this.#keyboardManagerAC = new AbortController(); 9586 const signal = this.combinedSignal(this.#keyboardManagerAC); 9587 window.addEventListener("keydown", this.keydown.bind(this), { 9588 signal 9589 }); 9590 window.addEventListener("keyup", this.keyup.bind(this), { 9591 signal 9592 }); 9593 } 9594 #removeKeyboardManager() { 9595 this.#keyboardManagerAC?.abort(); 9596 this.#keyboardManagerAC = null; 9597 } 9598 #addCopyPasteListeners() { 9599 if (this.#copyPasteAC) { 9600 return; 9601 } 9602 this.#copyPasteAC = new AbortController(); 9603 const signal = this.combinedSignal(this.#copyPasteAC); 9604 document.addEventListener("copy", this.copy.bind(this), { 9605 signal 9606 }); 9607 document.addEventListener("cut", this.cut.bind(this), { 9608 signal 9609 }); 9610 document.addEventListener("paste", this.paste.bind(this), { 9611 signal 9612 }); 9613 } 9614 #removeCopyPasteListeners() { 9615 this.#copyPasteAC?.abort(); 9616 this.#copyPasteAC = null; 9617 } 9618 #addDragAndDropListeners() { 9619 const signal = this._signal; 9620 document.addEventListener("dragover", this.dragOver.bind(this), { 9621 signal 9622 }); 9623 document.addEventListener("drop", this.drop.bind(this), { 9624 signal 9625 }); 9626 } 9627 addEditListeners() { 9628 this.#addKeyboardManager(); 9629 this.setEditingState(true); 9630 } 9631 removeEditListeners() { 9632 this.#removeKeyboardManager(); 9633 this.setEditingState(false); 9634 } 9635 dragOver(event) { 9636 for (const { 9637 type 9638 } of event.dataTransfer.items) { 9639 for (const editorType of this.#editorTypes) { 9640 if (editorType.isHandlingMimeForPasting(type)) { 9641 event.dataTransfer.dropEffect = "copy"; 9642 event.preventDefault(); 9643 return; 9644 } 9645 } 9646 } 9647 } 9648 drop(event) { 9649 for (const item of event.dataTransfer.items) { 9650 for (const editorType of this.#editorTypes) { 9651 if (editorType.isHandlingMimeForPasting(item.type)) { 9652 editorType.paste(item, this.currentLayer); 9653 event.preventDefault(); 9654 return; 9655 } 9656 } 9657 } 9658 } 9659 copy(event) { 9660 event.preventDefault(); 9661 this.#activeEditor?.commitOrRemove(); 9662 if (!this.hasSelection) { 9663 return; 9664 } 9665 const editors = []; 9666 for (const editor of this.#selectedEditors) { 9667 const serialized = editor.serialize(true); 9668 if (serialized) { 9669 editors.push(serialized); 9670 } 9671 } 9672 if (editors.length === 0) { 9673 return; 9674 } 9675 event.clipboardData.setData("application/pdfjs", JSON.stringify(editors)); 9676 } 9677 cut(event) { 9678 this.copy(event); 9679 this.delete(); 9680 } 9681 async paste(event) { 9682 event.preventDefault(); 9683 const { 9684 clipboardData 9685 } = event; 9686 for (const item of clipboardData.items) { 9687 for (const editorType of this.#editorTypes) { 9688 if (editorType.isHandlingMimeForPasting(item.type)) { 9689 editorType.paste(item, this.currentLayer); 9690 return; 9691 } 9692 } 9693 } 9694 let data = clipboardData.getData("application/pdfjs"); 9695 if (!data) { 9696 return; 9697 } 9698 try { 9699 data = JSON.parse(data); 9700 } catch (ex) { 9701 warn(`paste: "${ex.message}".`); 9702 return; 9703 } 9704 if (!Array.isArray(data)) { 9705 return; 9706 } 9707 this.unselectAll(); 9708 const layer = this.currentLayer; 9709 try { 9710 const newEditors = []; 9711 for (const editor of data) { 9712 const deserializedEditor = await layer.deserialize(editor); 9713 if (!deserializedEditor) { 9714 return; 9715 } 9716 newEditors.push(deserializedEditor); 9717 } 9718 const cmd = () => { 9719 for (const editor of newEditors) { 9720 this.#addEditorToLayer(editor); 9721 } 9722 this.#selectEditors(newEditors); 9723 }; 9724 const undo = () => { 9725 for (const editor of newEditors) { 9726 editor.remove(); 9727 } 9728 }; 9729 this.addCommands({ 9730 cmd, 9731 undo, 9732 mustExec: true 9733 }); 9734 } catch (ex) { 9735 warn(`paste: "${ex.message}".`); 9736 } 9737 } 9738 keydown(event) { 9739 if (!this.isShiftKeyDown && event.key === "Shift") { 9740 this.isShiftKeyDown = true; 9741 } 9742 if (this.#mode !== AnnotationEditorType.NONE && !this.isEditorHandlingKeyboard) { 9743 AnnotationEditorUIManager._keyboardManager.exec(this, event); 9744 } 9745 } 9746 keyup(event) { 9747 if (this.isShiftKeyDown && event.key === "Shift") { 9748 this.isShiftKeyDown = false; 9749 if (this.#highlightWhenShiftUp) { 9750 this.#highlightWhenShiftUp = false; 9751 this.#onSelectEnd("main_toolbar"); 9752 } 9753 } 9754 } 9755 onEditingAction({ 9756 name 9757 }) { 9758 switch (name) { 9759 case "undo": 9760 case "redo": 9761 case "delete": 9762 case "selectAll": 9763 this[name](); 9764 break; 9765 case "highlightSelection": 9766 this.highlightSelection("context_menu"); 9767 break; 9768 case "commentSelection": 9769 this.commentSelection("context_menu"); 9770 break; 9771 } 9772 } 9773 updatePageIndex(oldPageIndex, newPageIndex) { 9774 for (const editor of this.#savedEditorsByPage.get(oldPageIndex) || []) { 9775 editor.pageIndex = newPageIndex; 9776 } 9777 const layer = this.#savedAllLayers.get(oldPageIndex); 9778 if (layer) { 9779 layer.pageIndex = newPageIndex; 9780 this.#allLayers.set(newPageIndex, layer); 9781 if (this.#isEnabled) { 9782 layer.enable(); 9783 } else { 9784 layer.disable(); 9785 } 9786 } 9787 } 9788 startUpdatePages() { 9789 this.#savedAllLayers = new Map(this.#allLayers); 9790 this.#allLayers.clear(); 9791 const savedEditorsByPage = this.#savedEditorsByPage = new Map(); 9792 const saveEditor = editor => { 9793 savedEditorsByPage.getOrInsertComputed(editor.pageIndex, makeArr).push(editor); 9794 }; 9795 for (const editor of this.#allEditors.values()) { 9796 saveEditor(editor); 9797 } 9798 for (const [id, editor] of this.#annotationStorage) { 9799 if (id.startsWith(AnnotationEditorPrefix) && !this.#allEditors.has(id) && Number.isInteger(editor?.pageIndex)) { 9800 saveEditor(editor); 9801 } 9802 } 9803 } 9804 endUpdatePages() { 9805 this.#savedAllLayers = null; 9806 this.#savedEditorsByPage = null; 9807 } 9808 clonePage(pageIndex, newPageIndex) { 9809 for (const editor of this.getEditors(pageIndex)) { 9810 const serialized = editor.serialize(editor.mode !== AnnotationEditorType.HIGHLIGHT); 9811 if (!serialized) { 9812 continue; 9813 } 9814 serialized.pageIndex = newPageIndex; 9815 serialized.id = this.getId(); 9816 serialized.isClone = true; 9817 delete serialized.popupRef; 9818 this.#annotationStorage.setValue(serialized.id, serialized); 9819 } 9820 } 9821 findClonesForPage(layer) { 9822 const promises = []; 9823 const { 9824 pageIndex 9825 } = layer; 9826 for (const [id, editor] of this.#annotationStorage) { 9827 if (editor.pageIndex === pageIndex && editor.isClone) { 9828 this.#annotationStorage.remove(id); 9829 promises.push(layer.deserialize(editor).then(deserializedEditor => { 9830 if (deserializedEditor) { 9831 deserializedEditor.isClone = true; 9832 layer.addOrRebuild(deserializedEditor); 9833 } 9834 })); 9835 } 9836 } 9837 return Promise.all(promises); 9838 } 9839 #dispatchUpdateStates(details) { 9840 const hasChanged = Object.entries(details).some(([key, value]) => this.#previousStates[key] !== value); 9841 if (hasChanged) { 9842 this._eventBus.dispatch("editingstateschanged", { 9843 source: this, 9844 details: Object.assign(this.#previousStates, details) 9845 }); 9846 if (this.#mode === AnnotationEditorType.HIGHLIGHT && details.hasSelectedEditor === false) { 9847 this.#dispatchUpdateUI([[AnnotationEditorParamsType.HIGHLIGHT_FREE, true]]); 9848 } 9849 } 9850 } 9851 #dispatchUpdateUI(details) { 9852 this._eventBus.dispatch("annotationeditorparamschanged", { 9853 source: this, 9854 details 9855 }); 9856 } 9857 setEditingState(isEditing) { 9858 if (isEditing) { 9859 this.#addFocusManager(); 9860 this.#addCopyPasteListeners(); 9861 this.#dispatchUpdateStates({ 9862 isEditing: this.#mode !== AnnotationEditorType.NONE, 9863 isEmpty: this.#isEmpty(), 9864 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 9865 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 9866 hasSelectedEditor: false 9867 }); 9868 } else { 9869 this.#removeFocusManager(); 9870 this.#removeCopyPasteListeners(); 9871 this.#dispatchUpdateStates({ 9872 isEditing: false 9873 }); 9874 this.disableUserSelect(false); 9875 } 9876 } 9877 registerEditorTypes(types) { 9878 if (this.#editorTypes) { 9879 return; 9880 } 9881 this.#editorTypes = types; 9882 for (const editorType of this.#editorTypes) { 9883 this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); 9884 } 9885 } 9886 getId() { 9887 return this.#idManager.id; 9888 } 9889 get currentLayer() { 9890 return this.#allLayers.get(this.#currentPageIndex); 9891 } 9892 getLayer(pageIndex) { 9893 return this.#allLayers.get(pageIndex); 9894 } 9895 get currentPageIndex() { 9896 return this.#currentPageIndex; 9897 } 9898 addLayer(layer) { 9899 this.#allLayers.set(layer.pageIndex, layer); 9900 if (this.#isEnabled) { 9901 layer.enable(); 9902 } else { 9903 layer.disable(); 9904 } 9905 } 9906 removeLayer(layer) { 9907 this.#allLayers.delete(layer.pageIndex); 9908 } 9909 async updateMode(mode, editId = null, isFromUser = false, isFromKeyboard = false, mustEnterInEditMode = false, editComment = false) { 9910 if (this.#mode === mode) { 9911 return; 9912 } 9913 if (this.#updateModeCapability) { 9914 await this.#updateModeCapability.promise; 9915 if (!this.#updateModeCapability) { 9916 return; 9917 } 9918 } 9919 this.#updateModeCapability = Promise.withResolvers(); 9920 this.#currentDrawingSession?.commitOrRemove(); 9921 if (this.#mode === AnnotationEditorType.POPUP) { 9922 this.#commentManager?.hideSidebar(); 9923 } 9924 this.#commentManager?.destroyPopup(); 9925 this.#mode = mode; 9926 if (mode === AnnotationEditorType.NONE) { 9927 this.setEditingState(false); 9928 this.#disableAll(); 9929 for (const editor of this.#allEditors.values()) { 9930 editor.hideStandaloneCommentButton(); 9931 } 9932 this._editorUndoBar?.hide(); 9933 this.toggleComment(null); 9934 this.#updateModeCapability.resolve(); 9935 return; 9936 } 9937 for (const editor of this.#allEditors.values()) { 9938 editor.addStandaloneCommentButton(); 9939 } 9940 if (mode === AnnotationEditorType.SIGNATURE) { 9941 await this.#signatureManager?.loadSignatures(); 9942 } 9943 if (isFromUser) { 9944 CurrentPointers.clearPointerType(); 9945 } 9946 this.setEditingState(true); 9947 await this.#enableAll(); 9948 this.unselectAll(); 9949 for (const layer of this.#allLayers.values()) { 9950 layer.updateMode(mode); 9951 } 9952 if (mode === AnnotationEditorType.POPUP) { 9953 this.#allEditableAnnotations ||= await this.#pdfDocument.getAnnotationsByType(new Set(this.#editorTypes.map(editorClass => editorClass._editorType))); 9954 const elementIds = new Set(); 9955 const allComments = []; 9956 for (const editor of this.#allEditors.values()) { 9957 const { 9958 annotationElementId, 9959 hasComment, 9960 deleted 9961 } = editor; 9962 if (annotationElementId) { 9963 elementIds.add(annotationElementId); 9964 } 9965 if (hasComment && !deleted) { 9966 allComments.push(editor.getData()); 9967 } 9968 } 9969 for (const annotation of this.#allEditableAnnotations) { 9970 const { 9971 id, 9972 popupRef, 9973 contentsObj 9974 } = annotation; 9975 if (popupRef && contentsObj?.str && !elementIds.has(id) && !this.#deletedAnnotationsElementIds.has(id)) { 9976 allComments.push(annotation); 9977 } 9978 } 9979 this.#commentManager?.showSidebar(allComments); 9980 } 9981 if (!editId) { 9982 if (isFromKeyboard) { 9983 this.addNewEditorFromKeyboard(); 9984 } 9985 this.#updateModeCapability.resolve(); 9986 return; 9987 } 9988 for (const editor of this.#allEditors.values()) { 9989 if (editor.uid === editId) { 9990 this.setSelected(editor); 9991 if (editComment) { 9992 editor.editComment(); 9993 } else if (mustEnterInEditMode) { 9994 editor.enterInEditMode(); 9995 } else { 9996 editor.focus(); 9997 } 9998 } else { 9999 editor.unselect(); 10000 } 10001 } 10002 this.#updateModeCapability.resolve(); 10003 } 10004 addNewEditorFromKeyboard() { 10005 if (this.currentLayer.canCreateNewEmptyEditor()) { 10006 this.currentLayer.addNewEditor(); 10007 } 10008 } 10009 updateToolbar(options) { 10010 if (options.mode === this.#mode) { 10011 return; 10012 } 10013 this._eventBus.dispatch("switchannotationeditormode", { 10014 source: this, 10015 ...options 10016 }); 10017 } 10018 updateParams(type, value) { 10019 if (!this.#editorTypes) { 10020 return; 10021 } 10022 switch (type) { 10023 case AnnotationEditorParamsType.CREATE: 10024 this.currentLayer.addNewEditor(value); 10025 return; 10026 case AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL: 10027 this._eventBus.dispatch("reporttelemetry", { 10028 source: this, 10029 details: { 10030 type: "editing", 10031 data: { 10032 type: "highlight", 10033 action: "toggle_visibility" 10034 } 10035 } 10036 }); 10037 (this.#showAllStates ||= new Map()).set(type, value); 10038 this.showAllEditors("highlight", value); 10039 break; 10040 } 10041 if (this.hasSelection) { 10042 for (const editor of this.#selectedEditors) { 10043 editor.updateParams(type, value); 10044 } 10045 } else { 10046 for (const editorType of this.#editorTypes) { 10047 editorType.updateDefaultParams(type, value); 10048 } 10049 } 10050 } 10051 showAllEditors(type, visible, updateButton = false) { 10052 for (const editor of this.#allEditors.values()) { 10053 if (editor.editorType === type) { 10054 editor.show(visible); 10055 } 10056 } 10057 const state = this.#showAllStates?.get(AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL) ?? true; 10058 if (state !== visible) { 10059 this.#dispatchUpdateUI([[AnnotationEditorParamsType.HIGHLIGHT_SHOW_ALL, visible]]); 10060 } 10061 } 10062 enableWaiting(mustWait = false) { 10063 if (this.#isWaiting === mustWait) { 10064 return; 10065 } 10066 this.#isWaiting = mustWait; 10067 for (const layer of this.#allLayers.values()) { 10068 if (mustWait) { 10069 layer.disableClick(); 10070 } else { 10071 layer.enableClick(); 10072 } 10073 layer.div.classList.toggle("waiting", mustWait); 10074 } 10075 } 10076 async #enableAll() { 10077 if (!this.#isEnabled) { 10078 this.#isEnabled = true; 10079 const promises = []; 10080 for (const layer of this.#allLayers.values()) { 10081 promises.push(layer.enable()); 10082 } 10083 await Promise.all(promises); 10084 for (const editor of this.#allEditors.values()) { 10085 editor.enable(); 10086 } 10087 } 10088 } 10089 #disableAll() { 10090 this.unselectAll(); 10091 if (this.#isEnabled) { 10092 this.#isEnabled = false; 10093 for (const layer of this.#allLayers.values()) { 10094 layer.disable(); 10095 } 10096 for (const editor of this.#allEditors.values()) { 10097 editor.disable(); 10098 } 10099 } 10100 } 10101 *getEditors(pageIndex) { 10102 for (const editor of this.#allEditors.values()) { 10103 if (editor.pageIndex === pageIndex) { 10104 yield editor; 10105 } 10106 } 10107 } 10108 getEditor(id) { 10109 return this.#allEditors.get(id); 10110 } 10111 addEditor(editor) { 10112 this.#allEditors.set(editor.id, editor); 10113 } 10114 removeEditor(editor) { 10115 if (editor.div.contains(document.activeElement)) { 10116 if (this.#focusMainContainerTimeoutId) { 10117 clearTimeout(this.#focusMainContainerTimeoutId); 10118 } 10119 this.#focusMainContainerTimeoutId = setTimeout(() => { 10120 this.focusMainContainer(); 10121 this.#focusMainContainerTimeoutId = null; 10122 }, 0); 10123 } 10124 this.#allEditors.delete(editor.id); 10125 if (editor.annotationElementId) { 10126 this.#missingCanvases?.delete(editor.annotationElementId); 10127 } 10128 this.unselect(editor); 10129 if (!editor.annotationElementId || !this.#deletedAnnotationsElementIds.has(editor.annotationElementId)) { 10130 this.#annotationStorage?.remove(editor.id); 10131 } 10132 } 10133 addDeletedAnnotationElement(editor) { 10134 this.#deletedAnnotationsElementIds.add(editor.annotationElementId); 10135 this.addChangedExistingAnnotation(editor); 10136 editor.deleted = true; 10137 } 10138 isDeletedAnnotationElement(annotationElementId) { 10139 return this.#deletedAnnotationsElementIds.has(annotationElementId); 10140 } 10141 removeDeletedAnnotationElement(editor) { 10142 this.#deletedAnnotationsElementIds.delete(editor.annotationElementId); 10143 this.removeChangedExistingAnnotation(editor); 10144 editor.deleted = false; 10145 } 10146 #addEditorToLayer(editor) { 10147 const layer = this.#allLayers.get(editor.pageIndex); 10148 if (layer) { 10149 layer.addOrRebuild(editor); 10150 } else { 10151 this.addEditor(editor); 10152 this.addToAnnotationStorage(editor); 10153 } 10154 } 10155 setActiveEditor(editor) { 10156 if (this.#activeEditor === editor) { 10157 return; 10158 } 10159 this.#activeEditor = editor; 10160 if (editor) { 10161 this.#dispatchUpdateUI(editor.propertiesToUpdate); 10162 } 10163 } 10164 get #lastSelectedEditor() { 10165 let ed = null; 10166 for (ed of this.#selectedEditors) {} 10167 return ed; 10168 } 10169 updateUI(editor) { 10170 if (this.#lastSelectedEditor === editor) { 10171 this.#dispatchUpdateUI(editor.propertiesToUpdate); 10172 } 10173 } 10174 updateUIForDefaultProperties(editorType) { 10175 this.#dispatchUpdateUI(editorType.defaultPropertiesToUpdate); 10176 } 10177 toggleSelected(editor) { 10178 if (this.#selectedEditors.has(editor)) { 10179 this.#selectedEditors.delete(editor); 10180 editor.unselect(); 10181 this.#dispatchUpdateStates({ 10182 hasSelectedEditor: this.hasSelection 10183 }); 10184 return; 10185 } 10186 this.#selectedEditors.add(editor); 10187 editor.select(); 10188 this.#dispatchUpdateUI(editor.propertiesToUpdate); 10189 this.#dispatchUpdateStates({ 10190 hasSelectedEditor: true 10191 }); 10192 } 10193 setSelected(editor) { 10194 this.updateToolbar({ 10195 mode: editor.mode, 10196 editId: editor.uid 10197 }); 10198 this.#currentDrawingSession?.commitOrRemove(); 10199 for (const ed of this.#selectedEditors) { 10200 if (ed !== editor) { 10201 ed.unselect(); 10202 } 10203 } 10204 this.#commentManager?.destroyPopup(); 10205 this.#selectedEditors.clear(); 10206 this.#selectedEditors.add(editor); 10207 editor.select(); 10208 this.#dispatchUpdateUI(editor.propertiesToUpdate); 10209 this.#dispatchUpdateStates({ 10210 hasSelectedEditor: true 10211 }); 10212 } 10213 get firstSelectedEditor() { 10214 return this.#selectedEditors.values().next().value; 10215 } 10216 unselect(editor) { 10217 editor.unselect(); 10218 this.#selectedEditors.delete(editor); 10219 this.#dispatchUpdateStates({ 10220 hasSelectedEditor: this.hasSelection 10221 }); 10222 } 10223 get hasSelection() { 10224 return this.#selectedEditors.size !== 0; 10225 } 10226 get isEnterHandled() { 10227 return this.#selectedEditors.size === 1 && this.firstSelectedEditor.isEnterHandled; 10228 } 10229 undo() { 10230 this.#commandManager.undo(); 10231 this.#dispatchUpdateStates({ 10232 hasSomethingToUndo: this.#commandManager.hasSomethingToUndo(), 10233 hasSomethingToRedo: true, 10234 isEmpty: this.#isEmpty() 10235 }); 10236 this._editorUndoBar?.hide(); 10237 } 10238 redo() { 10239 this.#commandManager.redo(); 10240 this.#dispatchUpdateStates({ 10241 hasSomethingToUndo: true, 10242 hasSomethingToRedo: this.#commandManager.hasSomethingToRedo(), 10243 isEmpty: this.#isEmpty() 10244 }); 10245 } 10246 addCommands(params) { 10247 this.#commandManager.add(params); 10248 this.#dispatchUpdateStates({ 10249 hasSomethingToUndo: true, 10250 hasSomethingToRedo: false, 10251 isEmpty: this.#isEmpty() 10252 }); 10253 } 10254 cleanUndoStack(type) { 10255 this.#commandManager.cleanType(type); 10256 } 10257 #isEmpty() { 10258 if (this.#allEditors.size === 0) { 10259 return true; 10260 } 10261 if (this.#allEditors.size === 1) { 10262 for (const editor of this.#allEditors.values()) { 10263 return editor.isEmpty(); 10264 } 10265 } 10266 return false; 10267 } 10268 delete() { 10269 this.commitOrRemove(); 10270 const drawingEditor = this.currentLayer?.endDrawingSession(true); 10271 if (!this.hasSelection && !drawingEditor) { 10272 return; 10273 } 10274 const editors = drawingEditor ? [drawingEditor] : [...this.#selectedEditors]; 10275 const cmd = () => { 10276 this._editorUndoBar?.show(undo, editors.length === 1 ? editors[0].editorType : editors.length); 10277 for (const editor of editors) { 10278 editor.remove(); 10279 } 10280 }; 10281 const undo = () => { 10282 for (const editor of editors) { 10283 this.#addEditorToLayer(editor); 10284 } 10285 }; 10286 this.addCommands({ 10287 cmd, 10288 undo, 10289 mustExec: true 10290 }); 10291 } 10292 commitOrRemove() { 10293 this.#activeEditor?.commitOrRemove(); 10294 } 10295 hasSomethingToControl() { 10296 return this.#activeEditor || this.hasSelection; 10297 } 10298 #selectEditors(editors) { 10299 for (const editor of this.#selectedEditors) { 10300 editor.unselect(); 10301 } 10302 this.#selectedEditors.clear(); 10303 for (const editor of editors) { 10304 if (editor.isEmpty()) { 10305 continue; 10306 } 10307 this.#selectedEditors.add(editor); 10308 editor.select(); 10309 } 10310 this.#dispatchUpdateStates({ 10311 hasSelectedEditor: this.hasSelection 10312 }); 10313 } 10314 selectAll() { 10315 for (const editor of this.#selectedEditors) { 10316 editor.commit(); 10317 } 10318 this.#selectEditors(this.#allEditors.values()); 10319 } 10320 unselectAll() { 10321 if (this.#activeEditor) { 10322 this.#activeEditor.commitOrRemove(); 10323 if (this.#mode !== AnnotationEditorType.NONE) { 10324 return; 10325 } 10326 } 10327 if (this.#currentDrawingSession?.commitOrRemove()) { 10328 return; 10329 } 10330 this.#commentManager?.destroyPopup(); 10331 if (!this.hasSelection) { 10332 return; 10333 } 10334 for (const editor of this.#selectedEditors) { 10335 editor.unselect(); 10336 } 10337 this.#selectedEditors.clear(); 10338 this.#dispatchUpdateStates({ 10339 hasSelectedEditor: false 10340 }); 10341 } 10342 translateSelectedEditors(x, y, noCommit = false) { 10343 if (!noCommit) { 10344 this.commitOrRemove(); 10345 } 10346 if (!this.hasSelection) { 10347 return; 10348 } 10349 this.#translation[0] += x; 10350 this.#translation[1] += y; 10351 const [totalX, totalY] = this.#translation; 10352 const editors = [...this.#selectedEditors]; 10353 const TIME_TO_WAIT = 1000; 10354 if (this.#translationTimeoutId) { 10355 clearTimeout(this.#translationTimeoutId); 10356 } 10357 this.#translationTimeoutId = setTimeout(() => { 10358 this.#translationTimeoutId = null; 10359 this.#translation[0] = this.#translation[1] = 0; 10360 this.addCommands({ 10361 cmd: () => { 10362 for (const editor of editors) { 10363 if (this.#allEditors.has(editor.id)) { 10364 editor.translateInPage(totalX, totalY); 10365 editor.translationDone(); 10366 } 10367 } 10368 }, 10369 undo: () => { 10370 for (const editor of editors) { 10371 if (this.#allEditors.has(editor.id)) { 10372 editor.translateInPage(-totalX, -totalY); 10373 editor.translationDone(); 10374 } 10375 } 10376 }, 10377 mustExec: false 10378 }); 10379 }, TIME_TO_WAIT); 10380 for (const editor of editors) { 10381 editor.translateInPage(x, y); 10382 editor.translationDone(); 10383 } 10384 } 10385 setUpDragSession() { 10386 if (!this.hasSelection) { 10387 return; 10388 } 10389 this.disableUserSelect(true); 10390 this.#draggingEditors = new Map(); 10391 for (const editor of this.#selectedEditors) { 10392 this.#draggingEditors.set(editor, { 10393 savedX: editor.x, 10394 savedY: editor.y, 10395 savedPageIndex: editor.pageIndex, 10396 newX: 0, 10397 newY: 0, 10398 newPageIndex: -1 10399 }); 10400 } 10401 } 10402 endDragSession() { 10403 if (!this.#draggingEditors) { 10404 return false; 10405 } 10406 this.disableUserSelect(false); 10407 const map = this.#draggingEditors; 10408 this.#draggingEditors = null; 10409 let mustBeAddedInUndoStack = false; 10410 for (const [{ 10411 x, 10412 y, 10413 pageIndex 10414 }, value] of map) { 10415 value.newX = x; 10416 value.newY = y; 10417 value.newPageIndex = pageIndex; 10418 mustBeAddedInUndoStack ||= x !== value.savedX || y !== value.savedY || pageIndex !== value.savedPageIndex; 10419 } 10420 if (!mustBeAddedInUndoStack) { 10421 return false; 10422 } 10423 const move = (editor, x, y, pageIndex) => { 10424 if (this.#allEditors.has(editor.id)) { 10425 const parent = this.#allLayers.get(pageIndex); 10426 if (parent) { 10427 editor._setParentAndPosition(parent, x, y); 10428 } else { 10429 editor.pageIndex = pageIndex; 10430 editor.x = x; 10431 editor.y = y; 10432 } 10433 } 10434 }; 10435 this.addCommands({ 10436 cmd: () => { 10437 for (const [editor, { 10438 newX, 10439 newY, 10440 newPageIndex 10441 }] of map) { 10442 move(editor, newX, newY, newPageIndex); 10443 } 10444 }, 10445 undo: () => { 10446 for (const [editor, { 10447 savedX, 10448 savedY, 10449 savedPageIndex 10450 }] of map) { 10451 move(editor, savedX, savedY, savedPageIndex); 10452 } 10453 }, 10454 mustExec: true 10455 }); 10456 return true; 10457 } 10458 dragSelectedEditors(tx, ty) { 10459 if (!this.#draggingEditors) { 10460 return; 10461 } 10462 for (const editor of this.#draggingEditors.keys()) { 10463 editor.drag(tx, ty); 10464 } 10465 } 10466 rebuild(editor) { 10467 if (editor.parent === null) { 10468 const parent = this.getLayer(editor.pageIndex); 10469 if (parent) { 10470 parent.changeParent(editor); 10471 parent.addOrRebuild(editor); 10472 } else { 10473 this.addEditor(editor); 10474 this.addToAnnotationStorage(editor); 10475 editor.rebuild(); 10476 } 10477 } else { 10478 editor.parent.addOrRebuild(editor); 10479 } 10480 } 10481 get isEditorHandlingKeyboard() { 10482 return this.getActive()?.shouldGetKeyboardEvents() || this.#selectedEditors.size === 1 && this.firstSelectedEditor.shouldGetKeyboardEvents(); 10483 } 10484 isActive(editor) { 10485 return this.#activeEditor === editor; 10486 } 10487 getActive() { 10488 return this.#activeEditor; 10489 } 10490 getMode() { 10491 return this.#mode; 10492 } 10493 isEditingMode() { 10494 return this.#mode !== AnnotationEditorType.NONE; 10495 } 10496 get imageManager() { 10497 return shadow(this, "imageManager", new ImageManager()); 10498 } 10499 getSelectionBoxes(textLayer) { 10500 if (!textLayer) { 10501 return null; 10502 } 10503 const selection = document.getSelection(); 10504 for (let i = 0, ii = selection.rangeCount; i < ii; i++) { 10505 if (!textLayer.contains(selection.getRangeAt(i).commonAncestorContainer)) { 10506 return null; 10507 } 10508 } 10509 const { 10510 x: layerX, 10511 y: layerY, 10512 width: parentWidth, 10513 height: parentHeight 10514 } = textLayer.getBoundingClientRect(); 10515 let rotator; 10516 switch (textLayer.getAttribute("data-main-rotation")) { 10517 case "90": 10518 rotator = (x, y, w, h) => ({ 10519 x: (y - layerY) / parentHeight, 10520 y: 1 - (x + w - layerX) / parentWidth, 10521 width: h / parentHeight, 10522 height: w / parentWidth 10523 }); 10524 break; 10525 case "180": 10526 rotator = (x, y, w, h) => ({ 10527 x: 1 - (x + w - layerX) / parentWidth, 10528 y: 1 - (y + h - layerY) / parentHeight, 10529 width: w / parentWidth, 10530 height: h / parentHeight 10531 }); 10532 break; 10533 case "270": 10534 rotator = (x, y, w, h) => ({ 10535 x: 1 - (y + h - layerY) / parentHeight, 10536 y: (x - layerX) / parentWidth, 10537 width: h / parentHeight, 10538 height: w / parentWidth 10539 }); 10540 break; 10541 default: 10542 rotator = (x, y, w, h) => ({ 10543 x: (x - layerX) / parentWidth, 10544 y: (y - layerY) / parentHeight, 10545 width: w / parentWidth, 10546 height: h / parentHeight 10547 }); 10548 break; 10549 } 10550 const boxes = []; 10551 for (let i = 0, ii = selection.rangeCount; i < ii; i++) { 10552 const range = selection.getRangeAt(i); 10553 if (range.collapsed) { 10554 continue; 10555 } 10556 for (const { 10557 x, 10558 y, 10559 width, 10560 height 10561 } of range.getClientRects()) { 10562 if (width === 0 || height === 0) { 10563 continue; 10564 } 10565 boxes.push(rotator(x, y, width, height)); 10566 } 10567 } 10568 return boxes.length === 0 ? null : boxes; 10569 } 10570 addChangedExistingAnnotation({ 10571 annotationElementId, 10572 id 10573 }) { 10574 (this.#changedExistingAnnotations ||= new Map()).set(annotationElementId, id); 10575 } 10576 removeChangedExistingAnnotation({ 10577 annotationElementId 10578 }) { 10579 this.#changedExistingAnnotations?.delete(annotationElementId); 10580 } 10581 renderAnnotationElement(annotation) { 10582 const editorId = this.#changedExistingAnnotations?.get(annotation.data.id); 10583 if (!editorId) { 10584 return; 10585 } 10586 const editor = this.#annotationStorage.getRawValue(editorId); 10587 if (!editor) { 10588 return; 10589 } 10590 if (this.#mode === AnnotationEditorType.NONE && !editor.hasBeenModified) { 10591 return; 10592 } 10593 editor.renderAnnotationElement(annotation); 10594 } 10595 setMissingCanvas(annotationId, annotationElementId, canvas) { 10596 const editor = this.#missingCanvases?.get(annotationId); 10597 if (!editor) { 10598 return; 10599 } 10600 editor.setCanvas(annotationElementId, canvas); 10601 this.#missingCanvases.delete(annotationId); 10602 } 10603 addMissingCanvas(annotationId, editor) { 10604 (this.#missingCanvases ||= new Map()).set(annotationId, editor); 10605 } 10606} 10607 10608;// ./src/display/editor/alt_text.js 10609 10610class AltText { 10611 #altText = null; 10612 #altTextDecorative = false; 10613 #altTextButton = null; 10614 #altTextButtonLabel = null; 10615 #altTextTooltip = null; 10616 #altTextTooltipTimeout = null; 10617 #altTextWasFromKeyBoard = false; 10618 #badge = null; 10619 #editor = null; 10620 #guessedText = null; 10621 #textWithDisclaimer = null; 10622 #useNewAltTextFlow = false; 10623 static #l10nNewButton = null; 10624 static _l10n = null; 10625 constructor(editor) { 10626 this.#editor = editor; 10627 this.#useNewAltTextFlow = editor._uiManager.useNewAltTextFlow; 10628 AltText.#l10nNewButton ||= Object.freeze({ 10629 added: "pdfjs-editor-new-alt-text-added-button", 10630 "added-label": "pdfjs-editor-new-alt-text-added-button-label", 10631 missing: "pdfjs-editor-new-alt-text-missing-button", 10632 "missing-label": "pdfjs-editor-new-alt-text-missing-button-label", 10633 review: "pdfjs-editor-new-alt-text-to-review-button", 10634 "review-label": "pdfjs-editor-new-alt-text-to-review-button-label" 10635 }); 10636 } 10637 static initialize(l10n) { 10638 AltText._l10n ??= l10n; 10639 } 10640 async render() { 10641 const altText = this.#altTextButton = document.createElement("button"); 10642 altText.className = "altText"; 10643 altText.tabIndex = "0"; 10644 const label = this.#altTextButtonLabel = document.createElement("span"); 10645 altText.append(label); 10646 if (this.#useNewAltTextFlow) { 10647 altText.classList.add("new"); 10648 altText.setAttribute("data-l10n-id", AltText.#l10nNewButton.missing); 10649 label.setAttribute("data-l10n-id", AltText.#l10nNewButton["missing-label"]); 10650 } else { 10651 altText.setAttribute("data-l10n-id", "pdfjs-editor-alt-text-button"); 10652 label.setAttribute("data-l10n-id", "pdfjs-editor-alt-text-button-label"); 10653 } 10654 const signal = this.#editor._uiManager._signal; 10655 altText.addEventListener("contextmenu", noContextMenu, { 10656 signal 10657 }); 10658 altText.addEventListener("pointerdown", event => event.stopPropagation(), { 10659 signal 10660 }); 10661 const onClick = event => { 10662 event.preventDefault(); 10663 this.#editor._uiManager.editAltText(this.#editor); 10664 if (this.#useNewAltTextFlow) { 10665 this.#editor._reportTelemetry({ 10666 action: "pdfjs.image.alt_text.image_status_label_clicked", 10667 data: { 10668 label: this.#label 10669 } 10670 }); 10671 } 10672 }; 10673 altText.addEventListener("click", onClick, { 10674 capture: true, 10675 signal 10676 }); 10677 altText.addEventListener("keydown", event => { 10678 if (event.target === altText && event.key === "Enter") { 10679 this.#altTextWasFromKeyBoard = true; 10680 onClick(event); 10681 } 10682 }, { 10683 signal 10684 }); 10685 await this.#setState(); 10686 return altText; 10687 } 10688 get #label() { 10689 return this.#altText && "added" || this.#altText === null && this.guessedText && "review" || "missing"; 10690 } 10691 finish() { 10692 if (!this.#altTextButton) { 10693 return; 10694 } 10695 this.#altTextButton.focus({ 10696 focusVisible: this.#altTextWasFromKeyBoard 10697 }); 10698 this.#altTextWasFromKeyBoard = false; 10699 } 10700 isEmpty() { 10701 return this.#useNewAltTextFlow ? this.#altText === null : !this.#altText && !this.#altTextDecorative; 10702 } 10703 hasData() { 10704 return this.#useNewAltTextFlow ? this.#altText !== null || !!this.#guessedText : this.isEmpty(); 10705 } 10706 get guessedText() { 10707 return this.#guessedText; 10708 } 10709 async setGuessedText(guessedText) { 10710 if (this.#altText !== null) { 10711 return; 10712 } 10713 this.#guessedText = guessedText; 10714 this.#textWithDisclaimer = await AltText._l10n.get("pdfjs-editor-new-alt-text-generated-alt-text-with-disclaimer", { 10715 generatedAltText: guessedText 10716 }); 10717 this.#setState(); 10718 } 10719 toggleAltTextBadge(visibility = false) { 10720 if (!this.#useNewAltTextFlow || this.#altText) { 10721 this.#badge?.remove(); 10722 this.#badge = null; 10723 return; 10724 } 10725 if (!this.#badge) { 10726 const badge = this.#badge = document.createElement("div"); 10727 badge.className = "noAltTextBadge"; 10728 this.#editor.div.append(badge); 10729 } 10730 this.#badge.classList.toggle("hidden", !visibility); 10731 } 10732 serialize(isForCopying) { 10733 let altText = this.#altText; 10734 if (!isForCopying && this.#guessedText === altText) { 10735 altText = this.#textWithDisclaimer; 10736 } 10737 return { 10738 altText, 10739 decorative: this.#altTextDecorative, 10740 guessedText: this.#guessedText, 10741 textWithDisclaimer: this.#textWithDisclaimer 10742 }; 10743 } 10744 get data() { 10745 return { 10746 altText: this.#altText, 10747 decorative: this.#altTextDecorative 10748 }; 10749 } 10750 set data({ 10751 altText, 10752 decorative, 10753 guessedText, 10754 textWithDisclaimer, 10755 cancel = false 10756 }) { 10757 if (guessedText) { 10758 this.#guessedText = guessedText; 10759 this.#textWithDisclaimer = textWithDisclaimer; 10760 } 10761 if (this.#altText === altText && this.#altTextDecorative === decorative) { 10762 return; 10763 } 10764 if (!cancel) { 10765 this.#altText = altText; 10766 this.#altTextDecorative = decorative; 10767 } 10768 this.#setState(); 10769 } 10770 toggle(enabled = false) { 10771 if (!this.#altTextButton) { 10772 return; 10773 } 10774 if (!enabled && this.#altTextTooltipTimeout) { 10775 clearTimeout(this.#altTextTooltipTimeout); 10776 this.#altTextTooltipTimeout = null; 10777 } 10778 this.#altTextButton.disabled = !enabled; 10779 } 10780 shown() { 10781 this.#editor._reportTelemetry({ 10782 action: "pdfjs.image.alt_text.image_status_label_displayed", 10783 data: { 10784 label: this.#label 10785 } 10786 }); 10787 } 10788 destroy() { 10789 this.#altTextButton?.remove(); 10790 this.#altTextButton = null; 10791 this.#altTextButtonLabel = null; 10792 this.#altTextTooltip = null; 10793 this.#badge?.remove(); 10794 this.#badge = null; 10795 } 10796 async #setState() { 10797 const button = this.#altTextButton; 10798 if (!button) { 10799 return; 10800 } 10801 if (this.#useNewAltTextFlow) { 10802 button.classList.toggle("done", !!this.#altText); 10803 button.setAttribute("data-l10n-id", AltText.#l10nNewButton[this.#label]); 10804 this.#altTextButtonLabel?.setAttribute("data-l10n-id", AltText.#l10nNewButton[`${this.#label}-label`]); 10805 if (!this.#altText) { 10806 this.#altTextTooltip?.remove(); 10807 return; 10808 } 10809 } else { 10810 if (!this.#altText && !this.#altTextDecorative) { 10811 button.classList.remove("done"); 10812 this.#altTextTooltip?.remove(); 10813 return; 10814 } 10815 button.classList.add("done"); 10816 button.setAttribute("data-l10n-id", "pdfjs-editor-alt-text-edit-button"); 10817 } 10818 let tooltip = this.#altTextTooltip; 10819 if (!tooltip) { 10820 this.#altTextTooltip = tooltip = document.createElement("span"); 10821 tooltip.className = "tooltip"; 10822 tooltip.setAttribute("role", "tooltip"); 10823 tooltip.id = `alt-text-tooltip-${this.#editor.id}`; 10824 const DELAY_TO_SHOW_TOOLTIP = 100; 10825 const signal = this.#editor._uiManager._signal; 10826 signal.addEventListener("abort", () => { 10827 clearTimeout(this.#altTextTooltipTimeout); 10828 this.#altTextTooltipTimeout = null; 10829 }, { 10830 once: true 10831 }); 10832 button.addEventListener("mouseenter", () => { 10833 this.#altTextTooltipTimeout = setTimeout(() => { 10834 this.#altTextTooltipTimeout = null; 10835 this.#altTextTooltip.classList.add("show"); 10836 this.#editor._reportTelemetry({ 10837 action: "alt_text_tooltip" 10838 }); 10839 }, DELAY_TO_SHOW_TOOLTIP); 10840 }, { 10841 signal 10842 }); 10843 button.addEventListener("mouseleave", () => { 10844 if (this.#altTextTooltipTimeout) { 10845 clearTimeout(this.#altTextTooltipTimeout); 10846 this.#altTextTooltipTimeout = null; 10847 } 10848 this.#altTextTooltip?.classList.remove("show"); 10849 }, { 10850 signal 10851 }); 10852 } 10853 if (this.#altTextDecorative) { 10854 tooltip.setAttribute("data-l10n-id", "pdfjs-editor-alt-text-decorative-tooltip"); 10855 } else { 10856 tooltip.removeAttribute("data-l10n-id"); 10857 tooltip.textContent = this.#altText; 10858 } 10859 if (!tooltip.parentNode) { 10860 button.append(tooltip); 10861 } 10862 const element = this.#editor.getElementForAltText(); 10863 element?.setAttribute("aria-describedby", tooltip.id); 10864 } 10865} 10866 10867;// ./src/display/editor/comment.js 10868 10869class Comment { 10870 #commentStandaloneButton = null; 10871 #commentToolbarButton = null; 10872 #commentWasFromKeyBoard = false; 10873 #editor = null; 10874 #initialText = null; 10875 #richText = null; 10876 #text = null; 10877 #date = null; 10878 #deleted = false; 10879 #popupPosition = null; 10880 constructor(editor) { 10881 this.#editor = editor; 10882 } 10883 renderForToolbar() { 10884 const button = this.#commentToolbarButton = document.createElement("button"); 10885 button.className = "comment"; 10886 return this.#render(button, false); 10887 } 10888 renderForStandalone() { 10889 const button = this.#commentStandaloneButton = document.createElement("button"); 10890 button.className = "annotationCommentButton"; 10891 const position = this.#editor.commentButtonPosition; 10892 if (position) { 10893 const { 10894 style 10895 } = button; 10896 style.insetInlineEnd = `calc(${100 * (this.#editor._uiManager.direction === "ltr" ? 1 - position[0] : position[0])}% - var(--comment-button-dim))`; 10897 style.top = `calc(${100 * position[1]}% - var(--comment-button-dim))`; 10898 const color = this.#editor.commentButtonColor; 10899 if (color) { 10900 style.backgroundColor = color; 10901 } 10902 } 10903 return this.#render(button, true); 10904 } 10905 focusButton() { 10906 setTimeout(() => { 10907 (this.#commentStandaloneButton ?? this.#commentToolbarButton)?.focus(); 10908 }, 0); 10909 } 10910 onUpdatedColor() { 10911 if (!this.#commentStandaloneButton) { 10912 return; 10913 } 10914 const color = this.#editor.commentButtonColor; 10915 if (color) { 10916 this.#commentStandaloneButton.style.backgroundColor = color; 10917 } 10918 this.#editor._uiManager.updatePopupColor(this.#editor); 10919 } 10920 get commentButtonWidth() { 10921 return (this.#commentStandaloneButton?.getBoundingClientRect().width ?? 0) / this.#editor.parent.boundingClientRect.width; 10922 } 10923 get commentPopupPositionInLayer() { 10924 if (this.#popupPosition) { 10925 return this.#popupPosition; 10926 } 10927 if (!this.#commentStandaloneButton) { 10928 return null; 10929 } 10930 const { 10931 x, 10932 y, 10933 height 10934 } = this.#commentStandaloneButton.getBoundingClientRect(); 10935 const { 10936 x: parentX, 10937 y: parentY, 10938 width: parentWidth, 10939 height: parentHeight 10940 } = this.#editor.parent.boundingClientRect; 10941 return [(x - parentX) / parentWidth, (y + height - parentY) / parentHeight]; 10942 } 10943 set commentPopupPositionInLayer(pos) { 10944 this.#popupPosition = pos; 10945 } 10946 hasDefaultPopupPosition() { 10947 return this.#popupPosition === null; 10948 } 10949 removeStandaloneCommentButton() { 10950 this.#commentStandaloneButton?.remove(); 10951 this.#commentStandaloneButton = null; 10952 } 10953 removeToolbarCommentButton() { 10954 this.#commentToolbarButton?.remove(); 10955 this.#commentToolbarButton = null; 10956 } 10957 setCommentButtonStates({ 10958 selected, 10959 hasPopup 10960 }) { 10961 if (!this.#commentStandaloneButton) { 10962 return; 10963 } 10964 this.#commentStandaloneButton.classList.toggle("selected", selected); 10965 this.#commentStandaloneButton.ariaExpanded = hasPopup; 10966 } 10967 #render(comment, isStandalone) { 10968 if (!this.#editor._uiManager.hasCommentManager()) { 10969 return null; 10970 } 10971 comment.tabIndex = "0"; 10972 comment.ariaHasPopup = "dialog"; 10973 if (isStandalone) { 10974 comment.ariaControls = "commentPopup"; 10975 comment.setAttribute("data-l10n-id", "pdfjs-show-comment-button"); 10976 } else { 10977 comment.ariaControlsElements = [this.#editor._uiManager.getCommentDialogElement()]; 10978 comment.setAttribute("data-l10n-id", "pdfjs-editor-add-comment-button"); 10979 } 10980 const signal = this.#editor._uiManager._signal; 10981 if (!(signal instanceof AbortSignal) || signal.aborted) { 10982 return comment; 10983 } 10984 comment.addEventListener("contextmenu", noContextMenu, { 10985 signal 10986 }); 10987 if (isStandalone) { 10988 comment.addEventListener("focusin", e => { 10989 this.#editor._focusEventsAllowed = false; 10990 stopEvent(e); 10991 }, { 10992 capture: true, 10993 signal 10994 }); 10995 comment.addEventListener("focusout", e => { 10996 this.#editor._focusEventsAllowed = true; 10997 stopEvent(e); 10998 }, { 10999 capture: true, 11000 signal 11001 }); 11002 } 11003 comment.addEventListener("pointerdown", event => event.stopPropagation(), { 11004 signal 11005 }); 11006 const onClick = event => { 11007 event.preventDefault(); 11008 if (comment === this.#commentToolbarButton) { 11009 this.edit(); 11010 } else { 11011 this.#editor.toggleComment(true); 11012 } 11013 }; 11014 comment.addEventListener("click", onClick, { 11015 capture: true, 11016 signal 11017 }); 11018 comment.addEventListener("keydown", event => { 11019 if (event.target === comment && event.key === "Enter") { 11020 this.#commentWasFromKeyBoard = true; 11021 onClick(event); 11022 } 11023 }, { 11024 signal 11025 }); 11026 comment.addEventListener("pointerenter", () => { 11027 this.#editor.toggleComment(false, true); 11028 }, { 11029 signal 11030 }); 11031 comment.addEventListener("pointerleave", () => { 11032 this.#editor.toggleComment(false, false); 11033 }, { 11034 signal 11035 }); 11036 return comment; 11037 } 11038 edit(options) { 11039 const position = this.commentPopupPositionInLayer; 11040 let posX, posY; 11041 if (position) { 11042 [posX, posY] = position; 11043 } else { 11044 [posX, posY] = this.#editor.commentButtonPosition; 11045 const { 11046 width, 11047 height, 11048 x, 11049 y 11050 } = this.#editor; 11051 posX = x + posX * width; 11052 posY = y + posY * height; 11053 } 11054 const parentDimensions = this.#editor.parent.boundingClientRect; 11055 const { 11056 x: parentX, 11057 y: parentY, 11058 width: parentWidth, 11059 height: parentHeight 11060 } = parentDimensions; 11061 this.#editor._uiManager.editComment(this.#editor, parentX + posX * parentWidth, parentY + posY * parentHeight, { 11062 ...options, 11063 parentDimensions 11064 }); 11065 } 11066 finish() { 11067 if (!this.#commentToolbarButton) { 11068 return; 11069 } 11070 this.#commentToolbarButton.focus({ 11071 focusVisible: this.#commentWasFromKeyBoard 11072 }); 11073 this.#commentWasFromKeyBoard = false; 11074 } 11075 isDeleted() { 11076 return this.#deleted || this.#text === ""; 11077 } 11078 isEmpty() { 11079 return this.#text === null; 11080 } 11081 hasBeenEdited() { 11082 return this.isDeleted() || this.#text !== this.#initialText; 11083 } 11084 serialize() { 11085 return this.data; 11086 } 11087 get data() { 11088 return { 11089 text: this.#text, 11090 richText: this.#richText, 11091 date: this.#date, 11092 deleted: this.isDeleted() 11093 }; 11094 } 11095 set data(text) { 11096 if (text !== this.#text) { 11097 this.#richText = null; 11098 } 11099 if (text === null) { 11100 this.#text = ""; 11101 this.#deleted = true; 11102 return; 11103 } 11104 this.#text = text; 11105 this.#date = new Date(); 11106 this.#deleted = false; 11107 } 11108 restoreData({ 11109 text, 11110 richText, 11111 date 11112 }) { 11113 this.#text = text; 11114 this.#richText = richText; 11115 this.#date = date; 11116 this.#deleted = false; 11117 } 11118 setInitialText(text, richText = null) { 11119 this.#initialText = text; 11120 this.data = text; 11121 this.#date = null; 11122 this.#richText = richText; 11123 } 11124 shown() {} 11125 destroy() { 11126 this.#commentToolbarButton?.remove(); 11127 this.#commentToolbarButton = null; 11128 this.#commentStandaloneButton?.remove(); 11129 this.#commentStandaloneButton = null; 11130 this.#text = ""; 11131 this.#richText = null; 11132 this.#date = null; 11133 this.#editor = null; 11134 this.#commentWasFromKeyBoard = false; 11135 this.#deleted = false; 11136 } 11137} 11138 11139;// ./src/display/touch_manager.js 11140
vendor: 8,287 bytes, lines 11141-11437
11141 11142 11143 11144 11145 11146 11147 11148 11149function preventDefault(evt) { 11150 evt.preventDefault(); 11151} 11152const MIN_TOUCH_SPAN = 1e-4; 11153function stopTouchEvent(evt) { 11154 if (evt.cancelable) { 11155 stopEvent(evt); 11156 return true; 11157 } 11158 evt.stopPropagation(); 11159 return false; 11160} 11161class TouchManager { 11162 #container; 11163 #isPinching = false; 11164 #isPinchingStopped = null; 11165 #isPinchingDisabled; 11166 #onPinchStart; 11167 #onPinching; 11168 #onPinchEnd; 11169 #onPanning; 11170 #ownsGesture = false; 11171 #pointerDownAC = null; 11172 #signal; 11173 #touchIds = new Set(); 11174 #touchInfo = null; 11175 #touchManagerAC; 11176 #touchMoveAC = null; 11177 #unconfirmedPinch = 0; 11178 constructor({ 11179 container, 11180 isPinchingDisabled = null, 11181 isPinchingStopped = null, 11182 onPinchStart = null, 11183 onPinching = null, 11184 onPinchEnd = null, 11185 onPanning = null, 11186 signal 11187 }) { 11188 this.#container = container; 11189 this.#isPinchingStopped = isPinchingStopped; 11190 this.#isPinchingDisabled = isPinchingDisabled; 11191 this.#onPinchStart = onPinchStart; 11192 this.#onPinching = onPinching; 11193 this.#onPinchEnd = onPinchEnd; 11194 this.#onPanning = onPanning; 11195 this.#touchManagerAC = new AbortController(); 11196 this.#signal = AbortSignal.any([signal, this.#touchManagerAC.signal]); 11197 container.addEventListener("touchstart", this.#onTouchStart.bind(this), { 11198 passive: false, 11199 signal: this.#signal 11200 }); 11201 } 11202 get MIN_TOUCH_DISTANCE_TO_PINCH() { 11203 return 35 / OutputScale.pixelRatio; 11204 } 11205 get MIN_TOUCH_DISTANCE_TO_SCALE() { 11206 return 4 / OutputScale.pixelRatio; 11207 } 11208 #onTouchStart(evt) { 11209 if (this.#isPinchingDisabled?.()) { 11210 return; 11211 } 11212 this.#pruneTouchIds(evt); 11213 const touchIds = this.#touchIds; 11214 for (const { 11215 identifier 11216 } of evt.changedTouches) { 11217 touchIds.add(identifier); 11218 } 11219 if (touchIds.size === 1) { 11220 this.#armPointerDown(); 11221 return; 11222 } 11223 if (!this.#touchMoveAC) { 11224 this.#touchMoveAC = new AbortController(); 11225 const signal = AbortSignal.any([this.#signal, this.#touchMoveAC.signal]); 11226 const container = this.#container; 11227 const opt = { 11228 signal, 11229 capture: false, 11230 passive: false 11231 }; 11232 container.addEventListener("touchmove", this.#onTouchMove.bind(this), opt); 11233 const onTouchEnd = this.#onTouchEnd.bind(this); 11234 container.addEventListener("touchend", onTouchEnd, opt); 11235 container.addEventListener("touchcancel", onTouchEnd, opt); 11236 opt.capture = true; 11237 container.addEventListener("pointerdown", stopEvent, opt); 11238 container.addEventListener("pointermove", stopEvent, opt); 11239 container.addEventListener("pointercancel", preventDefault, opt); 11240 container.addEventListener("pointerup", preventDefault, opt); 11241 this.#onPinchStart?.(); 11242 } 11243 this.#ownsGesture = stopTouchEvent(evt); 11244 this.#setTouchInfo(evt); 11245 } 11246 #armPointerDown() { 11247 if (this.#pointerDownAC) { 11248 return; 11249 } 11250 const pointerDownAC = this.#pointerDownAC = new AbortController(); 11251 const signal = AbortSignal.any([this.#signal, pointerDownAC.signal]); 11252 const container = this.#container; 11253 const opts = { 11254 capture: true, 11255 signal, 11256 passive: false 11257 }; 11258 const cancelPointerDown = e => { 11259 if (e.pointerType === "touch") { 11260 this.#pointerDownAC?.abort(); 11261 this.#pointerDownAC = null; 11262 } 11263 }; 11264 container.addEventListener("pointerdown", e => { 11265 if (e.pointerType === "touch") { 11266 stopEvent(e); 11267 cancelPointerDown(e); 11268 } 11269 }, opts); 11270 container.addEventListener("pointerup", cancelPointerDown, opts); 11271 container.addEventListener("pointercancel", cancelPointerDown, opts); 11272 } 11273 #pruneTouchIds(evt) { 11274 const previous = this.#touchIds; 11275 if (previous.size === 0) { 11276 return; 11277 } 11278 const touchIds = this.#touchIds = new Set(); 11279 for (const { 11280 identifier 11281 } of evt.touches) { 11282 if (previous.has(identifier)) { 11283 touchIds.add(identifier); 11284 } 11285 } 11286 } 11287 #getTrackedTouches(evt) { 11288 const touchIds = this.#touchIds; 11289 const touches = []; 11290 for (const touch of evt.touches) { 11291 if (touchIds.has(touch.identifier)) { 11292 touches.push(touch); 11293 } 11294 } 11295 return touches; 11296 } 11297 #setTouchInfo(evt) { 11298 const touches = this.#getTrackedTouches(evt); 11299 if (touches.length !== 2 || this.#isPinchingStopped?.()) { 11300 this.#touchInfo = null; 11301 return; 11302 } 11303 const [touch0, touch1] = touches; 11304 this.#touchInfo = { 11305 touch0X: touch0.screenX, 11306 touch0Y: touch0.screenY, 11307 touch1X: touch1.screenX, 11308 touch1Y: touch1.screenY, 11309 panX: (touch0.clientX + touch1.clientX) / 2, 11310 panY: (touch0.clientY + touch1.clientY) / 2, 11311 screenPanX: (touch0.screenX + touch1.screenX) / 2, 11312 screenPanY: (touch0.screenY + touch1.screenY) / 2 11313 }; 11314 } 11315 #onTouchMove(evt) { 11316 if (!this.#touchInfo) { 11317 return; 11318 } 11319 const touches = this.#getTrackedTouches(evt); 11320 if (touches.length !== 2) { 11321 return; 11322 } 11323 const wasOwned = this.#ownsGesture; 11324 this.#ownsGesture = stopTouchEvent(evt); 11325 if (!this.#ownsGesture) { 11326 return; 11327 } 11328 if (!wasOwned) { 11329 this.#setTouchInfo(evt); 11330 return; 11331 } 11332 const [touch0, touch1] = touches; 11333 const { 11334 screenX: screen0X, 11335 screenY: screen0Y 11336 } = touch0; 11337 const { 11338 screenX: screen1X, 11339 screenY: screen1Y 11340 } = touch1; 11341 const touchInfo = this.#touchInfo; 11342 const { 11343 touch0X: pTouch0X, 11344 touch0Y: pTouch0Y, 11345 touch1X: pTouch1X, 11346 touch1Y: pTouch1Y, 11347 panX: pPanX, 11348 panY: pPanY 11349 } = touchInfo; 11350 const prevGapX = pTouch1X - pTouch0X; 11351 const prevGapY = pTouch1Y - pTouch0Y; 11352 const currGapX = screen1X - screen0X; 11353 const currGapY = screen1Y - screen0Y; 11354 const panX = (touch0.clientX + touch1.clientX) / 2; 11355 const panY = (touch0.clientY + touch1.clientY) / 2; 11356 touchInfo.panX = panX; 11357 touchInfo.panY = panY; 11358 const dx = panX - pPanX; 11359 const dy = panY - pPanY; 11360 const screenPanX = (screen0X + screen1X) / 2; 11361 const screenPanY = (screen0Y + screen1Y) / 2; 11362 const translation = Math.hypot(screenPanX - touchInfo.screenPanX, screenPanY - touchInfo.screenPanY); 11363 touchInfo.screenPanX = screenPanX; 11364 touchInfo.screenPanY = screenPanY; 11365 const distance = Math.hypot(currGapX, currGapY); 11366 const pDistance = Math.hypot(prevGapX, prevGapY); 11367 const minDistance = this.#isPinching ? this.MIN_TOUCH_DISTANCE_TO_SCALE : this.MIN_TOUCH_DISTANCE_TO_PINCH + 2 * translation; 11368 if (distance < MIN_TOUCH_SPAN || pDistance < MIN_TOUCH_SPAN || Math.abs(pDistance - distance) <= minDistance) { 11369 if (dx || dy) { 11370 this.#onPanning?.(dx, dy); 11371 } 11372 return; 11373 } 11374 touchInfo.touch0X = screen0X; 11375 touchInfo.touch0Y = screen0Y; 11376 touchInfo.touch1X = screen1X; 11377 touchInfo.touch1Y = screen1Y; 11378 const direction = Math.sign(distance - pDistance); 11379 if (!this.#isPinching) { 11380 this.#isPinching = true; 11381 this.#unconfirmedPinch = direction; 11382 if (dx || dy) { 11383 this.#onPanning?.(dx, dy); 11384 } 11385 return; 11386 } 11387 if (this.#unconfirmedPinch) { 11388 const unconfirmed = this.#unconfirmedPinch; 11389 this.#unconfirmedPinch = 0; 11390 if (direction !== unconfirmed && Math.abs(distance - pDistance) <= 2 * translation) { 11391 this.#isPinching = false; 11392 if (dx || dy) { 11393 this.#onPanning?.(dx, dy); 11394 } 11395 return; 11396 } 11397 } 11398 this.#onPinching?.([pPanX, pPanY], pDistance, distance, dx, dy); 11399 } 11400 #onTouchEnd(evt) { 11401 this.#pruneTouchIds(evt); 11402 if (this.#touchIds.size >= 2) { 11403 this.#setTouchInfo(evt); 11404 return; 11405 } 11406 const wasTracking = !!this.#touchInfo; 11407 this.#endGesture(); 11408 if (this.#touchIds.size === 1) { 11409 this.#armPointerDown(); 11410 } 11411 if (wasTracking) { 11412 stopTouchEvent(evt); 11413 } 11414 } 11415 #endGesture() { 11416 this.#touchInfo = null; 11417 this.#isPinching = false; 11418 this.#unconfirmedPinch = 0; 11419 this.#ownsGesture = false; 11420 if (this.#touchMoveAC) { 11421 this.#touchMoveAC.abort(); 11422 this.#touchMoveAC = null; 11423 this.#onPinchEnd?.(); 11424 } 11425 } 11426 destroy() { 11427 this.#endGesture(); 11428 this.#touchIds.clear(); 11429 this.#touchManagerAC?.abort(); 11430 this.#touchManagerAC = null; 11431 this.#pointerDownAC?.abort(); 11432 this.#pointerDownAC = null; 11433 } 11434} 11435 11436;// ./src/display/editor/editor.js 11437
vendor: 49,082 bytes, lines 11438-13119
11438 11439 11440 11441 11442 11443 11444 11445 11446 11447class AnnotationEditor { 11448 #accessibilityData = null; 11449 #allResizerDivs = null; 11450 #altText = null; 11451 #comment = null; 11452 #commentStandaloneButton = null; 11453 #disabled = false; 11454 #dragPointerId = null; 11455 #dragPointerType = ""; 11456 #resizersDiv = null; 11457 #lastPointerCoords = null; 11458 #savedDimensions = null; 11459 #fakeAnnotation = null; 11460 #focusAC = null; 11461 #focusedResizerName = ""; 11462 #hasBeenClicked = false; 11463 #initialRect = null; 11464 #isEditing = false; 11465 #isInEditMode = false; 11466 #isResizerEnabledForKeyboard = false; 11467 #moveInDOMTimeout = null; 11468 #prevDragX = 0; 11469 #prevDragY = 0; 11470 #telemetryTimeouts = null; 11471 #touchManager = null; 11472 isSelected = false; 11473 _isCopy = false; 11474 _editToolbar = null; 11475 _initialOptions = Object.create(null); 11476 _initialData = null; 11477 _isVisible = true; 11478 _uiManager = null; 11479 _focusEventsAllowed = true; 11480 static _l10n = null; 11481 static _l10nAlert = null; 11482 static _l10nResizer = null; 11483 #isDraggable = false; 11484 #zIndex = AnnotationEditor._zIndex++; 11485 static _borderLineWidth = -1; 11486 static _colorManager = new ColorManager(); 11487 static _zIndex = 1; 11488 static _telemetryTimeout = 1000; 11489 static get _resizerKeyboardManager() { 11490 const resize = AnnotationEditor.prototype._resizeWithKeyboard; 11491 const small = AnnotationEditorUIManager.TRANSLATE_SMALL; 11492 const big = AnnotationEditorUIManager.TRANSLATE_BIG; 11493 return shadow(this, "_resizerKeyboardManager", new KeyboardManager([[["ArrowLeft"], resize, { 11494 args: [-small, 0] 11495 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], resize, { 11496 args: [-big, 0] 11497 }], [["ArrowRight"], resize, { 11498 args: [small, 0] 11499 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], resize, { 11500 args: [big, 0] 11501 }], [["ArrowUp"], resize, { 11502 args: [0, -small] 11503 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], resize, { 11504 args: [0, -big] 11505 }], [["ArrowDown"], resize, { 11506 args: [0, small] 11507 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], resize, { 11508 args: [0, big] 11509 }], [["Escape"], AnnotationEditor.prototype._stopResizingWithKeyboard]])); 11510 } 11511 constructor(parameters) { 11512 this.parent = parameters.parent; 11513 this.id = parameters.id; 11514 this.width = this.height = null; 11515 this.pageIndex = parameters.parent.pageIndex; 11516 this.name = parameters.name; 11517 this.div = null; 11518 this._uiManager = parameters.uiManager; 11519 this.annotationElementId = null; 11520 this._willKeepAspectRatio = false; 11521 this._initialOptions.isCentered = parameters.isCentered; 11522 this._structTreeParentId = null; 11523 this.annotationElementId = parameters.annotationElementId || null; 11524 this.creationDate = parameters.creationDate || new Date(); 11525 this.modificationDate = parameters.modificationDate || null; 11526 this.canAddComment = true; 11527 const { 11528 rotation, 11529 rawDims: { 11530 pageWidth, 11531 pageHeight, 11532 pageX, 11533 pageY 11534 } 11535 } = this.parent.viewport; 11536 this.rotation = rotation; 11537 this.pageRotation = (360 + rotation - this._uiManager.viewParameters.rotation) % 360; 11538 this.pageDimensions = [pageWidth, pageHeight]; 11539 this.pageTranslation = [pageX, pageY]; 11540 const [width, height] = this.parentDimensions; 11541 this.x = parameters.x / width; 11542 this.y = parameters.y / height; 11543 this.isAttachedToDOM = false; 11544 this.deleted = false; 11545 } 11546 updatePageIndex(newPageIndex) { 11547 this.pageIndex = newPageIndex; 11548 } 11549 get editorType() { 11550 return Object.getPrototypeOf(this).constructor._type; 11551 } 11552 get mode() { 11553 return Object.getPrototypeOf(this).constructor._editorType; 11554 } 11555 static get isDrawer() { 11556 return false; 11557 } 11558 static get _defaultLineColor() { 11559 return shadow(this, "_defaultLineColor", this._colorManager.getHexCode("CanvasText")); 11560 } 11561 static deleteAnnotationElement(editor) { 11562 const fakeEditor = new FakeEditor({ 11563 id: editor._uiManager.getId(), 11564 parent: editor.parent, 11565 uiManager: editor._uiManager 11566 }); 11567 fakeEditor.annotationElementId = editor.annotationElementId; 11568 fakeEditor.deleted = true; 11569 fakeEditor._uiManager.addToAnnotationStorage(fakeEditor); 11570 } 11571 static initialize(l10n, _uiManager) { 11572 AnnotationEditor._l10n ??= l10n; 11573 AnnotationEditor._l10nAlert ??= Object.freeze({ 11574 highlight: "pdfjs-editor-highlight-added-alert", 11575 freetext: "pdfjs-editor-freetext-added-alert", 11576 ink: "pdfjs-editor-ink-added-alert", 11577 stamp: "pdfjs-editor-stamp-added-alert", 11578 signature: "pdfjs-editor-signature-added-alert" 11579 }); 11580 AnnotationEditor._l10nResizer ??= Object.freeze({ 11581 topLeft: "pdfjs-editor-resizer-top-left", 11582 topMiddle: "pdfjs-editor-resizer-top-middle", 11583 topRight: "pdfjs-editor-resizer-top-right", 11584 middleRight: "pdfjs-editor-resizer-middle-right", 11585 bottomRight: "pdfjs-editor-resizer-bottom-right", 11586 bottomMiddle: "pdfjs-editor-resizer-bottom-middle", 11587 bottomLeft: "pdfjs-editor-resizer-bottom-left", 11588 middleLeft: "pdfjs-editor-resizer-middle-left" 11589 }); 11590 if (AnnotationEditor._borderLineWidth !== -1) { 11591 return; 11592 } 11593 const style = getComputedStyle(document.documentElement); 11594 AnnotationEditor._borderLineWidth = parseFloat(style.getPropertyValue("--outline-width")) || 0; 11595 } 11596 static updateDefaultParams(_type, _value) {} 11597 static get defaultPropertiesToUpdate() { 11598 return []; 11599 } 11600 static isHandlingMimeForPasting(mime) { 11601 return false; 11602 } 11603 static paste(item, parent) { 11604 unreachable("Not implemented"); 11605 } 11606 get propertiesToUpdate() { 11607 return []; 11608 } 11609 get _isDraggable() { 11610 return this.#isDraggable; 11611 } 11612 set _isDraggable(value) { 11613 this.#isDraggable = value; 11614 this.div?.classList.toggle("draggable", value); 11615 } 11616 get uid() { 11617 return this.annotationElementId || this.id; 11618 } 11619 get isEnterHandled() { 11620 return true; 11621 } 11622 center() { 11623 const [pageWidth, pageHeight] = this.pageDimensions; 11624 switch (this.parentRotation) { 11625 case 90: 11626 this.x -= this.height * pageHeight / (pageWidth * 2); 11627 this.y += this.width * pageWidth / (pageHeight * 2); 11628 break; 11629 case 180: 11630 this.x += this.width / 2; 11631 this.y += this.height / 2; 11632 break; 11633 case 270: 11634 this.x += this.height * pageHeight / (pageWidth * 2); 11635 this.y -= this.width * pageWidth / (pageHeight * 2); 11636 break; 11637 default: 11638 this.x -= this.width / 2; 11639 this.y -= this.height / 2; 11640 break; 11641 } 11642 this.fixAndSetPosition(); 11643 } 11644 addCommands(params) { 11645 this._uiManager.addCommands(params); 11646 } 11647 get currentLayer() { 11648 return this._uiManager.currentLayer; 11649 } 11650 setInBackground() { 11651 this.div.style.zIndex = 0; 11652 } 11653 setInForeground() { 11654 this.div.style.zIndex = this.#zIndex; 11655 } 11656 setParent(parent) { 11657 if (parent !== null) { 11658 this.pageIndex = parent.pageIndex; 11659 this.pageDimensions = parent.pageDimensions; 11660 } else { 11661 this.#stopResizing(); 11662 this.#fakeAnnotation?.remove(); 11663 this.#fakeAnnotation = null; 11664 } 11665 this.parent = parent; 11666 } 11667 focusin(event) { 11668 if (!this._focusEventsAllowed) { 11669 return; 11670 } 11671 if (!this.#hasBeenClicked) { 11672 this.parent.setSelected(this); 11673 } else { 11674 this.#hasBeenClicked = false; 11675 } 11676 } 11677 focusout(event) { 11678 if (!this._focusEventsAllowed) { 11679 return; 11680 } 11681 if (!this.isAttachedToDOM) { 11682 return; 11683 } 11684 const target = event.relatedTarget; 11685 if (target?.closest(`#${this.id}`)) { 11686 return; 11687 } 11688 event.preventDefault(); 11689 if (!this.parent?.isMultipleSelection) { 11690 this.commitOrRemove(); 11691 } 11692 } 11693 commitOrRemove() { 11694 if (this.isEmpty()) { 11695 this.remove(); 11696 } else { 11697 this.commit(); 11698 } 11699 } 11700 commit() { 11701 if (!this.isInEditMode()) { 11702 return; 11703 } 11704 this.addToAnnotationStorage(); 11705 } 11706 addToAnnotationStorage() { 11707 this._uiManager.addToAnnotationStorage(this); 11708 } 11709 setAt(x, y, tx, ty) { 11710 const [width, height] = this.parentDimensions; 11711 [tx, ty] = this.screenToPageTranslation(tx, ty); 11712 this.x = (x + tx) / width; 11713 this.y = (y + ty) / height; 11714 this.fixAndSetPosition(); 11715 } 11716 _moveAfterPaste(baseX, baseY) { 11717 if (this.isClone) { 11718 delete this.isClone; 11719 return; 11720 } 11721 const [parentWidth, parentHeight] = this.parentDimensions; 11722 this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); 11723 this._onTranslated(); 11724 } 11725 #translate([width, height], x, y) { 11726 [x, y] = this.screenToPageTranslation(x, y); 11727 this.x += x / width; 11728 this.y += y / height; 11729 this._onTranslating(this.x, this.y); 11730 this.fixAndSetPosition(); 11731 } 11732 translate(x, y) { 11733 this.#translate(this.parentDimensions, x, y); 11734 } 11735 translateInPage(x, y) { 11736 this.#initialRect ||= [this.x, this.y, this.width, this.height]; 11737 this.#translate(this.pageDimensions, x, y); 11738 this.div.scrollIntoView({ 11739 block: "nearest" 11740 }); 11741 } 11742 translationDone() { 11743 this._onTranslated(this.x, this.y); 11744 } 11745 drag(tx, ty) { 11746 this.#initialRect ||= [this.x, this.y, this.width, this.height]; 11747 const { 11748 div, 11749 parentDimensions: [parentWidth, parentHeight] 11750 } = this; 11751 this.x += tx / parentWidth; 11752 this.y += ty / parentHeight; 11753 if (this.parent && (this.x < 0 || this.x > 1 || this.y < 0 || this.y > 1)) { 11754 const { 11755 x, 11756 y 11757 } = this.div.getBoundingClientRect(); 11758 if (this.parent.findNewParent(this, x, y)) { 11759 this.x -= Math.floor(this.x); 11760 this.y -= Math.floor(this.y); 11761 } 11762 } 11763 let { 11764 x, 11765 y 11766 } = this; 11767 const [bx, by] = this.getBaseTranslation(); 11768 x += bx; 11769 y += by; 11770 const { 11771 style 11772 } = div; 11773 style.left = `${(100 * x).toFixed(2)}%`; 11774 style.top = `${(100 * y).toFixed(2)}%`; 11775 this._onTranslating(x, y); 11776 } 11777 _onTranslating(x, y) {} 11778 _onTranslated(x, y) {} 11779 get _hasBeenMoved() { 11780 return !!this.#initialRect && (this.#initialRect[0] !== this.x || this.#initialRect[1] !== this.y); 11781 } 11782 get _hasBeenResized() { 11783 return !!this.#initialRect && (this.#initialRect[2] !== this.width || this.#initialRect[3] !== this.height); 11784 } 11785 getBaseTranslation() { 11786 const [parentWidth, parentHeight] = this.parentDimensions; 11787 const { 11788 _borderLineWidth 11789 } = AnnotationEditor; 11790 const x = _borderLineWidth / parentWidth; 11791 const y = _borderLineWidth / parentHeight; 11792 switch (this.rotation) { 11793 case 90: 11794 return [-x, y]; 11795 case 180: 11796 return [x, y]; 11797 case 270: 11798 return [x, -y]; 11799 default: 11800 return [-x, -y]; 11801 } 11802 } 11803 get _mustFixPosition() { 11804 return true; 11805 } 11806 fixAndSetPosition(rotation = this.rotation) { 11807 const { 11808 div: { 11809 style 11810 }, 11811 pageDimensions: [pageWidth, pageHeight] 11812 } = this; 11813 let { 11814 x, 11815 y, 11816 width, 11817 height 11818 } = this; 11819 width *= pageWidth; 11820 height *= pageHeight; 11821 x *= pageWidth; 11822 y *= pageHeight; 11823 if (this._mustFixPosition) { 11824 switch (rotation) { 11825 case 0: 11826 x = MathClamp(x, 0, pageWidth - width); 11827 y = MathClamp(y, 0, pageHeight - height); 11828 break; 11829 case 90: 11830 x = MathClamp(x, 0, pageWidth - height); 11831 y = MathClamp(y, width, pageHeight); 11832 break; 11833 case 180: 11834 x = MathClamp(x, width, pageWidth); 11835 y = MathClamp(y, height, pageHeight); 11836 break; 11837 case 270: 11838 x = MathClamp(x, height, pageWidth); 11839 y = MathClamp(y, 0, pageHeight - width); 11840 break; 11841 } 11842 } 11843 this.x = x /= pageWidth; 11844 this.y = y /= pageHeight; 11845 const [bx, by] = this.getBaseTranslation(); 11846 x += bx; 11847 y += by; 11848 style.left = `${(100 * x).toFixed(2)}%`; 11849 style.top = `${(100 * y).toFixed(2)}%`; 11850 this.moveInDOM(); 11851 } 11852 static #rotatePoint(x, y, angle) { 11853 switch (angle) { 11854 case 90: 11855 return [y, -x]; 11856 case 180: 11857 return [-x, -y]; 11858 case 270: 11859 return [-y, x]; 11860 default: 11861 return [x, y]; 11862 } 11863 } 11864 screenToPageTranslation(x, y) { 11865 return AnnotationEditor.#rotatePoint(x, y, this.parentRotation); 11866 } 11867 pageTranslationToScreen(x, y) { 11868 return AnnotationEditor.#rotatePoint(x, y, 360 - this.parentRotation); 11869 } 11870 #getRotationMatrix(rotation) { 11871 switch (rotation) { 11872 case 90: 11873 { 11874 const [pageWidth, pageHeight] = this.pageDimensions; 11875 return [0, -pageWidth / pageHeight, pageHeight / pageWidth, 0]; 11876 } 11877 case 180: 11878 return [-1, 0, 0, -1]; 11879 case 270: 11880 { 11881 const [pageWidth, pageHeight] = this.pageDimensions; 11882 return [0, pageWidth / pageHeight, -pageHeight / pageWidth, 0]; 11883 } 11884 default: 11885 return [1, 0, 0, 1]; 11886 } 11887 } 11888 get parentScale() { 11889 return this._uiManager.viewParameters.realScale; 11890 } 11891 get parentRotation() { 11892 return (this._uiManager.viewParameters.rotation + this.pageRotation) % 360; 11893 } 11894 get parentDimensions() { 11895 const { 11896 parentScale, 11897 pageDimensions: [pageWidth, pageHeight] 11898 } = this; 11899 return [pageWidth * parentScale, pageHeight * parentScale]; 11900 } 11901 setDims() { 11902 const { 11903 div: { 11904 style 11905 }, 11906 width, 11907 height 11908 } = this; 11909 style.width = `${(100 * width).toFixed(2)}%`; 11910 style.height = `${(100 * height).toFixed(2)}%`; 11911 } 11912 getInitialTranslation() { 11913 return [0, 0]; 11914 } 11915 #createResizers() { 11916 if (this.#resizersDiv) { 11917 return; 11918 } 11919 this.#resizersDiv = document.createElement("div"); 11920 this.#resizersDiv.classList.add("resizers"); 11921 const classes = this._willKeepAspectRatio ? ["topLeft", "topRight", "bottomRight", "bottomLeft"] : ["topLeft", "topMiddle", "topRight", "middleRight", "bottomRight", "bottomMiddle", "bottomLeft", "middleLeft"]; 11922 const signal = this._uiManager._signal; 11923 for (const name of classes) { 11924 const div = document.createElement("div"); 11925 this.#resizersDiv.append(div); 11926 div.classList.add("resizer", name); 11927 div.setAttribute("data-resizer-name", name); 11928 div.addEventListener("pointerdown", this.#resizerPointerdown.bind(this, name), { 11929 signal 11930 }); 11931 div.addEventListener("contextmenu", noContextMenu, { 11932 signal 11933 }); 11934 div.tabIndex = -1; 11935 } 11936 this.div.prepend(this.#resizersDiv); 11937 } 11938 #resizerPointerdown(name, event) { 11939 event.preventDefault(); 11940 const { 11941 isMac 11942 } = FeatureTest.platform; 11943 if (event.button !== 0 || event.ctrlKey && isMac) { 11944 return; 11945 } 11946 this.#altText?.toggle(false); 11947 const savedDraggable = this._isDraggable; 11948 this._isDraggable = false; 11949 this.#lastPointerCoords = [event.screenX, event.screenY]; 11950 const ac = new AbortController(); 11951 const signal = this._uiManager.combinedSignal(ac); 11952 this.parent.togglePointerEvents(false); 11953 window.addEventListener("pointermove", this.#resizerPointermove.bind(this, name), { 11954 passive: true, 11955 capture: true, 11956 signal 11957 }); 11958 window.addEventListener("touchmove", stopEvent, { 11959 passive: false, 11960 signal 11961 }); 11962 window.addEventListener("contextmenu", noContextMenu, { 11963 signal 11964 }); 11965 this.#savedDimensions = { 11966 savedX: this.x, 11967 savedY: this.y, 11968 savedWidth: this.width, 11969 savedHeight: this.height 11970 }; 11971 const savedParentCursor = this.parent.div.style.cursor; 11972 const savedCursor = this.div.style.cursor; 11973 this.div.style.cursor = this.parent.div.style.cursor = window.getComputedStyle(event.target).cursor; 11974 const pointerUpCallback = () => { 11975 ac.abort(); 11976 this.parent.togglePointerEvents(true); 11977 this.#altText?.toggle(true); 11978 this._isDraggable = savedDraggable; 11979 this.parent.div.style.cursor = savedParentCursor; 11980 this.div.style.cursor = savedCursor; 11981 this.#addResizeToUndoStack(); 11982 }; 11983 window.addEventListener("pointerup", pointerUpCallback, { 11984 signal 11985 }); 11986 window.addEventListener("blur", pointerUpCallback, { 11987 signal 11988 }); 11989 } 11990 #resize(x, y, width, height) { 11991 this.width = width; 11992 this.height = height; 11993 this.x = x; 11994 this.y = y; 11995 this.setDims(); 11996 this.fixAndSetPosition(); 11997 this._onResized(); 11998 } 11999 _onResized() {} 12000 #addResizeToUndoStack() { 12001 if (!this.#savedDimensions) { 12002 return; 12003 } 12004 const { 12005 savedX, 12006 savedY, 12007 savedWidth, 12008 savedHeight 12009 } = this.#savedDimensions; 12010 this.#savedDimensions = null; 12011 const newX = this.x; 12012 const newY = this.y; 12013 const newWidth = this.width; 12014 const newHeight = this.height; 12015 if (newX === savedX && newY === savedY && newWidth === savedWidth && newHeight === savedHeight) { 12016 return; 12017 } 12018 this.addCommands({ 12019 cmd: this.#resize.bind(this, newX, newY, newWidth, newHeight), 12020 undo: this.#resize.bind(this, savedX, savedY, savedWidth, savedHeight), 12021 mustExec: true 12022 }); 12023 } 12024 static _round(x) { 12025 return Math.round(x * 10000) / 10000; 12026 } 12027 #resizerPointermove(name, event) { 12028 const [parentWidth, parentHeight] = this.parentDimensions; 12029 const savedX = this.x; 12030 const savedY = this.y; 12031 const savedWidth = this.width; 12032 const savedHeight = this.height; 12033 const minWidth = AnnotationEditor.MIN_SIZE / parentWidth; 12034 const minHeight = AnnotationEditor.MIN_SIZE / parentHeight; 12035 const rotationMatrix = this.#getRotationMatrix(this.rotation); 12036 const transf = (x, y) => [rotationMatrix[0] * x + rotationMatrix[2] * y, rotationMatrix[1] * x + rotationMatrix[3] * y]; 12037 const invRotationMatrix = this.#getRotationMatrix(360 - this.rotation); 12038 const invTransf = (x, y) => [invRotationMatrix[0] * x + invRotationMatrix[2] * y, invRotationMatrix[1] * x + invRotationMatrix[3] * y]; 12039 let getPoint; 12040 let getOpposite; 12041 let isDiagonal = false; 12042 let isHorizontal = false; 12043 switch (name) { 12044 case "topLeft": 12045 isDiagonal = true; 12046 getPoint = (w, h) => [0, 0]; 12047 getOpposite = (w, h) => [w, h]; 12048 break; 12049 case "topMiddle": 12050 getPoint = (w, h) => [w / 2, 0]; 12051 getOpposite = (w, h) => [w / 2, h]; 12052 break; 12053 case "topRight": 12054 isDiagonal = true; 12055 getPoint = (w, h) => [w, 0]; 12056 getOpposite = (w, h) => [0, h]; 12057 break; 12058 case "middleRight": 12059 isHorizontal = true; 12060 getPoint = (w, h) => [w, h / 2]; 12061 getOpposite = (w, h) => [0, h / 2]; 12062 break; 12063 case "bottomRight": 12064 isDiagonal = true; 12065 getPoint = (w, h) => [w, h]; 12066 getOpposite = (w, h) => [0, 0]; 12067 break; 12068 case "bottomMiddle": 12069 getPoint = (w, h) => [w / 2, h]; 12070 getOpposite = (w, h) => [w / 2, 0]; 12071 break; 12072 case "bottomLeft": 12073 isDiagonal = true; 12074 getPoint = (w, h) => [0, h]; 12075 getOpposite = (w, h) => [w, 0]; 12076 break; 12077 case "middleLeft": 12078 isHorizontal = true; 12079 getPoint = (w, h) => [0, h / 2]; 12080 getOpposite = (w, h) => [w, h / 2]; 12081 break; 12082 } 12083 const point = getPoint(savedWidth, savedHeight); 12084 const oppositePoint = getOpposite(savedWidth, savedHeight); 12085 let transfOppositePoint = transf(...oppositePoint); 12086 const oppositeX = AnnotationEditor._round(savedX + transfOppositePoint[0]); 12087 const oppositeY = AnnotationEditor._round(savedY + transfOppositePoint[1]); 12088 let ratioX = 1; 12089 let ratioY = 1; 12090 let deltaX, deltaY; 12091 if (!event.fromKeyboard) { 12092 const { 12093 screenX, 12094 screenY 12095 } = event; 12096 const [lastScreenX, lastScreenY] = this.#lastPointerCoords; 12097 [deltaX, deltaY] = this.screenToPageTranslation(screenX - lastScreenX, screenY - lastScreenY); 12098 this.#lastPointerCoords[0] = screenX; 12099 this.#lastPointerCoords[1] = screenY; 12100 } else { 12101 ({ 12102 deltaX, 12103 deltaY 12104 } = event); 12105 } 12106 [deltaX, deltaY] = invTransf(deltaX / parentWidth, deltaY / parentHeight); 12107 if (isDiagonal) { 12108 const oldDiag = Math.hypot(savedWidth, savedHeight); 12109 ratioX = ratioY = Math.max(Math.min(Math.hypot(oppositePoint[0] - point[0] - deltaX, oppositePoint[1] - point[1] - deltaY) / oldDiag, 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 12110 } else if (isHorizontal) { 12111 ratioX = MathClamp(Math.abs(oppositePoint[0] - point[0] - deltaX), minWidth, 1) / savedWidth; 12112 } else { 12113 ratioY = MathClamp(Math.abs(oppositePoint[1] - point[1] - deltaY), minHeight, 1) / savedHeight; 12114 } 12115 const newWidth = AnnotationEditor._round(savedWidth * ratioX); 12116 const newHeight = AnnotationEditor._round(savedHeight * ratioY); 12117 transfOppositePoint = transf(...getOpposite(newWidth, newHeight)); 12118 const newX = oppositeX - transfOppositePoint[0]; 12119 const newY = oppositeY - transfOppositePoint[1]; 12120 this.#initialRect ||= [this.x, this.y, this.width, this.height]; 12121 this.width = newWidth; 12122 this.height = newHeight; 12123 this.x = newX; 12124 this.y = newY; 12125 this.setDims(); 12126 this.fixAndSetPosition(); 12127 this._onResizing(); 12128 } 12129 _onResizing() {} 12130 altTextFinish() { 12131 this.#altText?.finish(); 12132 } 12133 get toolbarButtons() { 12134 return null; 12135 } 12136 async addEditToolbar() { 12137 if (this._editToolbar || this.#isInEditMode) { 12138 return this._editToolbar; 12139 } 12140 this._editToolbar = new EditorToolbar(this); 12141 this.div.append(this._editToolbar.render()); 12142 const { 12143 toolbarButtons 12144 } = this; 12145 if (toolbarButtons) { 12146 for (const [name, tool] of toolbarButtons) { 12147 await this._editToolbar.addButton(name, tool); 12148 } 12149 } 12150 if (!this.hasComment) { 12151 this._editToolbar.addButton("comment", this.addCommentButton()); 12152 } 12153 this._editToolbar.addButton("delete"); 12154 return this._editToolbar; 12155 } 12156 addCommentButtonInToolbar() { 12157 this._editToolbar?.addButtonBefore("comment", this.addCommentButton(), ".deleteButton"); 12158 } 12159 removeCommentButtonFromToolbar() { 12160 this._editToolbar?.removeButton("comment"); 12161 } 12162 removeEditToolbar() { 12163 this._editToolbar?.remove(); 12164 this._editToolbar = null; 12165 this.#altText?.destroy(); 12166 } 12167 addContainer(container) { 12168 const editToolbarDiv = this._editToolbar?.div; 12169 if (editToolbarDiv) { 12170 editToolbarDiv.before(container); 12171 } else { 12172 this.div.append(container); 12173 } 12174 } 12175 getClientDimensions() { 12176 return this.div.getBoundingClientRect(); 12177 } 12178 createAltText() { 12179 if (!this.#altText) { 12180 AltText.initialize(AnnotationEditor._l10n); 12181 this.#altText = new AltText(this); 12182 if (this.#accessibilityData) { 12183 this.#altText.data = this.#accessibilityData; 12184 this.#accessibilityData = null; 12185 } 12186 } 12187 return this.#altText; 12188 } 12189 get altTextData() { 12190 return this.#altText?.data; 12191 } 12192 set altTextData(data) { 12193 if (!this.#altText) { 12194 return; 12195 } 12196 this.#altText.data = data; 12197 } 12198 get guessedAltText() { 12199 return this.#altText?.guessedText; 12200 } 12201 async setGuessedAltText(text) { 12202 await this.#altText?.setGuessedText(text); 12203 } 12204 serializeAltText(isForCopying) { 12205 return this.#altText?.serialize(isForCopying); 12206 } 12207 hasAltText() { 12208 return !!this.#altText && !this.#altText.isEmpty(); 12209 } 12210 hasAltTextData() { 12211 return this.#altText?.hasData() ?? false; 12212 } 12213 focusCommentButton() { 12214 this.#comment?.focusButton(); 12215 } 12216 addCommentButton() { 12217 return this.canAddComment ? this.#comment ||= new Comment(this) : null; 12218 } 12219 addStandaloneCommentButton() { 12220 if (!this._uiManager.hasCommentManager()) { 12221 return; 12222 } 12223 if (this.#commentStandaloneButton) { 12224 if (this._uiManager.isEditingMode()) { 12225 this.#commentStandaloneButton.classList.remove("hidden"); 12226 } 12227 return; 12228 } 12229 if (!this.hasComment) { 12230 return; 12231 } 12232 this.#commentStandaloneButton = this.#comment.renderForStandalone(); 12233 this.div.append(this.#commentStandaloneButton); 12234 } 12235 removeStandaloneCommentButton() { 12236 this.#comment.removeStandaloneCommentButton(); 12237 this.#commentStandaloneButton = null; 12238 } 12239 hideStandaloneCommentButton() { 12240 this.#commentStandaloneButton?.classList.add("hidden"); 12241 } 12242 get comment() { 12243 if (!this.#comment) { 12244 return null; 12245 } 12246 const { 12247 data: { 12248 richText, 12249 text, 12250 date, 12251 deleted 12252 } 12253 } = this.#comment; 12254 return { 12255 text, 12256 richText, 12257 date, 12258 deleted, 12259 color: this.getNonHCMColor(), 12260 opacity: this.opacity ?? 1 12261 }; 12262 } 12263 set comment(value) { 12264 this.#comment ||= new Comment(this); 12265 if (typeof value === "object" && value !== null) { 12266 this.#comment.restoreData(value); 12267 } else { 12268 this.#comment.data = value; 12269 } 12270 if (this.hasComment) { 12271 this.removeCommentButtonFromToolbar(); 12272 this.addStandaloneCommentButton(); 12273 this._uiManager.updateComment(this); 12274 } else { 12275 this.addCommentButtonInToolbar(); 12276 this.removeStandaloneCommentButton(); 12277 this._uiManager.removeComment(this); 12278 } 12279 } 12280 setCommentData({ 12281 comment, 12282 popupRef, 12283 richText 12284 }) { 12285 if (!popupRef) { 12286 return; 12287 } 12288 this.#comment ||= new Comment(this); 12289 this.#comment.setInitialText(comment, richText); 12290 if (!this.annotationElementId) { 12291 return; 12292 } 12293 const storedData = this._uiManager.getAndRemoveDataFromAnnotationStorage(this.annotationElementId); 12294 if (storedData) { 12295 this.updateFromAnnotationLayer(storedData); 12296 } 12297 } 12298 get hasEditedComment() { 12299 return this.#comment?.hasBeenEdited(); 12300 } 12301 get hasDeletedComment() { 12302 return this.#comment?.isDeleted(); 12303 } 12304 get hasComment() { 12305 return !!this.#comment && !this.#comment.isEmpty() && !this.#comment.isDeleted(); 12306 } 12307 async editComment(options) { 12308 this.#comment ||= new Comment(this); 12309 this.#comment.edit(options); 12310 } 12311 toggleComment(isSelected, visibility = undefined) { 12312 if (this.hasComment) { 12313 this._uiManager.toggleComment(this, isSelected, visibility); 12314 } 12315 } 12316 setSelectedCommentButton(selected) { 12317 this.#comment.setSelectedButton(selected); 12318 } 12319 addComment(serialized) { 12320 if (this.hasEditedComment) { 12321 const DEFAULT_POPUP_WIDTH = 180; 12322 const DEFAULT_POPUP_HEIGHT = 100; 12323 const [,,, trY] = serialized.rect; 12324 const [pageWidth] = this.pageDimensions; 12325 const [pageX] = this.pageTranslation; 12326 const blX = pageX + pageWidth + 1; 12327 const blY = trY - DEFAULT_POPUP_HEIGHT; 12328 const trX = blX + DEFAULT_POPUP_WIDTH; 12329 serialized.popup = { 12330 contents: this.comment.text, 12331 deleted: this.comment.deleted, 12332 rect: [blX, blY, trX, trY] 12333 }; 12334 } 12335 } 12336 updateFromAnnotationLayer({ 12337 popup: { 12338 contents, 12339 deleted 12340 } 12341 }) { 12342 this.#comment.data = deleted ? null : contents; 12343 } 12344 get parentBoundingClientRect() { 12345 return this.parent.boundingClientRect; 12346 } 12347 render() { 12348 const div = this.div = document.createElement("div"); 12349 div.setAttribute("data-editor-rotation", (360 - this.rotation) % 360); 12350 div.className = this.name; 12351 div.setAttribute("id", this.id); 12352 div.tabIndex = this.#disabled ? -1 : 0; 12353 div.setAttribute("role", "application"); 12354 if (this.defaultL10nId) { 12355 div.setAttribute("data-l10n-id", this.defaultL10nId); 12356 } 12357 if (!this._isVisible) { 12358 div.classList.add("hidden"); 12359 } 12360 this.setInForeground(); 12361 this.#addFocusListeners(); 12362 const [parentWidth, parentHeight] = this.parentDimensions; 12363 if (this.parentRotation % 180 !== 0) { 12364 div.style.maxWidth = `${(100 * parentHeight / parentWidth).toFixed(2)}%`; 12365 div.style.maxHeight = `${(100 * parentWidth / parentHeight).toFixed(2)}%`; 12366 } 12367 const [tx, ty] = this.getInitialTranslation(); 12368 this.translate(tx, ty); 12369 bindEvents(this, div, ["keydown", "pointerdown", "dblclick"]); 12370 this.#addTouchManager(); 12371 this.addStandaloneCommentButton(); 12372 this._uiManager._editorUndoBar?.hide(); 12373 return div; 12374 } 12375 #touchPinchStartCallback() { 12376 this.#savedDimensions = { 12377 savedX: this.x, 12378 savedY: this.y, 12379 savedWidth: this.width, 12380 savedHeight: this.height 12381 }; 12382 this.#altText?.toggle(false); 12383 this.parent.togglePointerEvents(false); 12384 } 12385 #touchPinchCallback(_origin, prevDistance, distance) { 12386 const slowDownFactor = 0.7; 12387 let factor = slowDownFactor * (distance / prevDistance) + 1 - slowDownFactor; 12388 if (factor === 1) { 12389 return; 12390 } 12391 const rotationMatrix = this.#getRotationMatrix(this.rotation); 12392 const transf = (x, y) => [rotationMatrix[0] * x + rotationMatrix[2] * y, rotationMatrix[1] * x + rotationMatrix[3] * y]; 12393 const [parentWidth, parentHeight] = this.parentDimensions; 12394 const savedX = this.x; 12395 const savedY = this.y; 12396 const savedWidth = this.width; 12397 const savedHeight = this.height; 12398 const minWidth = AnnotationEditor.MIN_SIZE / parentWidth; 12399 const minHeight = AnnotationEditor.MIN_SIZE / parentHeight; 12400 factor = Math.max(Math.min(factor, 1 / savedWidth, 1 / savedHeight), minWidth / savedWidth, minHeight / savedHeight); 12401 const newWidth = AnnotationEditor._round(savedWidth * factor); 12402 const newHeight = AnnotationEditor._round(savedHeight * factor); 12403 if (newWidth === savedWidth && newHeight === savedHeight) { 12404 return; 12405 } 12406 this.#initialRect ||= [savedX, savedY, savedWidth, savedHeight]; 12407 const transfCenterPoint = transf(savedWidth / 2, savedHeight / 2); 12408 const centerX = AnnotationEditor._round(savedX + transfCenterPoint[0]); 12409 const centerY = AnnotationEditor._round(savedY + transfCenterPoint[1]); 12410 const newTransfCenterPoint = transf(newWidth / 2, newHeight / 2); 12411 this.x = centerX - newTransfCenterPoint[0]; 12412 this.y = centerY - newTransfCenterPoint[1]; 12413 this.width = newWidth; 12414 this.height = newHeight; 12415 this.setDims(); 12416 this.fixAndSetPosition(); 12417 this._onResizing(); 12418 } 12419 #touchPinchEndCallback() { 12420 this.#altText?.toggle(true); 12421 this.parent.togglePointerEvents(true); 12422 this.#addResizeToUndoStack(); 12423 } 12424 pointerdown(event) { 12425 const { 12426 isMac 12427 } = FeatureTest.platform; 12428 if (event.button !== 0 || event.ctrlKey && isMac) { 12429 event.preventDefault(); 12430 return; 12431 } 12432 this.#hasBeenClicked = true; 12433 if (this._isDraggable) { 12434 this.#setUpDragSession(event); 12435 return; 12436 } 12437 this.#selectOnPointerEvent(event); 12438 } 12439 #selectOnPointerEvent(event) { 12440 const { 12441 isMac 12442 } = FeatureTest.platform; 12443 if (event.ctrlKey && !isMac || event.shiftKey || event.metaKey && isMac) { 12444 this.parent.toggleSelected(this); 12445 } else { 12446 this.parent.setSelected(this); 12447 } 12448 } 12449 #setUpDragSession(event) { 12450 const { 12451 isSelected 12452 } = this; 12453 this._uiManager.setUpDragSession(); 12454 let hasDraggingStarted = false; 12455 const ac = new AbortController(); 12456 const signal = this._uiManager.combinedSignal(ac); 12457 const opts = { 12458 capture: true, 12459 passive: false, 12460 signal 12461 }; 12462 const cancelDrag = e => { 12463 ac.abort(); 12464 this.#dragPointerId = null; 12465 this.#hasBeenClicked = false; 12466 if (!this._uiManager.endDragSession()) { 12467 this.#selectOnPointerEvent(e); 12468 } 12469 if (hasDraggingStarted) { 12470 this._onStopDragging(); 12471 } 12472 }; 12473 if (isSelected) { 12474 this.#prevDragX = event.clientX; 12475 this.#prevDragY = event.clientY; 12476 this.#dragPointerId = event.pointerId; 12477 this.#dragPointerType = event.pointerType; 12478 window.addEventListener("pointermove", e => { 12479 if (!hasDraggingStarted) { 12480 hasDraggingStarted = true; 12481 this._uiManager.toggleComment(this, true, false); 12482 this._onStartDragging(); 12483 } 12484 const { 12485 clientX: x, 12486 clientY: y, 12487 pointerId 12488 } = e; 12489 if (pointerId !== this.#dragPointerId) { 12490 stopEvent(e); 12491 return; 12492 } 12493 const [tx, ty] = this.screenToPageTranslation(x - this.#prevDragX, y - this.#prevDragY); 12494 this.#prevDragX = x; 12495 this.#prevDragY = y; 12496 this._uiManager.dragSelectedEditors(tx, ty); 12497 this.div.scrollIntoView({ 12498 block: "nearest" 12499 }); 12500 }, opts); 12501 window.addEventListener("touchmove", stopEvent, opts); 12502 window.addEventListener("pointerdown", e => { 12503 if (e.pointerType === this.#dragPointerType) { 12504 if (this.#touchManager || e.isPrimary) { 12505 cancelDrag(e); 12506 } 12507 } 12508 stopEvent(e); 12509 }, opts); 12510 } 12511 const pointerUpCallback = e => { 12512 if (!this.#dragPointerId || this.#dragPointerId === e.pointerId) { 12513 cancelDrag(e); 12514 return; 12515 } 12516 stopEvent(e); 12517 }; 12518 window.addEventListener("pointerup", pointerUpCallback, { 12519 signal 12520 }); 12521 window.addEventListener("blur", pointerUpCallback, { 12522 signal 12523 }); 12524 } 12525 _onStartDragging() {} 12526 _onStopDragging() {} 12527 moveInDOM() { 12528 if (this.#moveInDOMTimeout) { 12529 clearTimeout(this.#moveInDOMTimeout); 12530 } 12531 this.#moveInDOMTimeout = setTimeout(() => { 12532 this.#moveInDOMTimeout = null; 12533 this.parent?.moveEditorInDOM(this); 12534 }, 0); 12535 } 12536 _setParentAndPosition(parent, x, y) { 12537 parent.changeParent(this); 12538 this.x = x; 12539 this.y = y; 12540 this.fixAndSetPosition(); 12541 this._onTranslated(); 12542 } 12543 getRect(tx, ty, rotation = this.rotation) { 12544 const scale = this.parentScale; 12545 const [pageWidth, pageHeight] = this.pageDimensions; 12546 const [pageX, pageY] = this.pageTranslation; 12547 const shiftX = tx / scale; 12548 const shiftY = ty / scale; 12549 const x = this.x * pageWidth; 12550 const y = this.y * pageHeight; 12551 const width = this.width * pageWidth; 12552 const height = this.height * pageHeight; 12553 switch (rotation) { 12554 case 0: 12555 return [x + shiftX + pageX, pageHeight - y - shiftY - height + pageY, x + shiftX + width + pageX, pageHeight - y - shiftY + pageY]; 12556 case 90: 12557 return [x + shiftY + pageX, pageHeight - y + shiftX + pageY, x + shiftY + height + pageX, pageHeight - y + shiftX + width + pageY]; 12558 case 180: 12559 return [x - shiftX - width + pageX, pageHeight - y + shiftY + pageY, x - shiftX + pageX, pageHeight - y + shiftY + height + pageY]; 12560 case 270: 12561 return [x - shiftY - height + pageX, pageHeight - y - shiftX - width + pageY, x - shiftY + pageX, pageHeight - y - shiftX + pageY]; 12562 default: 12563 throw new Error("Invalid rotation"); 12564 } 12565 } 12566 getRectInCurrentCoords(rect, pageHeight) { 12567 const [x1, y1, x2, y2] = rect; 12568 const width = x2 - x1; 12569 const height = y2 - y1; 12570 switch (this.rotation) { 12571 case 0: 12572 return [x1, pageHeight - y2, width, height]; 12573 case 90: 12574 return [x1, pageHeight - y1, height, width]; 12575 case 180: 12576 return [x2, pageHeight - y1, width, height]; 12577 case 270: 12578 return [x2, pageHeight - y2, height, width]; 12579 default: 12580 throw new Error("Invalid rotation"); 12581 } 12582 } 12583 getPDFRect() { 12584 return this.getRect(0, 0); 12585 } 12586 getNonHCMColor() { 12587 return this.color && AnnotationEditor._colorManager.convert(this._uiManager.getNonHCMColor(this.color)); 12588 } 12589 onUpdatedColor() { 12590 this.#comment?.onUpdatedColor(); 12591 } 12592 getData() { 12593 const { 12594 comment: { 12595 text: str, 12596 color, 12597 date, 12598 opacity, 12599 deleted, 12600 richText 12601 }, 12602 uid: id, 12603 pageIndex, 12604 creationDate, 12605 modificationDate 12606 } = this; 12607 return { 12608 id, 12609 pageIndex, 12610 rect: this.getPDFRect(), 12611 richText, 12612 contentsObj: { 12613 str 12614 }, 12615 creationDate, 12616 modificationDate: date || modificationDate, 12617 popupRef: !deleted, 12618 color, 12619 opacity 12620 }; 12621 } 12622 onceAdded(focus) {} 12623 isEmpty() { 12624 return false; 12625 } 12626 enableEditMode() { 12627 if (this.isInEditMode()) { 12628 return false; 12629 } 12630 this.parent.setEditingState(false); 12631 this.#isInEditMode = true; 12632 return true; 12633 } 12634 disableEditMode() { 12635 if (!this.isInEditMode()) { 12636 return false; 12637 } 12638 this.parent.setEditingState(true); 12639 this.#isInEditMode = false; 12640 return true; 12641 } 12642 isInEditMode() { 12643 return this.#isInEditMode; 12644 } 12645 shouldGetKeyboardEvents() { 12646 return this.#isResizerEnabledForKeyboard; 12647 } 12648 needsToBeRebuilt() { 12649 return this.div && !this.isAttachedToDOM; 12650 } 12651 get isOnScreen() { 12652 const { 12653 top, 12654 left, 12655 bottom, 12656 right 12657 } = this.getClientDimensions(); 12658 const { 12659 innerHeight, 12660 innerWidth 12661 } = window; 12662 return left < innerWidth && right > 0 && top < innerHeight && bottom > 0; 12663 } 12664 #addFocusListeners() { 12665 if (this.#focusAC || !this.div) { 12666 return; 12667 } 12668 this.#focusAC = new AbortController(); 12669 const signal = this._uiManager.combinedSignal(this.#focusAC); 12670 this.div.addEventListener("focusin", this.focusin.bind(this), { 12671 signal 12672 }); 12673 this.div.addEventListener("focusout", this.focusout.bind(this), { 12674 signal 12675 }); 12676 } 12677 #addTouchManager() { 12678 if (this.#touchManager || !this.div || !this.isResizable || !this._uiManager._supportsPinchToZoom) { 12679 return; 12680 } 12681 this.#touchManager = new TouchManager({ 12682 container: this.div, 12683 isPinchingDisabled: () => !this.isSelected, 12684 onPinchStart: this.#touchPinchStartCallback.bind(this), 12685 onPinching: this.#touchPinchCallback.bind(this), 12686 onPinchEnd: this.#touchPinchEndCallback.bind(this), 12687 signal: this._uiManager._signal 12688 }); 12689 } 12690 rebuild() { 12691 this.#addFocusListeners(); 12692 this.#addTouchManager(); 12693 } 12694 rotate(_angle) {} 12695 resize() {} 12696 serializeDeleted() { 12697 return { 12698 id: this.annotationElementId, 12699 deleted: true, 12700 pageIndex: this.pageIndex, 12701 popupRef: this._initialData?.popupRef || "" 12702 }; 12703 } 12704 serialize(isForCopying = false, context = null) { 12705 return { 12706 annotationType: this.mode, 12707 pageIndex: this.pageIndex, 12708 rect: this.getPDFRect(), 12709 rotation: this.rotation, 12710 structTreeParentId: this._structTreeParentId, 12711 popupRef: this._initialData?.popupRef || "" 12712 }; 12713 } 12714 static async deserialize(data, parent, uiManager) { 12715 const editor = new this.prototype.constructor({ 12716 parent, 12717 id: uiManager.getId(), 12718 uiManager, 12719 annotationElementId: data.annotationElementId, 12720 creationDate: data.creationDate, 12721 modificationDate: data.modificationDate 12722 }); 12723 editor.rotation = data.rotation; 12724 editor.#accessibilityData = data.accessibilityData; 12725 editor._isCopy = data.isCopy || false; 12726 const [pageWidth, pageHeight] = editor.pageDimensions; 12727 const [x, y, width, height] = editor.getRectInCurrentCoords(data.rect, pageHeight); 12728 editor.x = x / pageWidth; 12729 editor.y = y / pageHeight; 12730 editor.width = width / pageWidth; 12731 editor.height = height / pageHeight; 12732 return editor; 12733 } 12734 get hasBeenModified() { 12735 return !!this.annotationElementId && (this.deleted || this.serialize() !== null); 12736 } 12737 remove() { 12738 this.#focusAC?.abort(); 12739 this.#focusAC = null; 12740 if (!this.isEmpty()) { 12741 this.commit(); 12742 } 12743 this.#touchManager?.destroy(); 12744 this.#touchManager = null; 12745 if (this.parent) { 12746 this.parent.remove(this); 12747 } else { 12748 this._uiManager.removeEditor(this); 12749 } 12750 this.hideCommentPopup(); 12751 if (this.#moveInDOMTimeout) { 12752 clearTimeout(this.#moveInDOMTimeout); 12753 this.#moveInDOMTimeout = null; 12754 } 12755 this.#stopResizing(); 12756 this.removeEditToolbar(); 12757 if (this.#telemetryTimeouts) { 12758 for (const timeout of this.#telemetryTimeouts.values()) { 12759 clearTimeout(timeout); 12760 } 12761 this.#telemetryTimeouts = null; 12762 } 12763 this.parent = null; 12764 this.#fakeAnnotation?.remove(); 12765 this.#fakeAnnotation = null; 12766 } 12767 get isResizable() { 12768 return false; 12769 } 12770 makeResizable() { 12771 if (this.isResizable) { 12772 this.#createResizers(); 12773 this.#resizersDiv.classList.remove("hidden"); 12774 } 12775 } 12776 get toolbarPosition() { 12777 return null; 12778 } 12779 get commentButtonPosition() { 12780 return this._uiManager.direction === "ltr" ? [1, 0] : [0, 0]; 12781 } 12782 get commentButtonPositionInPage() { 12783 const { 12784 commentButtonPosition: [posX, posY] 12785 } = this; 12786 const [blX, blY, trX, trY] = this.getPDFRect(); 12787 return [AnnotationEditor._round(blX + (trX - blX) * posX), AnnotationEditor._round(blY + (trY - blY) * (1 - posY))]; 12788 } 12789 get commentButtonColor() { 12790 return this._uiManager.makeCommentColor(this.getNonHCMColor(), this.opacity); 12791 } 12792 get commentPopupPosition() { 12793 return this.#comment.commentPopupPositionInLayer; 12794 } 12795 set commentPopupPosition(pos) { 12796 this.#comment.commentPopupPositionInLayer = pos; 12797 } 12798 hasDefaultPopupPosition() { 12799 return this.#comment.hasDefaultPopupPosition(); 12800 } 12801 get commentButtonWidth() { 12802 return this.#comment.commentButtonWidth; 12803 } 12804 get elementBeforePopup() { 12805 return this.div; 12806 } 12807 setCommentButtonStates(options) { 12808 this.#comment?.setCommentButtonStates(options); 12809 } 12810 keydown(event) { 12811 if (!this.isResizable || event.target !== this.div || event.key !== "Enter") { 12812 return; 12813 } 12814 this._uiManager.setSelected(this); 12815 this.#savedDimensions = { 12816 savedX: this.x, 12817 savedY: this.y, 12818 savedWidth: this.width, 12819 savedHeight: this.height 12820 }; 12821 const children = this.#resizersDiv.children; 12822 if (!this.#allResizerDivs) { 12823 this.#allResizerDivs = Array.from(children); 12824 const boundResizerKeydown = this.#resizerKeydown.bind(this); 12825 const boundResizerBlur = this.#resizerBlur.bind(this); 12826 const signal = this._uiManager._signal; 12827 for (const div of this.#allResizerDivs) { 12828 const name = div.getAttribute("data-resizer-name"); 12829 div.setAttribute("role", "spinbutton"); 12830 div.addEventListener("keydown", boundResizerKeydown, { 12831 signal 12832 }); 12833 div.addEventListener("blur", boundResizerBlur, { 12834 signal 12835 }); 12836 div.addEventListener("focus", this.#resizerFocus.bind(this, name), { 12837 signal 12838 }); 12839 div.setAttribute("data-l10n-id", AnnotationEditor._l10nResizer[name]); 12840 } 12841 } 12842 const first = this.#allResizerDivs[0]; 12843 let firstPosition = 0; 12844 for (const div of children) { 12845 if (div === first) { 12846 break; 12847 } 12848 firstPosition++; 12849 } 12850 const nextFirstPosition = (360 - this.rotation + this.parentRotation) % 360 / 90 * (this.#allResizerDivs.length / 4); 12851 if (nextFirstPosition !== firstPosition) { 12852 if (nextFirstPosition < firstPosition) { 12853 for (let i = 0; i < firstPosition - nextFirstPosition; i++) { 12854 this.#resizersDiv.append(this.#resizersDiv.firstElementChild); 12855 } 12856 } else if (nextFirstPosition > firstPosition) { 12857 for (let i = 0; i < nextFirstPosition - firstPosition; i++) { 12858 this.#resizersDiv.firstElementChild.before(this.#resizersDiv.lastElementChild); 12859 } 12860 } 12861 let i = 0; 12862 for (const child of children) { 12863 const div = this.#allResizerDivs[i++]; 12864 const name = div.getAttribute("data-resizer-name"); 12865 child.setAttribute("data-l10n-id", AnnotationEditor._l10nResizer[name]); 12866 } 12867 } 12868 this.#setResizerTabIndex(0); 12869 this.#isResizerEnabledForKeyboard = true; 12870 this.#resizersDiv.firstElementChild.focus({ 12871 focusVisible: true 12872 }); 12873 event.preventDefault(); 12874 event.stopImmediatePropagation(); 12875 } 12876 #resizerKeydown(event) { 12877 AnnotationEditor._resizerKeyboardManager.exec(this, event); 12878 } 12879 #resizerBlur(event) { 12880 if (this.#isResizerEnabledForKeyboard && event.relatedTarget?.parentNode !== this.#resizersDiv) { 12881 this.#stopResizing(); 12882 } 12883 } 12884 #resizerFocus(name) { 12885 this.#focusedResizerName = this.#isResizerEnabledForKeyboard ? name : ""; 12886 } 12887 #setResizerTabIndex(value) { 12888 if (!this.#allResizerDivs) { 12889 return; 12890 } 12891 for (const div of this.#allResizerDivs) { 12892 div.tabIndex = value; 12893 } 12894 } 12895 _resizeWithKeyboard(x, y) { 12896 if (!this.#isResizerEnabledForKeyboard) { 12897 return; 12898 } 12899 this.#resizerPointermove(this.#focusedResizerName, { 12900 deltaX: x, 12901 deltaY: y, 12902 fromKeyboard: true 12903 }); 12904 } 12905 #stopResizing() { 12906 this.#isResizerEnabledForKeyboard = false; 12907 this.#setResizerTabIndex(-1); 12908 this.#addResizeToUndoStack(); 12909 } 12910 _stopResizingWithKeyboard() { 12911 this.#stopResizing(); 12912 this.div.focus(); 12913 } 12914 select() { 12915 if (this.isSelected && this._editToolbar) { 12916 this._editToolbar.show(); 12917 return; 12918 } 12919 this.isSelected = true; 12920 this.makeResizable(); 12921 this.div?.classList.add("selectedEditor"); 12922 if (!this._editToolbar) { 12923 this.addEditToolbar().then(() => { 12924 if (this.div?.classList.contains("selectedEditor")) { 12925 this._editToolbar?.show(); 12926 } 12927 }); 12928 return; 12929 } 12930 this._editToolbar?.show(); 12931 this.#altText?.toggleAltTextBadge(false); 12932 } 12933 focus() { 12934 if (this.div && !this.div.contains(document.activeElement)) { 12935 setTimeout(() => this.div?.focus({ 12936 preventScroll: true 12937 }), 0); 12938 } 12939 } 12940 unselect() { 12941 if (!this.isSelected) { 12942 return; 12943 } 12944 this.isSelected = false; 12945 this.#resizersDiv?.classList.add("hidden"); 12946 this.div?.classList.remove("selectedEditor"); 12947 if (this.div?.contains(document.activeElement)) { 12948 this._uiManager.currentLayer.div.focus({ 12949 preventScroll: true 12950 }); 12951 } 12952 this._editToolbar?.hide(); 12953 this.#altText?.toggleAltTextBadge(true); 12954 this.hideCommentPopup(); 12955 } 12956 hideCommentPopup() { 12957 if (this.hasComment) { 12958 this._uiManager.toggleComment(null); 12959 } 12960 } 12961 updateParams(type, value) {} 12962 disableEditing() {} 12963 enableEditing() {} 12964 get canChangeContent() { 12965 return false; 12966 } 12967 enterInEditMode() { 12968 if (!this.canChangeContent) { 12969 return; 12970 } 12971 this.enableEditMode(); 12972 this.div.focus(); 12973 } 12974 dblclick(event) { 12975 if (event.target.nodeName === "BUTTON") { 12976 return; 12977 } 12978 this.enterInEditMode(); 12979 this.parent.updateToolbar({ 12980 mode: this.constructor._editorType, 12981 editId: this.uid 12982 }); 12983 } 12984 getElementForAltText() { 12985 return this.div; 12986 } 12987 get contentDiv() { 12988 return this.div; 12989 } 12990 get isEditing() { 12991 return this.#isEditing; 12992 } 12993 set isEditing(value) { 12994 this.#isEditing = value; 12995 if (!this.parent) { 12996 return; 12997 } 12998 if (value) { 12999 this.parent.setSelected(this); 13000 this.parent.setActiveEditor(this); 13001 } else { 13002 this.parent.setActiveEditor(null); 13003 } 13004 } 13005 static get MIN_SIZE() { 13006 return 16; 13007 } 13008 static canCreateNewEmptyEditor() { 13009 return true; 13010 } 13011 get telemetryInitialData() { 13012 return { 13013 action: "added" 13014 }; 13015 } 13016 get telemetryFinalData() { 13017 return null; 13018 } 13019 _reportTelemetry(data, mustWait = false) { 13020 if (mustWait) { 13021 this.#telemetryTimeouts ||= new Map(); 13022 const { 13023 action 13024 } = data; 13025 let timeout = this.#telemetryTimeouts.get(action); 13026 if (timeout) { 13027 clearTimeout(timeout); 13028 } 13029 timeout = setTimeout(() => { 13030 this._reportTelemetry(data); 13031 this.#telemetryTimeouts.delete(action); 13032 if (this.#telemetryTimeouts.size === 0) { 13033 this.#telemetryTimeouts = null; 13034 } 13035 }, AnnotationEditor._telemetryTimeout); 13036 this.#telemetryTimeouts.set(action, timeout); 13037 return; 13038 } 13039 data.type ||= this.editorType; 13040 this._uiManager._eventBus.dispatch("reporttelemetry", { 13041 source: this, 13042 details: { 13043 type: "editing", 13044 data 13045 } 13046 }); 13047 } 13048 show(visible = this._isVisible) { 13049 this.div.classList.toggle("hidden", !visible); 13050 this._isVisible = visible; 13051 } 13052 enable() { 13053 if (this.div) { 13054 this.div.tabIndex = 0; 13055 } 13056 this.#disabled = false; 13057 } 13058 disable() { 13059 if (this.div) { 13060 this.div.tabIndex = -1; 13061 } 13062 this.#disabled = true; 13063 } 13064 updateFakeAnnotationElement(annotationLayer) { 13065 if (!this.#fakeAnnotation && !this.deleted) { 13066 this.#fakeAnnotation = annotationLayer.addFakeAnnotation(this); 13067 return; 13068 } 13069 if (this.deleted) { 13070 this.#fakeAnnotation.remove(); 13071 this.#fakeAnnotation = null; 13072 return; 13073 } 13074 if (this.hasEditedComment || this._hasBeenMoved || this._hasBeenResized) { 13075 this.#fakeAnnotation.updateEdited({ 13076 rect: this.getPDFRect(), 13077 popup: this.comment 13078 }); 13079 } 13080 } 13081 renderAnnotationElement(annotation) { 13082 if (this.deleted) { 13083 annotation.hide(); 13084 return null; 13085 } 13086 let content = annotation.container.querySelector(".annotationContent"); 13087 if (!content) { 13088 content = document.createElement("div"); 13089 content.classList.add("annotationContent", this.editorType); 13090 annotation.container.prepend(content); 13091 } else if (content.nodeName === "CANVAS") { 13092 const canvas = content; 13093 content = document.createElement("div"); 13094 content.classList.add("annotationContent", this.editorType); 13095 canvas.before(content); 13096 } 13097 return content; 13098 } 13099 resetAnnotationElement(annotation) { 13100 const { 13101 firstElementChild 13102 } = annotation.container; 13103 if (firstElementChild?.nodeName === "DIV" && firstElementChild.classList.contains("annotationContent")) { 13104 firstElementChild.remove(); 13105 } 13106 } 13107} 13108class FakeEditor extends AnnotationEditor { 13109 constructor(params) { 13110 super(params); 13111 this.annotationElementId = params.annotationElementId; 13112 this.deleted = true; 13113 } 13114 serialize() { 13115 return this.serializeDeleted(); 13116 } 13117} 13118 13119;// ./src/shared/murmurhash3.js
vendor: 2,916 bytes, lines 13120-13231
13120 13121 13122 13123 13124 13125const SEED = 0xc3d2e1f0; 13126const MASK_HIGH = 0xffff0000; 13127const MASK_LOW = 0xffff; 13128class MurmurHash3_64 { 13129 constructor(seed) { 13130 this.h1 = seed ? seed & 0xffffffff : SEED; 13131 this.h2 = seed ? seed & 0xffffffff : SEED; 13132 } 13133 update(input) { 13134 let data, length; 13135 if (typeof input === "string") { 13136 data = new Uint8Array(input.length * 2); 13137 length = 0; 13138 for (let i = 0, ii = input.length; i < ii; i++) { 13139 const code = input.charCodeAt(i); 13140 if (code <= 0xff) { 13141 data[length++] = code; 13142 } else { 13143 data[length++] = code >>> 8; 13144 data[length++] = code & 0xff; 13145 } 13146 } 13147 } else if (ArrayBuffer.isView(input)) { 13148 data = input.slice(); 13149 length = data.byteLength; 13150 } else { 13151 throw new Error("Invalid data format, must be a string or TypedArray."); 13152 } 13153 const blockCounts = length >> 2; 13154 const tailLength = length - blockCounts * 4; 13155 const dataUint32 = new Uint32Array(data.buffer, 0, blockCounts); 13156 let k1 = 0, 13157 k2 = 0; 13158 let h1 = this.h1, 13159 h2 = this.h2; 13160 const C1 = 0xcc9e2d51, 13161 C2 = 0x1b873593; 13162 const C1_LOW = C1 & MASK_LOW, 13163 C2_LOW = C2 & MASK_LOW; 13164 for (let i = 0; i < blockCounts; i++) { 13165 if (i & 1) { 13166 k1 = dataUint32[i]; 13167 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 13168 k1 = k1 << 15 | k1 >>> 17; 13169 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 13170 h1 ^= k1; 13171 h1 = h1 << 13 | h1 >>> 19; 13172 h1 = h1 * 5 + 0xe6546b64; 13173 } else { 13174 k2 = dataUint32[i]; 13175 k2 = k2 * C1 & MASK_HIGH | k2 * C1_LOW & MASK_LOW; 13176 k2 = k2 << 15 | k2 >>> 17; 13177 k2 = k2 * C2 & MASK_HIGH | k2 * C2_LOW & MASK_LOW; 13178 h2 ^= k2; 13179 h2 = h2 << 13 | h2 >>> 19; 13180 h2 = h2 * 5 + 0xe6546b64; 13181 } 13182 } 13183 k1 = 0; 13184 switch (tailLength) { 13185 case 3: 13186 k1 ^= data[blockCounts * 4 + 2] << 16; 13187 case 2: 13188 k1 ^= data[blockCounts * 4 + 1] << 8; 13189 case 1: 13190 k1 ^= data[blockCounts * 4]; 13191 k1 = k1 * C1 & MASK_HIGH | k1 * C1_LOW & MASK_LOW; 13192 k1 = k1 << 15 | k1 >>> 17; 13193 k1 = k1 * C2 & MASK_HIGH | k1 * C2_LOW & MASK_LOW; 13194 if (blockCounts & 1) { 13195 h1 ^= k1; 13196 } else { 13197 h2 ^= k1; 13198 } 13199 } 13200 this.h1 = h1; 13201 this.h2 = h2; 13202 } 13203 hexdigest() { 13204 let h1 = this.h1, 13205 h2 = this.h2; 13206 h1 ^= h2 >>> 1; 13207 h1 = h1 * 0xed558ccd & MASK_HIGH | h1 * 0x8ccd & MASK_LOW; 13208 h2 = h2 * 0xff51afd7 & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16; 13209 h1 ^= h2 >>> 1; 13210 h1 = h1 * 0x1a85ec53 & MASK_HIGH | h1 * 0xec53 & MASK_LOW; 13211 h2 = h2 * 0xc4ceb9fe & MASK_HIGH | ((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16; 13212 h1 ^= h2 >>> 1; 13213 return (h1 >>> 0).toString(16).padStart(8, "0") + (h2 >>> 0).toString(16).padStart(8, "0"); 13214 } 13215} 13216 13217;// ./src/display/annotation_storage.js 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231
vendor: 6,287 bytes, lines 13232-13486
13232 13233 13234 13235 13236const SerializableEmpty = Object.freeze({ 13237 map: null, 13238 hash: "", 13239 transfer: undefined 13240}); 13241class AnnotationStorage { 13242 #modified = false; 13243 #modifiedIds = null; 13244 #editorsMap = null; 13245 #storage = new Map(); 13246 onSetModified = null; 13247 onResetModified = null; 13248 onAnnotationEditor = null; 13249 getValue(key, defaultValue) { 13250 const value = this.#storage.get(key); 13251 if (value === undefined) { 13252 return defaultValue; 13253 } 13254 return Object.assign(defaultValue, value); 13255 } 13256 getRawValue(key) { 13257 return this.#storage.get(key); 13258 } 13259 remove(key) { 13260 const storedValue = this.#storage.get(key); 13261 if (storedValue === undefined) { 13262 return; 13263 } 13264 if (storedValue instanceof AnnotationEditor) { 13265 this.#editorsMap.delete(storedValue.annotationElementId); 13266 } 13267 this.#storage.delete(key); 13268 if (this.#storage.size === 0) { 13269 this.resetModified(); 13270 } 13271 if (this.#storage.values().some(v => v instanceof AnnotationEditor)) { 13272 return; 13273 } 13274 this.onAnnotationEditor?.(null); 13275 } 13276 setValue(key, value) { 13277 const obj = this.#storage.get(key); 13278 let modified = false; 13279 if (obj !== undefined) { 13280 for (const [entry, val] of Object.entries(value)) { 13281 if (obj[entry] !== val) { 13282 modified = true; 13283 obj[entry] = val; 13284 } 13285 } 13286 } else { 13287 modified = true; 13288 this.#storage.set(key, value); 13289 } 13290 if (modified) { 13291 this.#setModified(); 13292 } 13293 if (value instanceof AnnotationEditor) { 13294 (this.#editorsMap ||= new Map()).set(value.annotationElementId, value); 13295 this.onAnnotationEditor?.(value.constructor._type); 13296 } 13297 } 13298 has(key) { 13299 return this.#storage.has(key); 13300 } 13301 get size() { 13302 return this.#storage.size; 13303 } 13304 #setModified() { 13305 if (!this.#modified) { 13306 this.#modified = true; 13307 this.onSetModified?.(); 13308 } 13309 } 13310 resetModified() { 13311 if (this.#modified) { 13312 this.#modified = false; 13313 this.onResetModified?.(); 13314 } 13315 } 13316 get print() { 13317 return new PrintAnnotationStorage(this); 13318 } 13319 get serializable() { 13320 if (this.#storage.size === 0) { 13321 return SerializableEmpty; 13322 } 13323 const map = new Map(), 13324 hash = new MurmurHash3_64(), 13325 transfer = []; 13326 const context = Object.create(null); 13327 let hasBitmap = false; 13328 for (const [key, val] of this.#storage) { 13329 const serialized = val instanceof AnnotationEditor ? val.serialize(false, context) : val; 13330 if (val.page) { 13331 val.pageIndex = val.page._pageIndex; 13332 delete val.page; 13333 } 13334 if (serialized) { 13335 map.set(key, serialized); 13336 hash.update(`${key}:${JSON.stringify(serialized)}`); 13337 hasBitmap ||= !!serialized.bitmap; 13338 } 13339 } 13340 if (hasBitmap) { 13341 for (const value of map.values()) { 13342 if (value.bitmap) { 13343 transfer.push(value.bitmap); 13344 } 13345 } 13346 } 13347 return map.size > 0 ? { 13348 map, 13349 hash: hash.hexdigest(), 13350 transfer 13351 } : SerializableEmpty; 13352 } 13353 get editorStats() { 13354 let stats = null; 13355 const typeToEditor = new Map(); 13356 let numberOfEditedComments = 0; 13357 let numberOfDeletedComments = 0; 13358 for (const value of this.#storage.values()) { 13359 if (!(value instanceof AnnotationEditor)) { 13360 if (value.popup) { 13361 if (value.popup.deleted) { 13362 numberOfDeletedComments += 1; 13363 } else { 13364 numberOfEditedComments += 1; 13365 } 13366 } 13367 continue; 13368 } 13369 if (value.isCommentDeleted) { 13370 numberOfDeletedComments += 1; 13371 } else if (value.hasEditedComment) { 13372 numberOfEditedComments += 1; 13373 } 13374 const editorStats = value.telemetryFinalData; 13375 if (!editorStats) { 13376 continue; 13377 } 13378 const { 13379 type 13380 } = editorStats; 13381 typeToEditor.getOrInsertComputed(type, () => Object.getPrototypeOf(value).constructor); 13382 stats ||= Object.create(null); 13383 const map = stats[type] ||= new Map(); 13384 for (const [key, val] of Object.entries(editorStats)) { 13385 if (key === "type") { 13386 continue; 13387 } 13388 const counters = map.getOrInsertComputed(key, makeMap); 13389 counters.set(val, (counters.get(val) ?? 0) + 1); 13390 } 13391 } 13392 if (numberOfDeletedComments > 0 || numberOfEditedComments > 0) { 13393 stats ||= Object.create(null); 13394 stats.comments = { 13395 deleted: numberOfDeletedComments, 13396 edited: numberOfEditedComments 13397 }; 13398 } 13399 if (!stats) { 13400 return null; 13401 } 13402 for (const [type, editor] of typeToEditor) { 13403 stats[type] = editor.computeTelemetryFinalData(stats[type]); 13404 } 13405 return stats; 13406 } 13407 resetModifiedIds() { 13408 this.#modifiedIds = null; 13409 } 13410 updateEditor(annotationId, data) { 13411 const value = this.#editorsMap?.get(annotationId); 13412 if (value) { 13413 value.updateFromAnnotationLayer(data); 13414 return true; 13415 } 13416 return false; 13417 } 13418 getEditor(annotationId) { 13419 return this.#editorsMap?.get(annotationId) || null; 13420 } 13421 get modifiedIds() { 13422 if (this.#modifiedIds) { 13423 return this.#modifiedIds; 13424 } 13425 const ids = []; 13426 if (this.#editorsMap) { 13427 for (const value of this.#editorsMap.values()) { 13428 if (!value.serialize()) { 13429 continue; 13430 } 13431 ids.push(value.annotationElementId); 13432 } 13433 } 13434 let hash = ""; 13435 if (ids.length) { 13436 const h = new MurmurHash3_64(); 13437 h.update(ids.join(",")); 13438 hash = h.hexdigest(); 13439 } 13440 return this.#modifiedIds = { 13441 ids: new Set(ids), 13442 hash 13443 }; 13444 } 13445 [Symbol.iterator]() { 13446 return this.#storage.entries(); 13447 } 13448} 13449class PrintAnnotationStorage extends AnnotationStorage { 13450 #serializable = SerializableEmpty; 13451 constructor(parent) { 13452 super(); 13453 const { 13454 serializable 13455 } = parent; 13456 if (serializable === SerializableEmpty) { 13457 return; 13458 } 13459 const { 13460 map, 13461 hash, 13462 transfer 13463 } = serializable; 13464 const clone = structuredClone(map, transfer ? { 13465 transfer 13466 } : null); 13467 this.#serializable = { 13468 map: clone, 13469 hash, 13470 transfer: [] 13471 }; 13472 } 13473 get print() { 13474 unreachable("Should not call PrintAnnotationStorage.print"); 13475 } 13476 get serializable() { 13477 return this.#serializable; 13478 } 13479 get modifiedIds() { 13480 return shadow(this, "modifiedIds", { 13481 ids: new Set(), 13482 hash: "" 13483 }); 13484 } 13485} 13486
13487// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.for-each.js 13488var es_iterator_for_each = __webpack_require__(7588); 13489;// ./src/display/canvas_dependency_tracker.js 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500 13501 13502 13503 13504 13505 13506
vendor: 24,912 bytes, lines 13507-14296
13507 13508 13509 13510 13511const FORCED_DEPENDENCY_LABEL = "__forcedDependency"; 13512const { 13513 floor, 13514 ceil 13515} = Math; 13516function expandBBox(array, index, minX, minY, maxX, maxY) { 13517 array[index * 4 + 0] = Math.min(array[index * 4 + 0], minX); 13518 array[index * 4 + 1] = Math.min(array[index * 4 + 1], minY); 13519 array[index * 4 + 2] = Math.max(array[index * 4 + 2], maxX); 13520 array[index * 4 + 3] = Math.max(array[index * 4 + 3], maxY); 13521} 13522function scaleCharBBox(scaleX, scaleY, x, y, bbox) { 13523 let temp; 13524 if (scaleX) { 13525 if (scaleX < 0) { 13526 temp = bbox[0]; 13527 bbox[0] = bbox[2]; 13528 bbox[2] = temp; 13529 } 13530 bbox[0] *= scaleX; 13531 bbox[2] *= scaleX; 13532 if (scaleY < 0) { 13533 temp = bbox[1]; 13534 bbox[1] = bbox[3]; 13535 bbox[3] = temp; 13536 } 13537 bbox[1] *= scaleY; 13538 bbox[3] *= scaleY; 13539 } else { 13540 bbox.fill(0); 13541 } 13542 bbox[0] += x; 13543 bbox[1] += y; 13544 bbox[2] += x; 13545 bbox[3] += y; 13546} 13547const EMPTY_BBOX = new Uint32Array(new Uint8Array([255, 255, 0, 0]).buffer)[0]; 13548class BBoxReader { 13549 #bboxes; 13550 #coords; 13551 constructor(bboxes, coords) { 13552 this.#bboxes = bboxes; 13553 this.#coords = coords; 13554 } 13555 get length() { 13556 return this.#bboxes.length; 13557 } 13558 isEmpty(i) { 13559 return this.#bboxes[i] === EMPTY_BBOX; 13560 } 13561 minX(i) { 13562 return this.#coords[i * 4 + 0] / 256; 13563 } 13564 minY(i) { 13565 return this.#coords[i * 4 + 1] / 256; 13566 } 13567 maxX(i) { 13568 return (this.#coords[i * 4 + 2] + 1) / 256; 13569 } 13570 maxY(i) { 13571 return (this.#coords[i * 4 + 3] + 1) / 256; 13572 } 13573} 13574const ensureDebugMetadata = (map, key) => map?.getOrInsertComputed(key, () => ({ 13575 dependencies: new Set(), 13576 isRenderingOperation: false 13577})); 13578class CanvasBBoxTracker { 13579 #baseTransformStack = [[1, 0, 0, 1, 0, 0]]; 13580 #clipBox = [-Infinity, -Infinity, Infinity, Infinity]; 13581 #pendingBBox = new Float64Array(BBOX_INIT); 13582 _pendingBBoxIdx = -1; 13583 #canvasWidth; 13584 #canvasHeight; 13585 #bboxesCoords; 13586 #bboxes; 13587 _savesStack = []; 13588 _markedContentStack = []; 13589 constructor(canvas, operationsCount) { 13590 this.#canvasWidth = canvas.width; 13591 this.#canvasHeight = canvas.height; 13592 this.#initializeBBoxes(operationsCount); 13593 } 13594 growOperationsCount(operationsCount) { 13595 if (operationsCount >= this.#bboxes.length) { 13596 this.#initializeBBoxes(operationsCount, this.#bboxes); 13597 } 13598 } 13599 #initializeBBoxes(operationsCount, oldBBoxes) { 13600 const buffer = new ArrayBuffer(operationsCount * 4); 13601 this.#bboxesCoords = new Uint8ClampedArray(buffer); 13602 this.#bboxes = new Uint32Array(buffer); 13603 if (oldBBoxes && oldBBoxes.length > 0) { 13604 this.#bboxes.set(oldBBoxes); 13605 this.#bboxes.fill(EMPTY_BBOX, oldBBoxes.length); 13606 } else { 13607 this.#bboxes.fill(EMPTY_BBOX); 13608 } 13609 } 13610 get clipBox() { 13611 return this.#clipBox; 13612 } 13613 save(opIdx) { 13614 this.#clipBox = { 13615 __proto__: this.#clipBox 13616 }; 13617 this._savesStack.push(opIdx); 13618 return this; 13619 } 13620 restore(opIdx, onSavePopped) { 13621 const previous = Object.getPrototypeOf(this.#clipBox); 13622 if (previous === null) { 13623 return this; 13624 } 13625 this.#clipBox = previous; 13626 const lastSave = this._savesStack.pop(); 13627 if (lastSave !== undefined) { 13628 onSavePopped?.(lastSave, opIdx); 13629 this.#bboxes[opIdx] = this.#bboxes[lastSave]; 13630 } 13631 return this; 13632 } 13633 recordOpenMarker(idx) { 13634 this._savesStack.push(idx); 13635 return this; 13636 } 13637 getOpenMarker() { 13638 return this._savesStack.length === 0 ? null : this._savesStack.at(-1); 13639 } 13640 recordCloseMarker(opIdx, onSavePopped) { 13641 const lastSave = this._savesStack.pop(); 13642 if (lastSave !== undefined) { 13643 onSavePopped?.(lastSave, opIdx); 13644 this.#bboxes[opIdx] = this.#bboxes[lastSave]; 13645 } 13646 return this; 13647 } 13648 beginMarkedContent(opIdx) { 13649 this._markedContentStack.push(opIdx); 13650 return this; 13651 } 13652 endMarkedContent(opIdx, onSavePopped) { 13653 const lastSave = this._markedContentStack.pop(); 13654 if (lastSave !== undefined) { 13655 onSavePopped?.(lastSave, opIdx); 13656 this.#bboxes[opIdx] = this.#bboxes[lastSave]; 13657 } 13658 return this; 13659 } 13660 pushBaseTransform(ctx) { 13661 this.#baseTransformStack.push(Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform())); 13662 return this; 13663 } 13664 popBaseTransform() { 13665 if (this.#baseTransformStack.length > 1) { 13666 this.#baseTransformStack.pop(); 13667 } 13668 return this; 13669 } 13670 resetBBox(idx) { 13671 if (this._pendingBBoxIdx !== idx) { 13672 this._pendingBBoxIdx = idx; 13673 this.#pendingBBox.set(BBOX_INIT, 0); 13674 } 13675 return this; 13676 } 13677 recordClipBox(idx, ctx, minX, maxX, minY, maxY) { 13678 const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform()); 13679 const clipBox = BBOX_INIT.slice(); 13680 Util.axialAlignedBoundingBox([minX, minY, maxX, maxY], transform, clipBox); 13681 const intersection = Util.intersect(this.#clipBox, clipBox); 13682 if (intersection) { 13683 this.#clipBox[0] = intersection[0]; 13684 this.#clipBox[1] = intersection[1]; 13685 this.#clipBox[2] = intersection[2]; 13686 this.#clipBox[3] = intersection[3]; 13687 } else { 13688 this.#clipBox[0] = this.#clipBox[1] = Infinity; 13689 this.#clipBox[2] = this.#clipBox[3] = -Infinity; 13690 } 13691 return this; 13692 } 13693 recordBBox(idx, ctx, minX, maxX, minY, maxY) { 13694 const clipBox = this.#clipBox; 13695 if (clipBox[0] === Infinity) { 13696 return this; 13697 } 13698 const transform = Util.multiplyByDOMMatrix(this.#baseTransformStack.at(-1), ctx.getTransform()); 13699 if (clipBox[0] === -Infinity) { 13700 Util.axialAlignedBoundingBox([minX, minY, maxX, maxY], transform, this.#pendingBBox); 13701 return this; 13702 } 13703 const bbox = BBOX_INIT.slice(); 13704 Util.axialAlignedBoundingBox([minX, minY, maxX, maxY], transform, bbox); 13705 this.#pendingBBox[0] = MathClamp(bbox[0], clipBox[0], this.#pendingBBox[0]); 13706 this.#pendingBBox[1] = MathClamp(bbox[1], clipBox[1], this.#pendingBBox[1]); 13707 this.#pendingBBox[2] = MathClamp(bbox[2], this.#pendingBBox[2], clipBox[2]); 13708 this.#pendingBBox[3] = MathClamp(bbox[3], this.#pendingBBox[3], clipBox[3]); 13709 return this; 13710 } 13711 recordFullPageBBox(idx) { 13712 this.#pendingBBox[0] = Math.max(0, this.#clipBox[0]); 13713 this.#pendingBBox[1] = Math.max(0, this.#clipBox[1]); 13714 this.#pendingBBox[2] = Math.min(this.#canvasWidth, this.#clipBox[2]); 13715 this.#pendingBBox[3] = Math.min(this.#canvasHeight, this.#clipBox[3]); 13716 return this; 13717 } 13718 recordOperation(idx, preserve = false, dependencyLists) { 13719 if (this._pendingBBoxIdx !== idx) { 13720 return this; 13721 } 13722 const minX = floor(this.#pendingBBox[0] * 256 / this.#canvasWidth); 13723 const minY = floor(this.#pendingBBox[1] * 256 / this.#canvasHeight); 13724 const maxX = ceil(this.#pendingBBox[2] * 256 / this.#canvasWidth); 13725 const maxY = ceil(this.#pendingBBox[3] * 256 / this.#canvasHeight); 13726 expandBBox(this.#bboxesCoords, idx, minX, minY, maxX, maxY); 13727 if (dependencyLists) { 13728 for (const dependencies of dependencyLists) { 13729 for (const depIdx of dependencies) { 13730 if (depIdx !== idx) { 13731 expandBBox(this.#bboxesCoords, depIdx, minX, minY, maxX, maxY); 13732 } 13733 } 13734 } 13735 } 13736 if (!preserve) { 13737 this._pendingBBoxIdx = -1; 13738 } 13739 return this; 13740 } 13741 bboxToClipBoxDropOperation(idx) { 13742 if (this._pendingBBoxIdx === idx) { 13743 this._pendingBBoxIdx = -1; 13744 this.#clipBox[0] = Math.max(this.#clipBox[0], this.#pendingBBox[0]); 13745 this.#clipBox[1] = Math.max(this.#clipBox[1], this.#pendingBBox[1]); 13746 this.#clipBox[2] = Math.min(this.#clipBox[2], this.#pendingBBox[2]); 13747 this.#clipBox[3] = Math.min(this.#clipBox[3], this.#pendingBBox[3]); 13748 } 13749 return this; 13750 } 13751 take() { 13752 return new BBoxReader(this.#bboxes, this.#bboxesCoords); 13753 } 13754 takeDebugMetadata() { 13755 throw new Error("Unreachable"); 13756 } 13757 recordSimpleData(name, idx) { 13758 return this; 13759 } 13760 recordIncrementalData(name, idx) { 13761 return this; 13762 } 13763 resetIncrementalData(name, idx) { 13764 return this; 13765 } 13766 recordNamedData(name, idx) { 13767 return this; 13768 } 13769 recordSimpleDataFromNamed(name, depName, fallbackIdx) { 13770 return this; 13771 } 13772 recordFutureForcedDependency(name, idx) { 13773 return this; 13774 } 13775 inheritSimpleDataAsFutureForcedDependencies(names) { 13776 return this; 13777 } 13778 inheritPendingDependenciesAsFutureForcedDependencies() { 13779 return this; 13780 } 13781 recordCharacterBBox(idx, ctx, font, scale = 1, x = 0, y = 0, getMeasure) { 13782 return this; 13783 } 13784 getSimpleIndex(dependencyName) { 13785 return undefined; 13786 } 13787 recordDependencies(idx, dependencyNames) { 13788 return this; 13789 } 13790 recordNamedDependency(idx, name) { 13791 return this; 13792 } 13793 recordShowTextOperation(idx, preserve = false) { 13794 return this; 13795 } 13796} 13797class CanvasDependencyTracker { 13798 #simple = { 13799 __proto__: null 13800 }; 13801 #incremental = { 13802 __proto__: null, 13803 transform: [], 13804 moveText: [], 13805 sameLineText: [], 13806 [FORCED_DEPENDENCY_LABEL]: [] 13807 }; 13808 #namedDependencies = new Map(); 13809 #pendingDependencies = new Set(); 13810 #fontBBoxTrustworthy = new Map(); 13811 #debugMetadata; 13812 #recordDebugMetadataDepenencyAfterRestore; 13813 #bboxTracker; 13814 constructor(bboxTracker, recordDebugMetadata = false) { 13815 this.#bboxTracker = bboxTracker; 13816 if (recordDebugMetadata) { 13817 this.#debugMetadata = new Map(); 13818 this.#recordDebugMetadataDepenencyAfterRestore = (lastSave, opIdx) => { 13819 ensureDebugMetadata(this.#debugMetadata, opIdx).dependencies.add(lastSave); 13820 }; 13821 } 13822 } 13823 get clipBox() { 13824 return this.#bboxTracker.clipBox; 13825 } 13826 growOperationsCount(operationsCount) { 13827 this.#bboxTracker.growOperationsCount(operationsCount); 13828 } 13829 save(opIdx) { 13830 this.#simple = { 13831 __proto__: this.#simple 13832 }; 13833 this.#incremental = { 13834 __proto__: this.#incremental, 13835 transform: { 13836 __proto__: this.#incremental.transform 13837 }, 13838 moveText: { 13839 __proto__: this.#incremental.moveText 13840 }, 13841 sameLineText: { 13842 __proto__: this.#incremental.sameLineText 13843 }, 13844 [FORCED_DEPENDENCY_LABEL]: { 13845 __proto__: this.#incremental[FORCED_DEPENDENCY_LABEL] 13846 } 13847 }; 13848 this.#bboxTracker.save(opIdx); 13849 return this; 13850 } 13851 restore(opIdx) { 13852 this.#bboxTracker.restore(opIdx, this.#recordDebugMetadataDepenencyAfterRestore); 13853 const previous = Object.getPrototypeOf(this.#simple); 13854 if (previous === null) { 13855 return this; 13856 } 13857 this.#simple = previous; 13858 this.#incremental = Object.getPrototypeOf(this.#incremental); 13859 return this; 13860 } 13861 recordOpenMarker(opIdx) { 13862 this.#bboxTracker.recordOpenMarker(opIdx, this.#recordDebugMetadataDepenencyAfterRestore); 13863 return this; 13864 } 13865 getOpenMarker() { 13866 return this.#bboxTracker.getOpenMarker(); 13867 } 13868 recordCloseMarker(opIdx) { 13869 this.#bboxTracker.recordCloseMarker(opIdx, this.#recordDebugMetadataDepenencyAfterRestore); 13870 return this; 13871 } 13872 beginMarkedContent(opIdx) { 13873 this.#bboxTracker.beginMarkedContent(opIdx); 13874 return this; 13875 } 13876 endMarkedContent(opIdx) { 13877 this.#bboxTracker.endMarkedContent(opIdx, this.#recordDebugMetadataDepenencyAfterRestore); 13878 return this; 13879 } 13880 pushBaseTransform(ctx) { 13881 this.#bboxTracker.pushBaseTransform(ctx); 13882 return this; 13883 } 13884 popBaseTransform() { 13885 this.#bboxTracker.popBaseTransform(); 13886 return this; 13887 } 13888 recordSimpleData(name, idx) { 13889 this.#simple[name] = idx; 13890 return this; 13891 } 13892 recordIncrementalData(name, idx) { 13893 this.#incremental[name].push(idx); 13894 return this; 13895 } 13896 resetIncrementalData(name, idx) { 13897 this.#incremental[name].length = 0; 13898 return this; 13899 } 13900 recordNamedData(name, idx) { 13901 this.#namedDependencies.set(name, idx); 13902 return this; 13903 } 13904 recordSimpleDataFromNamed(name, depName, fallbackIdx) { 13905 this.#simple[name] = this.#namedDependencies.get(depName) ?? fallbackIdx; 13906 } 13907 recordFutureForcedDependency(name, idx) { 13908 this.recordIncrementalData(FORCED_DEPENDENCY_LABEL, idx); 13909 return this; 13910 } 13911 inheritSimpleDataAsFutureForcedDependencies(names) { 13912 for (const name of names) { 13913 if (name in this.#simple) { 13914 this.recordFutureForcedDependency(name, this.#simple[name]); 13915 } 13916 } 13917 return this; 13918 } 13919 inheritPendingDependenciesAsFutureForcedDependencies() { 13920 for (const dep of this.#pendingDependencies) { 13921 this.recordFutureForcedDependency(FORCED_DEPENDENCY_LABEL, dep); 13922 } 13923 return this; 13924 } 13925 resetBBox(idx) { 13926 this.#bboxTracker.resetBBox(idx); 13927 return this; 13928 } 13929 recordClipBox(idx, ctx, minX, maxX, minY, maxY) { 13930 this.#bboxTracker.recordClipBox(idx, ctx, minX, maxX, minY, maxY); 13931 return this; 13932 } 13933 recordBBox(idx, ctx, minX, maxX, minY, maxY) { 13934 this.#bboxTracker.recordBBox(idx, ctx, minX, maxX, minY, maxY); 13935 return this; 13936 } 13937 recordCharacterBBox(idx, ctx, font, scale = 1, x = 0, y = 0, getMeasure) { 13938 const fontBBox = font.bbox; 13939 let isBBoxTrustworthy; 13940 let computedBBox; 13941 if (fontBBox) { 13942 isBBoxTrustworthy = fontBBox[2] !== fontBBox[0] && fontBBox[3] !== fontBBox[1] && this.#fontBBoxTrustworthy.get(font); 13943 if (isBBoxTrustworthy !== false) { 13944 computedBBox = [0, 0, 0, 0]; 13945 Util.axialAlignedBoundingBox(fontBBox, font.fontMatrix, computedBBox); 13946 if (scale !== 1 || x !== 0 || y !== 0) { 13947 scaleCharBBox(scale, -scale, x, y, computedBBox); 13948 } 13949 if (isBBoxTrustworthy) { 13950 return this.recordBBox(idx, ctx, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]); 13951 } 13952 } 13953 } 13954 if (!getMeasure) { 13955 return this.recordFullPageBBox(idx); 13956 } 13957 const measure = getMeasure(); 13958 if (fontBBox && computedBBox && isBBoxTrustworthy === undefined) { 13959 isBBoxTrustworthy = computedBBox[0] <= x - measure.actualBoundingBoxLeft && computedBBox[2] >= x + measure.actualBoundingBoxRight && computedBBox[1] <= y - measure.actualBoundingBoxAscent && computedBBox[3] >= y + measure.actualBoundingBoxDescent; 13960 this.#fontBBoxTrustworthy.set(font, isBBoxTrustworthy); 13961 if (isBBoxTrustworthy) { 13962 return this.recordBBox(idx, ctx, computedBBox[0], computedBBox[2], computedBBox[1], computedBBox[3]); 13963 } 13964 } 13965 return this.recordBBox(idx, ctx, x - measure.actualBoundingBoxLeft, x + measure.actualBoundingBoxRight, y - measure.actualBoundingBoxAscent, y + measure.actualBoundingBoxDescent); 13966 } 13967 recordFullPageBBox(idx) { 13968 this.#bboxTracker.recordFullPageBBox(idx); 13969 return this; 13970 } 13971 getSimpleIndex(dependencyName) { 13972 return this.#simple[dependencyName]; 13973 } 13974 recordDependencies(idx, dependencyNames) { 13975 const pendingDependencies = this.#pendingDependencies; 13976 const simple = this.#simple; 13977 const incremental = this.#incremental; 13978 for (const name of dependencyNames) { 13979 if (name in this.#simple) { 13980 pendingDependencies.add(simple[name]); 13981 } else if (name in incremental) { 13982 incremental[name].forEach(pendingDependencies.add, pendingDependencies); 13983 } 13984 } 13985 return this; 13986 } 13987 recordNamedDependency(idx, name) { 13988 if (this.#namedDependencies.has(name)) { 13989 this.#pendingDependencies.add(this.#namedDependencies.get(name)); 13990 } 13991 return this; 13992 } 13993 recordOperation(idx, preserve = false) { 13994 this.recordDependencies(idx, [FORCED_DEPENDENCY_LABEL]); 13995 if (this.#debugMetadata) { 13996 const metadata = ensureDebugMetadata(this.#debugMetadata, idx); 13997 const { 13998 dependencies 13999 } = metadata; 14000 this.#pendingDependencies.forEach(dependencies.add, dependencies); 14001 this.#bboxTracker._savesStack.forEach(dependencies.add, dependencies); 14002 this.#bboxTracker._markedContentStack.forEach(dependencies.add, dependencies); 14003 dependencies.delete(idx); 14004 metadata.isRenderingOperation = true; 14005 } 14006 const needsCleanup = !preserve && idx === this.#bboxTracker._pendingBBoxIdx; 14007 this.#bboxTracker.recordOperation(idx, preserve, [this.#pendingDependencies, this.#bboxTracker._savesStack, this.#bboxTracker._markedContentStack]); 14008 if (needsCleanup) { 14009 this.#pendingDependencies.clear(); 14010 } 14011 return this; 14012 } 14013 recordShowTextOperation(idx, preserve = false) { 14014 const deps = Array.from(this.#pendingDependencies); 14015 this.recordOperation(idx, preserve); 14016 this.recordIncrementalData("sameLineText", idx); 14017 for (const dep of deps) { 14018 this.recordIncrementalData("sameLineText", dep); 14019 } 14020 return this; 14021 } 14022 bboxToClipBoxDropOperation(idx, preserve = false) { 14023 const needsCleanup = !preserve && idx === this.#bboxTracker._pendingBBoxIdx; 14024 this.#bboxTracker.bboxToClipBoxDropOperation(idx); 14025 if (needsCleanup) { 14026 this.#pendingDependencies.clear(); 14027 } 14028 return this; 14029 } 14030 take() { 14031 this.#fontBBoxTrustworthy.clear(); 14032 return this.#bboxTracker.take(); 14033 } 14034 takeDebugMetadata() { 14035 return this.#debugMetadata; 14036 } 14037} 14038class CanvasNestedDependencyTracker { 14039 #dependencyTracker; 14040 #opIdx; 14041 #ignoreBBoxes; 14042 #nestingLevel = 0; 14043 #savesLevel = 0; 14044 constructor(dependencyTracker, opIdx, ignoreBBoxes) { 14045 if (dependencyTracker instanceof CanvasNestedDependencyTracker && dependencyTracker.#ignoreBBoxes === !!ignoreBBoxes) { 14046 return dependencyTracker; 14047 } 14048 this.#dependencyTracker = dependencyTracker; 14049 this.#opIdx = opIdx; 14050 this.#ignoreBBoxes = !!ignoreBBoxes; 14051 } 14052 get clipBox() { 14053 return this.#dependencyTracker.clipBox; 14054 } 14055 growOperationsCount() { 14056 throw new Error("Unreachable"); 14057 } 14058 save(opIdx) { 14059 this.#savesLevel++; 14060 this.#dependencyTracker.save(this.#opIdx); 14061 return this; 14062 } 14063 restore(opIdx) { 14064 if (this.#savesLevel > 0) { 14065 this.#dependencyTracker.restore(this.#opIdx); 14066 this.#savesLevel--; 14067 } 14068 return this; 14069 } 14070 recordOpenMarker(idx) { 14071 this.#nestingLevel++; 14072 return this; 14073 } 14074 getOpenMarker() { 14075 return this.#nestingLevel > 0 ? this.#opIdx : this.#dependencyTracker.getOpenMarker(); 14076 } 14077 recordCloseMarker(idx) { 14078 this.#nestingLevel--; 14079 return this; 14080 } 14081 beginMarkedContent(opIdx) { 14082 return this; 14083 } 14084 endMarkedContent(opIdx) { 14085 return this; 14086 } 14087 pushBaseTransform(ctx) { 14088 this.#dependencyTracker.pushBaseTransform(ctx); 14089 return this; 14090 } 14091 popBaseTransform() { 14092 this.#dependencyTracker.popBaseTransform(); 14093 return this; 14094 } 14095 recordSimpleData(name, idx) { 14096 this.#dependencyTracker.recordSimpleData(name, this.#opIdx); 14097 return this; 14098 } 14099 recordIncrementalData(name, idx) { 14100 this.#dependencyTracker.recordIncrementalData(name, this.#opIdx); 14101 return this; 14102 } 14103 resetIncrementalData(name, idx) { 14104 this.#dependencyTracker.resetIncrementalData(name, this.#opIdx); 14105 return this; 14106 } 14107 recordNamedData(name, idx) { 14108 return this; 14109 } 14110 recordSimpleDataFromNamed(name, depName, fallbackIdx) { 14111 this.#dependencyTracker.recordSimpleDataFromNamed(name, depName, this.#opIdx); 14112 return this; 14113 } 14114 recordFutureForcedDependency(name, idx) { 14115 this.#dependencyTracker.recordFutureForcedDependency(name, this.#opIdx); 14116 return this; 14117 } 14118 inheritSimpleDataAsFutureForcedDependencies(names) { 14119 this.#dependencyTracker.inheritSimpleDataAsFutureForcedDependencies(names); 14120 return this; 14121 } 14122 inheritPendingDependenciesAsFutureForcedDependencies() { 14123 this.#dependencyTracker.inheritPendingDependenciesAsFutureForcedDependencies(); 14124 return this; 14125 } 14126 resetBBox(idx) { 14127 if (!this.#ignoreBBoxes) { 14128 this.#dependencyTracker.resetBBox(this.#opIdx); 14129 } 14130 return this; 14131 } 14132 recordClipBox(idx, ctx, minX, maxX, minY, maxY) { 14133 if (!this.#ignoreBBoxes) { 14134 this.#dependencyTracker.recordClipBox(this.#opIdx, ctx, minX, maxX, minY, maxY); 14135 } 14136 return this; 14137 } 14138 recordBBox(idx, ctx, minX, maxX, minY, maxY) { 14139 if (!this.#ignoreBBoxes) { 14140 this.#dependencyTracker.recordBBox(this.#opIdx, ctx, minX, maxX, minY, maxY); 14141 } 14142 return this; 14143 } 14144 recordCharacterBBox(idx, ctx, font, scale, x, y, getMeasure) { 14145 if (!this.#ignoreBBoxes) { 14146 this.#dependencyTracker.recordCharacterBBox(this.#opIdx, ctx, font, scale, x, y, getMeasure); 14147 } 14148 return this; 14149 } 14150 recordFullPageBBox(idx) { 14151 if (!this.#ignoreBBoxes) { 14152 this.#dependencyTracker.recordFullPageBBox(this.#opIdx); 14153 } 14154 return this; 14155 } 14156 getSimpleIndex(dependencyName) { 14157 return this.#dependencyTracker.getSimpleIndex(dependencyName); 14158 } 14159 recordDependencies(idx, dependencyNames) { 14160 this.#dependencyTracker.recordDependencies(this.#opIdx, dependencyNames); 14161 return this; 14162 } 14163 recordNamedDependency(idx, name) { 14164 this.#dependencyTracker.recordNamedDependency(this.#opIdx, name); 14165 return this; 14166 } 14167 recordOperation(idx) { 14168 this.#dependencyTracker.recordOperation(this.#opIdx, true); 14169 return this; 14170 } 14171 recordShowTextOperation(idx) { 14172 this.#dependencyTracker.recordShowTextOperation(this.#opIdx, true); 14173 return this; 14174 } 14175 bboxToClipBoxDropOperation(idx) { 14176 if (!this.#ignoreBBoxes) { 14177 this.#dependencyTracker.bboxToClipBoxDropOperation(this.#opIdx, true); 14178 } 14179 return this; 14180 } 14181 take() { 14182 throw new Error("Unreachable"); 14183 } 14184 takeDebugMetadata() { 14185 throw new Error("Unreachable"); 14186 } 14187} 14188const Dependencies = { 14189 stroke: ["path", "transform", "filter", "strokeColor", "strokeAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "dash"], 14190 fill: ["path", "transform", "filter", "fillColor", "fillAlpha", "globalCompositeOperation", "SMask"], 14191 imageXObject: ["transform", "SMask", "filter", "fillAlpha", "strokeAlpha", "globalCompositeOperation"], 14192 rawFillPath: ["filter", "fillColor", "fillAlpha"], 14193 showText: ["transform", "leading", "charSpacing", "wordSpacing", "hScale", "textRise", "moveText", "textMatrix", "font", "fontObj", "filter", "fillColor", "textRenderingMode", "SMask", "fillAlpha", "strokeAlpha", "globalCompositeOperation", "sameLineText"], 14194 transform: ["transform"], 14195 transformAndFill: ["transform", "fillColor"] 14196}; 14197class CanvasImagesTracker { 14198 #canvasWidth; 14199 #canvasHeight; 14200 #capacity = 4; 14201 #count = 0; 14202 #coords = new CanvasImagesTracker.#CoordsArray(this.#capacity * 6); 14203 static #CoordsArray = FeatureTest.isFloat16ArraySupported ? Float16Array : Float32Array; 14204 constructor(canvas) { 14205 this.#canvasWidth = canvas.width; 14206 this.#canvasHeight = canvas.height; 14207 } 14208 record(ctx, width, height, clipBox) { 14209 if (this.#count === this.#capacity) { 14210 this.#capacity *= 2; 14211 const newCoords = new CanvasImagesTracker.#CoordsArray(this.#capacity * 6); 14212 newCoords.set(this.#coords); 14213 this.#coords = newCoords; 14214 } 14215 const transform = getCurrentTransform(ctx); 14216 let coords; 14217 if (clipBox[0] !== Infinity) { 14218 const bbox = BBOX_INIT.slice(); 14219 Util.axialAlignedBoundingBox([0, -height, width, 0], transform, bbox); 14220 const finalBBox = Util.intersect(clipBox, bbox); 14221 if (!finalBBox) { 14222 return; 14223 } 14224 const [minX, minY, maxX, maxY] = finalBBox; 14225 if (minX !== bbox[0] || minY !== bbox[1] || maxX !== bbox[2] || maxY !== bbox[3]) { 14226 const rotationAngle = Math.atan2(transform[1], transform[0]); 14227 const sin = Math.abs(Math.sin(rotationAngle)); 14228 const cos = Math.abs(Math.cos(rotationAngle)); 14229 if (sin < 1e-6 || cos < 1e-6 || Math.abs(sin - cos) < 1e-6) { 14230 coords = [minX, minY, minX, maxY, maxX, minY]; 14231 } else { 14232 const finalBBoxWidth = maxX - minX; 14233 const finalBBoxHeight = maxY - minY; 14234 const sin2 = sin * sin; 14235 const cos2 = cos * cos; 14236 const cosSin = cos * sin; 14237 const denom = cos2 - sin2; 14238 const a = (finalBBoxHeight * cos2 - finalBBoxWidth * cosSin) / denom; 14239 const b = (finalBBoxHeight * cosSin - finalBBoxWidth * sin2) / denom; 14240 coords = [minX + b, minY, minX, minY + a, maxX, maxY - a]; 14241 } 14242 } 14243 } 14244 if (!coords) { 14245 coords = [0, -height, 0, 0, width, -height]; 14246 Util.applyTransform(coords, transform, 0); 14247 Util.applyTransform(coords, transform, 2); 14248 Util.applyTransform(coords, transform, 4); 14249 } 14250 coords[0] /= this.#canvasWidth; 14251 coords[1] /= this.#canvasHeight; 14252 coords[2] /= this.#canvasWidth; 14253 coords[3] /= this.#canvasHeight; 14254 coords[4] /= this.#canvasWidth; 14255 coords[5] /= this.#canvasHeight; 14256 this.#coords.set(coords, this.#count * 6); 14257 this.#count++; 14258 } 14259 take() { 14260 return this.#coords.subarray(0, this.#count * 6); 14261 } 14262} 14263 14264;// ./src/shared/css_utils.js 14265const CONTROL_CHAR_REGEXP = /\p{Cc}/u; 14266function isCSSString(str) { 14267 const quote = str[0]; 14268 if (str.length < 2 || quote !== `"` && quote !== `'` || str.at(-1) !== quote) { 14269 return false; 14270 } 14271 const end = str.length - 1; 14272 for (let i = 1; i < end; i++) { 14273 const char = str[i]; 14274 if (char === quote || CONTROL_CHAR_REGEXP.test(char)) { 14275 return false; 14276 } 14277 if (char === "\\") { 14278 if (++i >= end || CONTROL_CHAR_REGEXP.test(str[i])) { 14279 return false; 14280 } 14281 } 14282 } 14283 return true; 14284} 14285function serializeFontFamily(fontFamily) { 14286 if (isCSSString(fontFamily)) { 14287 return fontFamily; 14288 } 14289 const escaped = fontFamily.replaceAll(/["\\\p{Cc}]/gu, char => char === `"` || char === "\\" ? `\\${char}` : `\\${char.codePointAt(0).toString(16)} `); 14290 return `"${escaped}"`; 14291} 14292 14293;// ./src/display/font_loader.js 14294 14295 14296
14297 14298 14299 14300 14301 14302 14303 14304
vendor: 14,212 bytes, lines 14305-14722
14305 14306 14307 14308 14309class FontLoader { 14310 #systemFonts = new Set(); 14311 #styleSheet = null; 14312 constructor({ 14313 ownerDocument = globalThis.document, 14314 styleElement = null 14315 }) { 14316 this._document = ownerDocument; 14317 this.nativeFontFaces = new Set(); 14318 this.styleElement = null; 14319 this.loadingRequests = []; 14320 this.loadTestFontId = 0; 14321 } 14322 addNativeFontFace(nativeFontFace) { 14323 this.nativeFontFaces.add(nativeFontFace); 14324 this._document.fonts.add(nativeFontFace); 14325 } 14326 removeNativeFontFace(nativeFontFace) { 14327 this.nativeFontFaces.delete(nativeFontFace); 14328 this._document.fonts.delete(nativeFontFace); 14329 } 14330 insertRule(rule) { 14331 const styleSheet = this.#getStyleSheet(); 14332 styleSheet.insertRule(rule, styleSheet.cssRules.length); 14333 } 14334 #getStyleSheet() { 14335 if (this.#styleSheet) { 14336 return this.#styleSheet; 14337 } 14338 const StyleSheet = this._document.defaultView?.CSSStyleSheet || globalThis.CSSStyleSheet; 14339 if (!this.styleElement && StyleSheet) { 14340 const { 14341 adoptedStyleSheets 14342 } = this._document; 14343 if (adoptedStyleSheets) { 14344 const styleSheet = new StyleSheet(); 14345 adoptedStyleSheets.push(styleSheet); 14346 return this.#styleSheet = styleSheet; 14347 } 14348 } 14349 if (!this.styleElement) { 14350 this.styleElement = this._document.createElement("style"); 14351 this._document.documentElement.getElementsByTagName("head")[0].append(this.styleElement); 14352 } 14353 return this.#styleSheet = this.styleElement.sheet; 14354 } 14355 clear() { 14356 for (const nativeFontFace of this.nativeFontFaces) { 14357 this._document.fonts.delete(nativeFontFace); 14358 } 14359 this.nativeFontFaces.clear(); 14360 this.#systemFonts.clear(); 14361 if (this.#styleSheet) { 14362 const { 14363 adoptedStyleSheets 14364 } = this._document; 14365 if (adoptedStyleSheets?.includes(this.#styleSheet)) { 14366 this._document.adoptedStyleSheets = adoptedStyleSheets.filter(styleSheet => styleSheet !== this.#styleSheet); 14367 } 14368 this.#styleSheet = null; 14369 } 14370 if (this.styleElement) { 14371 this.styleElement.remove(); 14372 this.styleElement = null; 14373 } 14374 } 14375 async loadSystemFont({ 14376 systemFontInfo: info, 14377 disableFontFace, 14378 _inspectFont 14379 }) { 14380 if (!info || this.#systemFonts.has(info.loadedName)) { 14381 return; 14382 } 14383 assert(!disableFontFace, "loadSystemFont shouldn't be called when `disableFontFace` is set."); 14384 if (this.isFontLoadingAPISupported) { 14385 const { 14386 loadedName, 14387 src, 14388 style 14389 } = info; 14390 const fontFace = new FontFace(loadedName, src, style); 14391 this.addNativeFontFace(fontFace); 14392 try { 14393 await fontFace.load(); 14394 this.#systemFonts.add(loadedName); 14395 _inspectFont?.(info); 14396 } catch { 14397 warn(`Cannot load system font: ${info.baseFontName}, installing it could help to improve PDF rendering.`); 14398 this.removeNativeFontFace(fontFace); 14399 } 14400 return; 14401 } 14402 unreachable("Not implemented: loadSystemFont without the Font Loading API."); 14403 } 14404 async bind(font) { 14405 if (font.attached || font.missingFile && !font.systemFontInfo) { 14406 return; 14407 } 14408 font.attached = true; 14409 if (font.systemFontInfo) { 14410 await this.loadSystemFont(font); 14411 return; 14412 } 14413 if (this.isFontLoadingAPISupported) { 14414 const nativeFontFace = font.createNativeFontFace(); 14415 if (nativeFontFace) { 14416 this.addNativeFontFace(nativeFontFace); 14417 try { 14418 await nativeFontFace.loaded; 14419 } catch (ex) { 14420 warn(`Failed to load font '${nativeFontFace.family}': '${ex}'.`); 14421 font.disableFontFace = true; 14422 throw ex; 14423 } 14424 } 14425 return; 14426 } 14427 const rule = font.createFontFaceRule(); 14428 if (rule) { 14429 this.insertRule(rule); 14430 if (this.isSyncFontLoadingSupported) { 14431 return; 14432 } 14433 await new Promise(resolve => { 14434 const request = this._queueLoadingCallback(resolve); 14435 this._prepareFontLoadEvent(font, request); 14436 }); 14437 } 14438 } 14439 get isFontLoadingAPISupported() { 14440 const hasFonts = !!this._document?.fonts; 14441 return shadow(this, "isFontLoadingAPISupported", hasFonts); 14442 } 14443 get isSyncFontLoadingSupported() { 14444 return shadow(this, "isSyncFontLoadingSupported", isNodeJS || FeatureTest.platform.isFirefox); 14445 } 14446 _queueLoadingCallback(callback) { 14447 function completeRequest() { 14448 assert(!request.done, "completeRequest() cannot be called twice."); 14449 request.done = true; 14450 while (loadingRequests.length > 0 && loadingRequests[0].done) { 14451 const otherRequest = loadingRequests.shift(); 14452 setTimeout(otherRequest.callback, 0); 14453 } 14454 } 14455 const { 14456 loadingRequests 14457 } = this; 14458 const request = { 14459 done: false, 14460 complete: completeRequest, 14461 callback 14462 }; 14463 loadingRequests.push(request); 14464 return request; 14465 } 14466 get _loadTestFont() { 14467 const testFont = atob("T1RUTwALAIAAAwAwQ0ZGIDHtZg4AAAOYAAAAgUZGVE1lkzZwAAAEHAAAABxHREVGABQA" + "FQAABDgAAAAeT1MvMlYNYwkAAAEgAAAAYGNtYXABDQLUAAACNAAAAUJoZWFk/xVFDQAA" + "ALwAAAA2aGhlYQdkA+oAAAD0AAAAJGhtdHgD6AAAAAAEWAAAAAZtYXhwAAJQAAAAARgA" + "AAAGbmFtZVjmdH4AAAGAAAAAsXBvc3T/hgAzAAADeAAAACAAAQAAAAEAALZRFsRfDzz1" + "AAsD6AAAAADOBOTLAAAAAM4KHDwAAAAAA+gDIQAAAAgAAgAAAAAAAAABAAADIQAAAFoD" + "6AAAAAAD6AABAAAAAAAAAAAAAAAAAAAAAQAAUAAAAgAAAAQD6AH0AAUAAAKKArwAAACM" + "AooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAAQAAAAAAAAAAAAAAAFBmRWQAwAAuAC4D" + "IP84AFoDIQAAAAAAAQAAAAAAAAAAACAAIAABAAAADgCuAAEAAAAAAAAAAQAAAAEAAAAA" + "AAEAAQAAAAEAAAAAAAIAAQAAAAEAAAAAAAMAAQAAAAEAAAAAAAQAAQAAAAEAAAAAAAUA" + "AQAAAAEAAAAAAAYAAQAAAAMAAQQJAAAAAgABAAMAAQQJAAEAAgABAAMAAQQJAAIAAgAB" + "AAMAAQQJAAMAAgABAAMAAQQJAAQAAgABAAMAAQQJAAUAAgABAAMAAQQJAAYAAgABWABY" + "AAAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAAAC7//wAA" + "AC7////TAAEAAAAAAAABBgAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAD/gwAyAAAAAQAAAAAAAAAAAAAAAAAA" + "AAABAAQEAAEBAQJYAAEBASH4DwD4GwHEAvgcA/gXBIwMAYuL+nz5tQXkD5j3CBLnEQAC" + "AQEBIVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYAAABAQAADwACAQEEE/t3" + "Dov6fAH6fAT+fPp8+nwHDosMCvm1Cvm1DAz6fBQAAAAAAAABAAAAAMmJbzEAAAAAzgTj" + "FQAAAADOBOQpAAEAAAAAAAAADAAUAAQAAAABAAAAAgABAAAAAAAAAAAD6AAAAAAAAA=="); 14468 return shadow(this, "_loadTestFont", testFont); 14469 } 14470 _prepareFontLoadEvent(font, request) { 14471 function int32(data, offset) { 14472 return data.charCodeAt(offset) << 24 | data.charCodeAt(offset + 1) << 16 | data.charCodeAt(offset + 2) << 8 | data.charCodeAt(offset + 3) & 0xff; 14473 } 14474 function string32(value) { 14475 return String.fromCharCode(value >> 24 & 0xff, value >> 16 & 0xff, value >> 8 & 0xff, value & 0xff); 14476 } 14477 function spliceString(s, offset, remove, insert) { 14478 const chunk1 = s.substring(0, offset); 14479 const chunk2 = s.substring(offset + remove); 14480 return chunk1 + insert + chunk2; 14481 } 14482 let i, ii; 14483 const canvas = this._document.createElement("canvas"); 14484 canvas.width = 1; 14485 canvas.height = 1; 14486 const ctx = canvas.getContext("2d"); 14487 let called = 0; 14488 function isFontReady(name, callback) { 14489 if (++called > 30) { 14490 warn("Load test font never loaded."); 14491 callback(); 14492 return; 14493 } 14494 ctx.font = "30px " + name; 14495 ctx.fillText(".", 0, 20); 14496 const imageData = ctx.getImageData(0, 0, 1, 1); 14497 if (imageData.data[3] > 0) { 14498 callback(); 14499 return; 14500 } 14501 setTimeout(isFontReady.bind(null, name, callback)); 14502 } 14503 const loadTestFontId = `lt${Date.now()}${this.loadTestFontId++}`; 14504 let data = this._loadTestFont; 14505 const COMMENT_OFFSET = 976; 14506 data = spliceString(data, COMMENT_OFFSET, loadTestFontId.length, loadTestFontId); 14507 const CFF_CHECKSUM_OFFSET = 16; 14508 const XXXX_VALUE = 0x58585858; 14509 let checksum = int32(data, CFF_CHECKSUM_OFFSET); 14510 for (i = 0, ii = loadTestFontId.length - 3; i < ii; i += 4) { 14511 checksum = checksum - XXXX_VALUE + int32(loadTestFontId, i) | 0; 14512 } 14513 if (i < loadTestFontId.length) { 14514 checksum = checksum - XXXX_VALUE + int32(loadTestFontId + "XXX", i) | 0; 14515 } 14516 data = spliceString(data, CFF_CHECKSUM_OFFSET, 4, string32(checksum)); 14517 const url = `url(data:font/opentype;base64,${btoa(data)});`; 14518 const rule = `@font-face {font-family:"${loadTestFontId}";src:${url}}`; 14519 this.insertRule(rule); 14520 const div = this._document.createElement("div"); 14521 div.style.visibility = "hidden"; 14522 div.style.width = div.style.height = "10px"; 14523 div.style.position = "absolute"; 14524 div.style.top = div.style.left = "0px"; 14525 for (const name of [font.loadedName, loadTestFontId]) { 14526 const span = this._document.createElement("span"); 14527 span.textContent = "Hi"; 14528 span.style.fontFamily = name; 14529 div.append(span); 14530 } 14531 this._document.body.append(div); 14532 isFontReady(loadTestFontId, () => { 14533 div.remove(); 14534 request.complete(); 14535 }); 14536 } 14537} 14538class FontFaceObject { 14539 compiledGlyphs = Object.create(null); 14540 #fontData; 14541 constructor(translatedData, inspectFont = null, charProcOperatorList, extra) { 14542 this.#fontData = translatedData; 14543 this._inspectFont = inspectFont; 14544 if (charProcOperatorList) { 14545 this.charProcOperatorList = charProcOperatorList; 14546 } 14547 if (extra) { 14548 Object.assign(this, extra); 14549 } 14550 } 14551 createNativeFontFace() { 14552 if (!this.data || this.disableFontFace) { 14553 return null; 14554 } 14555 let nativeFontFace; 14556 if (!this.cssFontInfo) { 14557 nativeFontFace = new FontFace(this.loadedName, this.data, {}); 14558 } else { 14559 const css = { 14560 weight: this.cssFontInfo.fontWeight 14561 }; 14562 if (this.cssFontInfo.italicAngle) { 14563 css.style = `oblique ${this.cssFontInfo.italicAngle}deg`; 14564 } 14565 nativeFontFace = new FontFace(serializeFontFamily(this.cssFontInfo.fontFamily), this.data, css); 14566 } 14567 this._inspectFont?.(this); 14568 return nativeFontFace; 14569 } 14570 createFontFaceRule() { 14571 if (!this.data || this.disableFontFace) { 14572 return null; 14573 } 14574 const url = `url(data:${this.mimetype};base64,${this.data.toBase64()});`; 14575 let rule; 14576 if (!this.cssFontInfo) { 14577 rule = `@font-face {font-family:"${this.loadedName}";src:${url}}`; 14578 } else { 14579 let css = `font-weight: ${this.cssFontInfo.fontWeight};`; 14580 if (this.cssFontInfo.italicAngle) { 14581 css += `font-style: oblique ${this.cssFontInfo.italicAngle}deg;`; 14582 } 14583 const fontFamily = serializeFontFamily(this.cssFontInfo.fontFamily); 14584 rule = `@font-face {font-family:${fontFamily};${css}src:${url}}`; 14585 } 14586 this._inspectFont?.(this, url); 14587 return rule; 14588 } 14589 getPathGenerator(objs, character) { 14590 if (this.compiledGlyphs[character] !== undefined) { 14591 return this.compiledGlyphs[character]; 14592 } 14593 const objId = this.loadedName + "_path_" + character; 14594 let cmds; 14595 try { 14596 cmds = objs.get(objId); 14597 } catch (ex) { 14598 warn(`getPathGenerator - ignoring character: "${ex}".`); 14599 } 14600 const path = makePathFromDrawOPS(cmds?.path); 14601 if (!this.fontExtraProperties) { 14602 objs.delete(objId); 14603 } 14604 return this.compiledGlyphs[character] = path; 14605 } 14606 get black() { 14607 return this.#fontData.black; 14608 } 14609 get bold() { 14610 return this.#fontData.bold; 14611 } 14612 get disableFontFace() { 14613 return this.#fontData.disableFontFace; 14614 } 14615 set disableFontFace(value) { 14616 shadow(this, "disableFontFace", !!value); 14617 } 14618 get fontExtraProperties() { 14619 return this.#fontData.fontExtraProperties; 14620 } 14621 get isInvalidPDFjsFont() { 14622 return this.#fontData.isInvalidPDFjsFont; 14623 } 14624 get isType3Font() { 14625 return this.#fontData.isType3Font; 14626 } 14627 get italic() { 14628 return this.#fontData.italic; 14629 } 14630 get missingFile() { 14631 return this.#fontData.missingFile; 14632 } 14633 get remeasure() { 14634 return this.#fontData.remeasure; 14635 } 14636 get vertical() { 14637 return this.#fontData.vertical; 14638 } 14639 get ascent() { 14640 return this.#fontData.ascent; 14641 } 14642 get defaultWidth() { 14643 return this.#fontData.defaultWidth; 14644 } 14645 get descent() { 14646 return this.#fontData.descent; 14647 } 14648 get bbox() { 14649 return this.#fontData.bbox; 14650 } 14651 get fontMatrix() { 14652 return this.#fontData.fontMatrix; 14653 } 14654 get fallbackName() { 14655 return this.#fontData.fallbackName; 14656 } 14657 get loadedName() { 14658 return this.#fontData.loadedName; 14659 } 14660 get mimetype() { 14661 return this.#fontData.mimetype; 14662 } 14663 get name() { 14664 return this.#fontData.name; 14665 } 14666 get data() { 14667 return this.#fontData.data; 14668 } 14669 clearData() { 14670 this.#fontData.clearData(); 14671 } 14672 get cssFontInfo() { 14673 return this.#fontData.cssFontInfo; 14674 } 14675 get systemFontInfo() { 14676 return this.#fontData.systemFontInfo; 14677 } 14678 get defaultVMetrics() { 14679 return this.#fontData.defaultVMetrics; 14680 } 14681} 14682 14683;// ./src/shared/obj_bin_transform_utils.js 14684 14685class CSS_FONT_INFO { 14686 static strings = ["fontFamily", "fontWeight", "italicAngle"]; 14687} 14688class SYSTEM_FONT_INFO { 14689 static strings = ["css", "loadedName", "baseFontName", "src"]; 14690} 14691class FONT_INFO { 14692 static bools = ["black", "bold", "disableFontFace", "fontExtraProperties", "isInvalidPDFjsFont", "isType3Font", "italic", "missingFile", "remeasure", "vertical"]; 14693 static numbers = ["ascent", "defaultWidth", "descent"]; 14694 static strings = ["fallbackName", "loadedName", "mimetype", "name"]; 14695 static OFFSET_NUMBERS = Math.ceil(this.bools.length * 2 / 8); 14696 static OFFSET_BBOX = this.OFFSET_NUMBERS + this.numbers.length * 8; 14697 static OFFSET_FONT_MATRIX = this.OFFSET_BBOX + 1 + 2 * 4; 14698 static OFFSET_DEFAULT_VMETRICS = this.OFFSET_FONT_MATRIX + 1 + 8 * 6; 14699 static OFFSET_STRINGS = this.OFFSET_DEFAULT_VMETRICS + 1 + 2 * 3; 14700} 14701class PATTERN_INFO { 14702 static KIND = 0; 14703 static HAS_BBOX = 1; 14704 static HAS_BACKGROUND = 2; 14705 static SHADING_TYPE = 3; 14706 static N_COORD = 4; 14707 static N_COLOR = 8; 14708 static N_STOP = 12; 14709 static N_FIGURES = 16; 14710} 14711class InfoUtils { 14712 static get decoder() { 14713 return shadow(this, "decoder", new TextDecoder()); 14714 } 14715 static get encoder() { 14716 return shadow(this, "encoder", new TextEncoder()); 14717 } 14718} 14719 14720;// ./src/display/obj_bin_transform_display.js 14721 14722
vendor: 27,334 bytes, lines 14723-15684
14723 14724 14725 14726 14727 14728 14729class CssFontInfo { 14730 #buffer; 14731 #view; 14732 constructor(buffer) { 14733 this.#buffer = buffer; 14734 this.#view = new DataView(buffer); 14735 } 14736 #readString(index) { 14737 assert(index < CSS_FONT_INFO.strings.length, "Invalid string index"); 14738 const { 14739 decoder 14740 } = InfoUtils; 14741 let offset = 0; 14742 for (let i = 0; i < index; i++) { 14743 offset += this.#view.getUint32(offset) + 4; 14744 } 14745 const length = this.#view.getUint32(offset); 14746 return decoder.decode(new Uint8Array(this.#buffer, offset + 4, length)); 14747 } 14748 get fontFamily() { 14749 return this.#readString(0); 14750 } 14751 get fontWeight() { 14752 return this.#readString(1); 14753 } 14754 get italicAngle() { 14755 return this.#readString(2); 14756 } 14757} 14758class SystemFontInfo { 14759 #buffer; 14760 #view; 14761 constructor(buffer) { 14762 this.#buffer = buffer; 14763 this.#view = new DataView(buffer); 14764 } 14765 get guessFallback() { 14766 return this.#view.getUint8(0) !== 0; 14767 } 14768 #readString(index) { 14769 assert(index < SYSTEM_FONT_INFO.strings.length, "Invalid string index"); 14770 const { 14771 decoder 14772 } = InfoUtils; 14773 let offset = 5; 14774 for (let i = 0; i < index; i++) { 14775 offset += this.#view.getUint32(offset) + 4; 14776 } 14777 const length = this.#view.getUint32(offset); 14778 return decoder.decode(new Uint8Array(this.#buffer, offset + 4, length)); 14779 } 14780 get css() { 14781 return this.#readString(0); 14782 } 14783 get loadedName() { 14784 return this.#readString(1); 14785 } 14786 get baseFontName() { 14787 return this.#readString(2); 14788 } 14789 get src() { 14790 return this.#readString(3); 14791 } 14792 get style() { 14793 const { 14794 decoder 14795 } = InfoUtils; 14796 let offset = 1; 14797 offset += 4 + this.#view.getUint32(offset); 14798 const styleLength = this.#view.getUint32(offset); 14799 const style = decoder.decode(new Uint8Array(this.#buffer, offset + 4, styleLength)); 14800 offset += 4 + styleLength; 14801 const weightLength = this.#view.getUint32(offset); 14802 const weight = decoder.decode(new Uint8Array(this.#buffer, offset + 4, weightLength)); 14803 return { 14804 style, 14805 weight 14806 }; 14807 } 14808} 14809class FontInfo { 14810 #buffer; 14811 #view; 14812 constructor({ 14813 buffer, 14814 extra 14815 }) { 14816 this.#buffer = buffer; 14817 this.#view = new DataView(buffer); 14818 if (extra) { 14819 Object.assign(this, extra); 14820 } 14821 } 14822 #readBoolean(index) { 14823 assert(index < FONT_INFO.bools.length, "Invalid boolean index"); 14824 const byteOffset = Math.floor(index / 4); 14825 const bitOffset = index * 2 % 8; 14826 const value = this.#view.getUint8(byteOffset) >> bitOffset & 0x03; 14827 return value === 0x00 ? undefined : value === 0x02; 14828 } 14829 get black() { 14830 return this.#readBoolean(0); 14831 } 14832 get bold() { 14833 return this.#readBoolean(1); 14834 } 14835 get disableFontFace() { 14836 return this.#readBoolean(2); 14837 } 14838 get fontExtraProperties() { 14839 return this.#readBoolean(3); 14840 } 14841 get isInvalidPDFjsFont() { 14842 return this.#readBoolean(4); 14843 } 14844 get isType3Font() { 14845 return this.#readBoolean(5); 14846 } 14847 get italic() { 14848 return this.#readBoolean(6); 14849 } 14850 get missingFile() { 14851 return this.#readBoolean(7); 14852 } 14853 get remeasure() { 14854 return this.#readBoolean(8); 14855 } 14856 get vertical() { 14857 return this.#readBoolean(9); 14858 } 14859 #readNumber(index) { 14860 assert(index < FONT_INFO.numbers.length, "Invalid number index"); 14861 return this.#view.getFloat64(FONT_INFO.OFFSET_NUMBERS + index * 8); 14862 } 14863 get ascent() { 14864 return this.#readNumber(0); 14865 } 14866 get defaultWidth() { 14867 return this.#readNumber(1); 14868 } 14869 get descent() { 14870 return this.#readNumber(2); 14871 } 14872 #readArray(offset, arrLen, lookupName, increment) { 14873 const len = this.#view.getUint8(offset); 14874 if (len === 0) { 14875 return undefined; 14876 } 14877 assert(len === arrLen, "Invalid array length."); 14878 offset += 1; 14879 const arr = new Array(len); 14880 for (let i = 0; i < len; i++) { 14881 arr[i] = this.#view[lookupName](offset, true); 14882 offset += increment; 14883 } 14884 return arr; 14885 } 14886 get bbox() { 14887 return this.#readArray(FONT_INFO.OFFSET_BBOX, 4, "getInt16", 2); 14888 } 14889 get fontMatrix() { 14890 return this.#readArray(FONT_INFO.OFFSET_FONT_MATRIX, 6, "getFloat64", 8); 14891 } 14892 get defaultVMetrics() { 14893 return this.#readArray(FONT_INFO.OFFSET_DEFAULT_VMETRICS, 3, "getInt16", 2); 14894 } 14895 #readString(index) { 14896 assert(index < FONT_INFO.strings.length, "Invalid string index"); 14897 const { 14898 decoder 14899 } = InfoUtils; 14900 let offset = FONT_INFO.OFFSET_STRINGS + 4; 14901 for (let i = 0; i < index; i++) { 14902 offset += this.#view.getUint32(offset) + 4; 14903 } 14904 const length = this.#view.getUint32(offset); 14905 return decoder.decode(new Uint8Array(this.#buffer, offset + 4, length)); 14906 } 14907 get fallbackName() { 14908 return this.#readString(0); 14909 } 14910 get loadedName() { 14911 return this.#readString(1); 14912 } 14913 get mimetype() { 14914 return this.#readString(2); 14915 } 14916 get name() { 14917 return this.#readString(3); 14918 } 14919 #getDataOffsets() { 14920 let offset = FONT_INFO.OFFSET_STRINGS; 14921 const stringsLength = this.#view.getUint32(offset); 14922 offset += 4 + stringsLength; 14923 const systemFontInfoLength = this.#view.getUint32(offset); 14924 offset += 4 + systemFontInfoLength; 14925 const cssFontInfoLength = this.#view.getUint32(offset); 14926 offset += 4 + cssFontInfoLength; 14927 const length = this.#view.getUint32(offset); 14928 return { 14929 offset, 14930 length 14931 }; 14932 } 14933 get data() { 14934 const { 14935 offset, 14936 length 14937 } = this.#getDataOffsets(); 14938 return length === 0 ? undefined : new Uint8Array(this.#buffer, offset + 4, length); 14939 } 14940 clearData() { 14941 const { 14942 offset, 14943 length 14944 } = this.#getDataOffsets(); 14945 if (length === 0) { 14946 return; 14947 } 14948 this.#view.setUint32(offset, 0); 14949 this.#buffer = new Uint8Array(this.#buffer, 0, offset + 4).slice().buffer; 14950 this.#view = new DataView(this.#buffer); 14951 } 14952 get cssFontInfo() { 14953 let offset = FONT_INFO.OFFSET_STRINGS; 14954 const stringsLength = this.#view.getUint32(offset); 14955 offset += 4 + stringsLength; 14956 const systemFontInfoLength = this.#view.getUint32(offset); 14957 offset += 4 + systemFontInfoLength; 14958 const cssFontInfoLength = this.#view.getUint32(offset); 14959 if (cssFontInfoLength === 0) { 14960 return null; 14961 } 14962 const cssFontInfoData = new Uint8Array(cssFontInfoLength); 14963 cssFontInfoData.set(new Uint8Array(this.#buffer, offset + 4, cssFontInfoLength)); 14964 return new CssFontInfo(cssFontInfoData.buffer); 14965 } 14966 get systemFontInfo() { 14967 let offset = FONT_INFO.OFFSET_STRINGS; 14968 const stringsLength = this.#view.getUint32(offset); 14969 offset += 4 + stringsLength; 14970 const systemFontInfoLength = this.#view.getUint32(offset); 14971 if (systemFontInfoLength === 0) { 14972 return null; 14973 } 14974 const systemFontInfoData = new Uint8Array(systemFontInfoLength); 14975 systemFontInfoData.set(new Uint8Array(this.#buffer, offset + 4, systemFontInfoLength)); 14976 return new SystemFontInfo(systemFontInfoData.buffer); 14977 } 14978} 14979class PatternInfo { 14980 constructor(buffer) { 14981 this.buffer = buffer; 14982 this.view = new DataView(buffer); 14983 this.data = new Uint8Array(buffer); 14984 } 14985 getIR() { 14986 const dataView = this.view; 14987 const kind = this.data[PATTERN_INFO.KIND]; 14988 const hasBBox = !!this.data[PATTERN_INFO.HAS_BBOX]; 14989 const hasBackground = !!this.data[PATTERN_INFO.HAS_BACKGROUND]; 14990 const nCoord = dataView.getUint32(PATTERN_INFO.N_COORD, true); 14991 const nColor = dataView.getUint32(PATTERN_INFO.N_COLOR, true); 14992 const nStop = dataView.getUint32(PATTERN_INFO.N_STOP, true); 14993 let offset = 20; 14994 const coords = new Float32Array(this.buffer, offset, nCoord * 2); 14995 offset += nCoord * 8; 14996 const colors = new Uint8Array(this.buffer, offset, nColor * 4); 14997 offset += nColor * 4; 14998 const stops = []; 14999 for (let i = 0; i < nStop; ++i) { 15000 const p = dataView.getFloat32(offset, true); 15001 offset += 4; 15002 const rgb = dataView.getUint32(offset, true); 15003 offset += 4; 15004 stops.push([p, `#${rgb.toString(16).padStart(6, "0")}`]); 15005 } 15006 let bbox = null; 15007 if (hasBBox) { 15008 bbox = []; 15009 for (let i = 0; i < 4; ++i) { 15010 bbox.push(dataView.getFloat32(offset, true)); 15011 offset += 4; 15012 } 15013 } 15014 let background = null; 15015 if (hasBackground) { 15016 background = new Uint8Array(this.buffer, offset, 3); 15017 offset += 3; 15018 } 15019 if (kind === 1) { 15020 return ["RadialAxial", "axial", bbox, stops, Array.from(coords.slice(0, 2)), Array.from(coords.slice(2, 4)), null, null]; 15021 } 15022 if (kind === 2) { 15023 return ["RadialAxial", "radial", bbox, stops, [coords[0], coords[1]], [coords[3], coords[4]], coords[2], coords[5]]; 15024 } 15025 if (kind === 3) { 15026 const shadingType = this.data[PATTERN_INFO.SHADING_TYPE]; 15027 let bounds = null; 15028 if (coords.length > 0) { 15029 bounds = BBOX_INIT.slice(); 15030 for (let i = 0, ii = coords.length; i < ii; i += 2) { 15031 Util.pointBoundingBox(coords[i], coords[i + 1], bounds); 15032 } 15033 } 15034 return ["Mesh", shadingType, coords, colors, nCoord, bounds, bbox, background]; 15035 } 15036 throw new Error(`Unsupported pattern kind: ${kind}`); 15037 } 15038} 15039class FontPathInfo { 15040 #buffer; 15041 constructor(buffer) { 15042 this.#buffer = buffer; 15043 } 15044 get path() { 15045 if (FeatureTest.isFloat16ArraySupported) { 15046 return new Float16Array(this.#buffer); 15047 } 15048 return new Float32Array(this.#buffer); 15049 } 15050} 15051 15052;// ./src/display/api_utils.js 15053 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063function getUrlProp(val) { 15064 if (val instanceof URL) { 15065 return val; 15066 } 15067 if (typeof val === "string") { 15068 if (isNodeJS) { 15069 if (/^[a-z][a-z0-9\-+.]+:/i.test(val)) { 15070 return new URL(val); 15071 } 15072 const url = process.getBuiltinModule("url"); 15073 return new URL(url.pathToFileURL(val)); 15074 } 15075 const url = URL.parse(val, window.location); 15076 if (url) { 15077 return url; 15078 } 15079 } 15080 throw new Error("Invalid PDF url data: " + "either string or URL-object is expected in the url property."); 15081} 15082function getDataProp(val) { 15083 if (isNodeJS && typeof Buffer !== "undefined" && val instanceof Buffer) { 15084 throw new Error("Please provide binary data as `Uint8Array`, rather than `Buffer`."); 15085 } 15086 if (val instanceof Uint8Array && val.byteLength === val.buffer.byteLength) { 15087 return val; 15088 } 15089 if (typeof val === "string") { 15090 return stringToBytes(val); 15091 } 15092 if (val instanceof ArrayBuffer || ArrayBuffer.isView(val) || typeof val === "object" && !isNaN(val?.length)) { 15093 return new Uint8Array(val); 15094 } 15095 throw new Error("Invalid PDF binary data: either TypedArray, " + "string, or array-like object is expected in the data property."); 15096} 15097function getFactoryUrlProp(val) { 15098 if (typeof val !== "string") { 15099 return null; 15100 } 15101 if (val.endsWith("/")) { 15102 return val; 15103 } 15104 throw new Error(`Invalid factory url: "${val}" must include trailing slash.`); 15105} 15106const isRefProxy = v => typeof v === "object" && Number.isInteger(v?.num) && v.num >= 0 && Number.isInteger(v?.gen) && v.gen >= 0; 15107const isNameProxy = v => typeof v === "object" && typeof v?.name === "string"; 15108const isValidExplicitDest = _isValidExplicitDest.bind(null, isRefProxy, isNameProxy); 15109class LoopbackPort { 15110 #listeners = new Map(); 15111 #deferred = Promise.resolve(); 15112 postMessage(obj, transfer) { 15113 const event = { 15114 data: structuredClone(obj, transfer ? { 15115 transfer 15116 } : null) 15117 }; 15118 this.#deferred.then(() => { 15119 for (const [listener] of this.#listeners) { 15120 listener.call(this, event); 15121 } 15122 }); 15123 } 15124 addEventListener(name, listener, options = null) { 15125 let rmAbort = null; 15126 if (options?.signal instanceof AbortSignal) { 15127 const { 15128 signal 15129 } = options; 15130 if (signal.aborted) { 15131 warn("LoopbackPort - cannot use an `aborted` signal."); 15132 return; 15133 } 15134 const onAbort = () => this.removeEventListener(name, listener); 15135 rmAbort = () => signal.removeEventListener("abort", onAbort); 15136 signal.addEventListener("abort", onAbort); 15137 } 15138 this.#listeners.set(listener, rmAbort); 15139 } 15140 removeEventListener(name, listener) { 15141 const rmAbort = this.#listeners.get(listener); 15142 rmAbort?.(); 15143 this.#listeners.delete(listener); 15144 } 15145 terminate() { 15146 for (const [, rmAbort] of this.#listeners) { 15147 rmAbort?.(); 15148 } 15149 this.#listeners.clear(); 15150 } 15151} 15152 15153// EXTERNAL MODULE: ./node_modules/core-js/modules/es.promise.try.js 15154var es_promise_try = __webpack_require__(1689); 15155;// ./src/shared/message_handler.js 15156 15157 15158const CallbackKind = { 15159 DATA: 1, 15160 ERROR: 2 15161}; 15162const StreamKind = { 15163 CANCEL: 1, 15164 CANCEL_COMPLETE: 2, 15165 CLOSE: 3, 15166 ENQUEUE: 4, 15167 ERROR: 5, 15168 PULL: 6, 15169 PULL_COMPLETE: 7, 15170 START_COMPLETE: 8 15171}; 15172function onFn() {} 15173function wrapReason(ex) { 15174 if (ex instanceof AbortException || ex instanceof InvalidPDFException || ex instanceof PasswordException || ex instanceof ResponseException || ex instanceof UnknownErrorException) { 15175 return ex; 15176 } 15177 if (!(ex instanceof Error || typeof ex === "object" && ex !== null)) { 15178 unreachable('wrapReason: Expected "reason" to be a (possibly cloned) Error.'); 15179 } 15180 switch (ex.name) { 15181 case "AbortException": 15182 return new AbortException(ex.message); 15183 case "InvalidPDFException": 15184 return new InvalidPDFException(ex.message); 15185 case "PasswordException": 15186 return new PasswordException(ex.message, ex.code); 15187 case "ResponseException": 15188 return new ResponseException(ex.message, ex.status, ex.missing); 15189 case "UnknownErrorException": 15190 return new UnknownErrorException(ex.message, ex.details); 15191 } 15192 return new UnknownErrorException(ex.message, ex.toString()); 15193} 15194class MessageHandler { 15195 #messageAC = new AbortController(); 15196 constructor(sourceName, targetName, comObj) { 15197 this.sourceName = sourceName; 15198 this.targetName = targetName; 15199 this.comObj = comObj; 15200 this.callbackId = 1; 15201 this.streamId = 1; 15202 this.streamSinks = Object.create(null); 15203 this.streamControllers = Object.create(null); 15204 this.callbackCapabilities = Object.create(null); 15205 this.actionHandler = Object.create(null); 15206 comObj.addEventListener("message", this.#onMessage.bind(this), { 15207 signal: this.#messageAC.signal 15208 }); 15209 } 15210 #onMessage({ 15211 data 15212 }) { 15213 if (data.targetName !== this.sourceName) { 15214 return; 15215 } 15216 if (data.stream) { 15217 this.#processStreamMessage(data); 15218 return; 15219 } 15220 if (data.callback) { 15221 const callbackId = data.callbackId; 15222 const capability = this.callbackCapabilities[callbackId]; 15223 if (!capability) { 15224 throw new Error(`Cannot resolve callback ${callbackId}`); 15225 } 15226 delete this.callbackCapabilities[callbackId]; 15227 if (data.callback === CallbackKind.DATA) { 15228 capability.resolve(data.data); 15229 } else if (data.callback === CallbackKind.ERROR) { 15230 capability.reject(wrapReason(data.reason)); 15231 } else { 15232 throw new Error("Unexpected callback case"); 15233 } 15234 return; 15235 } 15236 const action = this.actionHandler[data.action]; 15237 if (!action) { 15238 throw new Error(`Unknown action from worker: ${data.action}`); 15239 } 15240 if (data.callbackId) { 15241 const sourceName = this.sourceName, 15242 targetName = data.sourceName, 15243 comObj = this.comObj; 15244 Promise.try(action, data.data).then(function (result) { 15245 comObj.postMessage({ 15246 sourceName, 15247 targetName, 15248 callback: CallbackKind.DATA, 15249 callbackId: data.callbackId, 15250 data: result 15251 }); 15252 }, function (reason) { 15253 comObj.postMessage({ 15254 sourceName, 15255 targetName, 15256 callback: CallbackKind.ERROR, 15257 callbackId: data.callbackId, 15258 reason: wrapReason(reason) 15259 }); 15260 }); 15261 return; 15262 } 15263 if (data.streamId) { 15264 this.#createStreamSink(data); 15265 return; 15266 } 15267 action(data.data); 15268 } 15269 on(actionName, handler) { 15270 const ah = this.actionHandler; 15271 if (ah[actionName]) { 15272 throw new Error(`There is already an actionName called "${actionName}"`); 15273 } 15274 ah[actionName] = handler; 15275 } 15276 send(actionName, data, transfers) { 15277 this.comObj.postMessage({ 15278 sourceName: this.sourceName, 15279 targetName: this.targetName, 15280 action: actionName, 15281 data 15282 }, transfers); 15283 } 15284 sendWithPromise(actionName, data, transfers) { 15285 const callbackId = this.callbackId++; 15286 const capability = Promise.withResolvers(); 15287 this.callbackCapabilities[callbackId] = capability; 15288 try { 15289 this.comObj.postMessage({ 15290 sourceName: this.sourceName, 15291 targetName: this.targetName, 15292 action: actionName, 15293 callbackId, 15294 data 15295 }, transfers); 15296 } catch (ex) { 15297 capability.reject(ex); 15298 } 15299 return capability.promise; 15300 } 15301 sendWithStream(actionName, data, queueingStrategy, transfers) { 15302 const streamId = this.streamId++, 15303 sourceName = this.sourceName, 15304 targetName = this.targetName, 15305 comObj = this.comObj; 15306 return new ReadableStream({ 15307 start: controller => { 15308 const startCapability = Promise.withResolvers(); 15309 this.streamControllers[streamId] = { 15310 controller, 15311 startCall: startCapability, 15312 pullCall: null, 15313 cancelCall: null, 15314 isClosed: false 15315 }; 15316 comObj.postMessage({ 15317 sourceName, 15318 targetName, 15319 action: actionName, 15320 streamId, 15321 data, 15322 desiredSize: controller.desiredSize 15323 }, transfers); 15324 return startCapability.promise; 15325 }, 15326 pull: controller => { 15327 const pullCapability = Promise.withResolvers(); 15328 this.streamControllers[streamId].pullCall = pullCapability; 15329 comObj.postMessage({ 15330 sourceName, 15331 targetName, 15332 stream: StreamKind.PULL, 15333 streamId, 15334 desiredSize: controller.desiredSize 15335 }); 15336 return pullCapability.promise; 15337 }, 15338 cancel: reason => { 15339 assert(reason instanceof Error, "cancel must have a valid reason"); 15340 const cancelCapability = Promise.withResolvers(); 15341 this.streamControllers[streamId].cancelCall = cancelCapability; 15342 this.streamControllers[streamId].isClosed = true; 15343 comObj.postMessage({ 15344 sourceName, 15345 targetName, 15346 stream: StreamKind.CANCEL, 15347 streamId, 15348 reason: wrapReason(reason) 15349 }); 15350 return cancelCapability.promise; 15351 } 15352 }, queueingStrategy); 15353 } 15354 #createStreamSink(data) { 15355 const streamId = data.streamId, 15356 sourceName = this.sourceName, 15357 targetName = data.sourceName, 15358 comObj = this.comObj; 15359 const self = this, 15360 action = this.actionHandler[data.action]; 15361 const streamSink = { 15362 enqueue(chunk, size = 1, transfers) { 15363 if (this.isCancelled) { 15364 return; 15365 } 15366 const lastDesiredSize = this.desiredSize; 15367 this.desiredSize -= size; 15368 if (lastDesiredSize > 0 && this.desiredSize <= 0) { 15369 this.sinkCapability = Promise.withResolvers(); 15370 this.ready = this.sinkCapability.promise; 15371 } 15372 comObj.postMessage({ 15373 sourceName, 15374 targetName, 15375 stream: StreamKind.ENQUEUE, 15376 streamId, 15377 chunk 15378 }, transfers); 15379 }, 15380 close() { 15381 if (this.isCancelled) { 15382 return; 15383 } 15384 this.isCancelled = true; 15385 comObj.postMessage({ 15386 sourceName, 15387 targetName, 15388 stream: StreamKind.CLOSE, 15389 streamId 15390 }); 15391 delete self.streamSinks[streamId]; 15392 }, 15393 error(reason) { 15394 assert(reason instanceof Error, "error must have a valid reason"); 15395 if (this.isCancelled) { 15396 return; 15397 } 15398 this.isCancelled = true; 15399 comObj.postMessage({ 15400 sourceName, 15401 targetName, 15402 stream: StreamKind.ERROR, 15403 streamId, 15404 reason: wrapReason(reason) 15405 }); 15406 }, 15407 sinkCapability: Promise.withResolvers(), 15408 onPull: null, 15409 onCancel: null, 15410 isCancelled: false, 15411 desiredSize: data.desiredSize, 15412 ready: null 15413 }; 15414 streamSink.sinkCapability.resolve(); 15415 streamSink.ready = streamSink.sinkCapability.promise; 15416 this.streamSinks[streamId] = streamSink; 15417 Promise.try(action, data.data, streamSink).then(function () { 15418 comObj.postMessage({ 15419 sourceName, 15420 targetName, 15421 stream: StreamKind.START_COMPLETE, 15422 streamId, 15423 success: true 15424 }); 15425 }, function (reason) { 15426 comObj.postMessage({ 15427 sourceName, 15428 targetName, 15429 stream: StreamKind.START_COMPLETE, 15430 streamId, 15431 reason: wrapReason(reason) 15432 }); 15433 }); 15434 } 15435 #processStreamMessage(data) { 15436 const streamId = data.streamId, 15437 sourceName = this.sourceName, 15438 targetName = data.sourceName, 15439 comObj = this.comObj; 15440 const streamController = this.streamControllers[streamId], 15441 streamSink = this.streamSinks[streamId]; 15442 switch (data.stream) { 15443 case StreamKind.START_COMPLETE: 15444 if (data.success) { 15445 streamController.startCall.resolve(); 15446 } else { 15447 streamController.startCall.reject(wrapReason(data.reason)); 15448 } 15449 break; 15450 case StreamKind.PULL_COMPLETE: 15451 if (data.success) { 15452 streamController.pullCall.resolve(); 15453 } else { 15454 streamController.pullCall.reject(wrapReason(data.reason)); 15455 } 15456 break; 15457 case StreamKind.PULL: 15458 if (!streamSink) { 15459 comObj.postMessage({ 15460 sourceName, 15461 targetName, 15462 stream: StreamKind.PULL_COMPLETE, 15463 streamId, 15464 success: true 15465 }); 15466 break; 15467 } 15468 if (streamSink.desiredSize <= 0 && data.desiredSize > 0) { 15469 streamSink.sinkCapability.resolve(); 15470 } 15471 streamSink.desiredSize = data.desiredSize; 15472 Promise.try(streamSink.onPull || onFn).then(function () { 15473 comObj.postMessage({ 15474 sourceName, 15475 targetName, 15476 stream: StreamKind.PULL_COMPLETE, 15477 streamId, 15478 success: true 15479 }); 15480 }, function (reason) { 15481 comObj.postMessage({ 15482 sourceName, 15483 targetName, 15484 stream: StreamKind.PULL_COMPLETE, 15485 streamId, 15486 reason: wrapReason(reason) 15487 }); 15488 }); 15489 break; 15490 case StreamKind.ENQUEUE: 15491 assert(streamController, "enqueue should have stream controller"); 15492 if (streamController.isClosed) { 15493 break; 15494 } 15495 streamController.controller.enqueue(data.chunk); 15496 break; 15497 case StreamKind.CLOSE: 15498 assert(streamController, "close should have stream controller"); 15499 if (streamController.isClosed) { 15500 break; 15501 } 15502 streamController.isClosed = true; 15503 streamController.controller.close(); 15504 this.#deleteStreamController(streamController, streamId); 15505 break; 15506 case StreamKind.ERROR: 15507 assert(streamController, "error should have stream controller"); 15508 streamController.controller.error(wrapReason(data.reason)); 15509 this.#deleteStreamController(streamController, streamId); 15510 break; 15511 case StreamKind.CANCEL_COMPLETE: 15512 if (data.success) { 15513 streamController.cancelCall.resolve(); 15514 } else { 15515 streamController.cancelCall.reject(wrapReason(data.reason)); 15516 } 15517 this.#deleteStreamController(streamController, streamId); 15518 break; 15519 case StreamKind.CANCEL: 15520 if (!streamSink) { 15521 break; 15522 } 15523 const dataReason = wrapReason(data.reason); 15524 Promise.try(streamSink.onCancel || onFn, dataReason).then(function () { 15525 comObj.postMessage({ 15526 sourceName, 15527 targetName, 15528 stream: StreamKind.CANCEL_COMPLETE, 15529 streamId, 15530 success: true 15531 }); 15532 }, function (reason) { 15533 comObj.postMessage({ 15534 sourceName, 15535 targetName, 15536 stream: StreamKind.CANCEL_COMPLETE, 15537 streamId, 15538 reason: wrapReason(reason) 15539 }); 15540 }); 15541 streamSink.sinkCapability.reject(dataReason); 15542 streamSink.isCancelled = true; 15543 delete this.streamSinks[streamId]; 15544 break; 15545 default: 15546 throw new Error("Unexpected stream case"); 15547 } 15548 } 15549 async #deleteStreamController(streamController, streamId) { 15550 await Promise.allSettled([streamController.startCall?.promise, streamController.pullCall?.promise, streamController.cancelCall?.promise]); 15551 delete this.streamControllers[streamId]; 15552 } 15553 destroy() { 15554 this.#messageAC?.abort(); 15555 this.#messageAC = null; 15556 } 15557} 15558 15559;// ./src/display/binary_data_factory.js 15560 15561 15562 15563 15564 15565 15566 15567class BaseBinaryDataFactory { 15568 #errorStr = Object.freeze({ 15569 cMapUrl: "CMap", 15570 standardFontDataUrl: "font", 15571 wasmUrl: "wasm" 15572 }); 15573 constructor({ 15574 cMapUrl = null, 15575 standardFontDataUrl = null, 15576 wasmUrl = null 15577 }) { 15578 this.cMapUrl = cMapUrl; 15579 this.standardFontDataUrl = standardFontDataUrl; 15580 this.wasmUrl = wasmUrl; 15581 } 15582 async fetch({ 15583 kind, 15584 filename 15585 }) { 15586 switch (kind) { 15587 case "cMapUrl": 15588 case "standardFontDataUrl": 15589 case "wasmUrl": 15590 break; 15591 default: 15592 unreachable(`Not implemented: ${kind}`); 15593 } 15594 const baseUrl = this[kind]; 15595 if (!baseUrl) { 15596 throw new Error(`Ensure that the \`${kind}\` API parameter is provided.`); 15597 } 15598 const url = `${baseUrl}${filename}`; 15599 return this._fetch(url, kind).catch(reason => { 15600 throw new Error(`Unable to load ${this.#errorStr[kind]} data at: ${url}`); 15601 }); 15602 } 15603 async _fetch(url, kind) { 15604 unreachable("Abstract method `_fetch` called."); 15605 } 15606} 15607class DOMBinaryDataFactory extends BaseBinaryDataFactory { 15608 async _fetch(url, kind) { 15609 const type = kind === "cMapUrl" && !url.endsWith(".bcmap") ? "text" : "bytes"; 15610 const data = await fetchData(url, type); 15611 return data instanceof Uint8Array ? data : stringToBytes(data); 15612 } 15613} 15614 15615;// ./src/display/canvas_factory.js 15616 15617class BaseCanvasFactory { 15618 #enableHWA = false; 15619 constructor({ 15620 enableHWA = false 15621 }) { 15622 this.#enableHWA = enableHWA; 15623 } 15624 create(width, height) { 15625 if (width <= 0 || height <= 0) { 15626 throw new Error("Invalid canvas size"); 15627 } 15628 const canvas = this._createCanvas(width, height); 15629 return { 15630 canvas, 15631 context: canvas.getContext("2d", { 15632 willReadFrequently: !this.#enableHWA 15633 }) 15634 }; 15635 } 15636 reset({ 15637 canvas 15638 }, width, height) { 15639 if (!canvas) { 15640 throw new Error("Canvas is not specified"); 15641 } 15642 if (width <= 0 || height <= 0) { 15643 throw new Error("Invalid canvas size"); 15644 } 15645 canvas.width = width; 15646 canvas.height = height; 15647 } 15648 destroy(canvasAndContext) { 15649 const { 15650 canvas 15651 } = canvasAndContext; 15652 if (!canvas) { 15653 throw new Error("Canvas is not specified"); 15654 } 15655 canvas.width = canvas.height = 0; 15656 canvasAndContext.canvas = null; 15657 canvasAndContext.context = null; 15658 } 15659 _createCanvas(width, height) { 15660 unreachable("Abstract method `_createCanvas` called."); 15661 } 15662} 15663class DOMCanvasFactory extends BaseCanvasFactory { 15664 constructor({ 15665 ownerDocument = globalThis.document, 15666 enableHWA = false 15667 }) { 15668 super({ 15669 enableHWA 15670 }); 15671 this._document = ownerDocument; 15672 } 15673 _createCanvas(width, height) { 15674 const canvas = this._document.createElement("canvas"); 15675 canvas.width = width; 15676 canvas.height = height; 15677 return canvas; 15678 } 15679} 15680 15681;// ./src/display/filter_factory.js 15682 15683 15684
vendor: 12,828 bytes, lines 15685-16093
15685 15686 15687 15688class BaseFilterFactory { 15689 addFilter(maps) { 15690 return "none"; 15691 } 15692 addHCMFilter(fgColor, bgColor) { 15693 return "none"; 15694 } 15695 addAlphaFilter(map) { 15696 return "none"; 15697 } 15698 addLuminosityFilter(map) { 15699 return "none"; 15700 } 15701 addKnockoutFilter(alpha = 0) { 15702 return "none"; 15703 } 15704 addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) { 15705 return "none"; 15706 } 15707 addSelectionHCMFilter(fgColor, bgColor) { 15708 return "none"; 15709 } 15710 addSelectionFilter() { 15711 return "none"; 15712 } 15713 createSelectionStyle(pageColors = null) { 15714 return null; 15715 } 15716 destroy(keepHCM = false) {} 15717} 15718class DOMFilterFactory extends BaseFilterFactory { 15719 #baseUrl; 15720 #_cache; 15721 #_defs; 15722 #docId; 15723 #document; 15724 #_hcmCache; 15725 #id = 0; 15726 constructor({ 15727 docId, 15728 ownerDocument = globalThis.document 15729 }) { 15730 super(); 15731 this.#docId = docId; 15732 this.#document = ownerDocument; 15733 } 15734 get #cache() { 15735 return this.#_cache ||= new Map(); 15736 } 15737 get #hcmCache() { 15738 return this.#_hcmCache ||= new Map(); 15739 } 15740 get #defs() { 15741 if (!this.#_defs) { 15742 const div = this.#document.createElement("div"); 15743 const { 15744 style 15745 } = div; 15746 style.colorScheme = "only light"; 15747 style.visibility = "hidden"; 15748 style.contain = "strict"; 15749 style.width = style.height = 0; 15750 style.position = "absolute"; 15751 style.top = style.left = 0; 15752 style.zIndex = -1; 15753 const svg = this.#document.createElementNS(SVG_NS, "svg"); 15754 svg.setAttribute("width", 0); 15755 svg.setAttribute("height", 0); 15756 this.#_defs = this.#document.createElementNS(SVG_NS, "defs"); 15757 div.append(svg); 15758 svg.append(this.#_defs); 15759 this.#document.body.append(div); 15760 } 15761 return this.#_defs; 15762 } 15763 #createTables(maps) { 15764 if (maps.length === 1) { 15765 const mapR = maps[0]; 15766 const buffer = new Array(256); 15767 for (let i = 0; i < 256; i++) { 15768 buffer[i] = mapR[i] / 255; 15769 } 15770 const table = buffer.join(","); 15771 return [table, table, table]; 15772 } 15773 const [mapR, mapG, mapB] = maps; 15774 const bufferR = new Array(256); 15775 const bufferG = new Array(256); 15776 const bufferB = new Array(256); 15777 for (let i = 0; i < 256; i++) { 15778 bufferR[i] = mapR[i] / 255; 15779 bufferG[i] = mapG[i] / 255; 15780 bufferB[i] = mapB[i] / 255; 15781 } 15782 return [bufferR.join(","), bufferG.join(","), bufferB.join(",")]; 15783 } 15784 #createUrl(id) { 15785 if (this.#baseUrl === undefined) { 15786 this.#baseUrl = ""; 15787 const url = this.#document.URL; 15788 if (url !== this.#document.baseURI) { 15789 if (isDataScheme(url)) { 15790 warn('#createUrl: ignore "data:"-URL for performance reasons.'); 15791 } else { 15792 this.#baseUrl = updateUrlHash(url, ""); 15793 } 15794 } 15795 } 15796 return `url(${this.#baseUrl}#${id})`; 15797 } 15798 addFilter(maps) { 15799 if (!maps) { 15800 return "none"; 15801 } 15802 let value = this.#cache.get(maps); 15803 if (value) { 15804 return value; 15805 } 15806 const [tableR, tableG, tableB] = this.#createTables(maps); 15807 const key = maps.length === 1 ? tableR : `${tableR}${tableG}${tableB}`; 15808 value = this.#cache.get(key); 15809 if (value) { 15810 this.#cache.set(maps, value); 15811 return value; 15812 } 15813 const id = `g_${this.#docId}_transfer_map_${this.#id++}`; 15814 const url = this.#createUrl(id); 15815 this.#cache.set(maps, url); 15816 this.#cache.set(key, url); 15817 const filter = this.#createFilter(id); 15818 this.#addTransferMapConversion(tableR, tableG, tableB, filter); 15819 return url; 15820 } 15821 addHCMFilter(fgColor, bgColor) { 15822 const key = `${fgColor}-${bgColor}`; 15823 const filterName = "base"; 15824 let info = this.#hcmCache.get(filterName); 15825 if (info?.key === key) { 15826 return info.url; 15827 } 15828 if (info) { 15829 info.filter?.remove(); 15830 info.key = key; 15831 info.url = "none"; 15832 info.filter = null; 15833 } else { 15834 info = { 15835 key, 15836 url: "none", 15837 filter: null 15838 }; 15839 this.#hcmCache.set(filterName, info); 15840 } 15841 if (!fgColor || !bgColor) { 15842 return info.url; 15843 } 15844 const fgRGB = this.#getRGB(fgColor); 15845 fgColor = Util.makeHexColor(...fgRGB); 15846 const bgRGB = this.#getRGB(bgColor); 15847 bgColor = Util.makeHexColor(...bgRGB); 15848 this.#resetDefsColor(); 15849 if (fgColor === "#000000" && bgColor === "#ffffff" || fgColor === bgColor) { 15850 return info.url; 15851 } 15852 const map = Array.from({ 15853 length: 256 15854 }, (_, i) => computeLuminance(i / 255)); 15855 const table = map.join(","); 15856 const id = `g_${this.#docId}_hcm_filter`; 15857 const filter = info.filter = this.#createFilter(id); 15858 this.#addTransferMapConversion(table, table, table, filter); 15859 this.#addGrayConversion(filter); 15860 const getSteps = (c, n) => { 15861 const start = fgRGB[c] / 255; 15862 const end = bgRGB[c] / 255; 15863 const arr = new Array(n + 1); 15864 for (let i = 0; i <= n; i++) { 15865 arr[i] = start + i / n * (end - start); 15866 } 15867 return arr.join(","); 15868 }; 15869 this.#addTransferMapConversion(getSteps(0, 5), getSteps(1, 5), getSteps(2, 5), filter); 15870 info.url = this.#createUrl(id); 15871 return info.url; 15872 } 15873 addSelectionHCMFilter(fgColor, bgColor) { 15874 return this.addHighlightHCMFilter("selection", fgColor, bgColor, "HighlightText", "Highlight"); 15875 } 15876 addSelectionFilter() { 15877 return this.addHighlightHCMFilter("selection_default", "black", "white", "HighlightText", "Highlight"); 15878 } 15879 createSelectionStyle(pageColors = null) { 15880 const filter = pageColors ? this.addSelectionHCMFilter(pageColors.foreground, pageColors.background) : this.addSelectionFilter(); 15881 if (filter === "none" || !FeatureTest.platform.isFirefox) { 15882 return null; 15883 } 15884 return { 15885 "backdrop-filter": filter, 15886 "background-color": "transparent" 15887 }; 15888 } 15889 addAlphaFilter(map) { 15890 let value = this.#cache.get(map); 15891 if (value) { 15892 return value; 15893 } 15894 const [tableA] = this.#createTables([map]); 15895 const key = `alpha_${tableA}`; 15896 value = this.#cache.get(key); 15897 if (value) { 15898 this.#cache.set(map, value); 15899 return value; 15900 } 15901 const id = `g_${this.#docId}_alpha_map_${this.#id++}`; 15902 const url = this.#createUrl(id); 15903 this.#cache.set(map, url); 15904 this.#cache.set(key, url); 15905 const filter = this.#createFilter(id); 15906 this.#addTransferMapAlphaConversion(tableA, filter); 15907 return url; 15908 } 15909 addLuminosityFilter(map) { 15910 let value = this.#cache.get(map || "luminosity"); 15911 if (value) { 15912 return value; 15913 } 15914 let tableA, key; 15915 if (map) { 15916 [tableA] = this.#createTables([map]); 15917 key = `luminosity_${tableA}`; 15918 } else { 15919 key = "luminosity"; 15920 } 15921 value = this.#cache.get(key); 15922 if (value) { 15923 this.#cache.set(map, value); 15924 return value; 15925 } 15926 const id = `g_${this.#docId}_luminosity_map_${this.#id++}`; 15927 const url = this.#createUrl(id); 15928 this.#cache.set(map, url); 15929 this.#cache.set(key, url); 15930 const filter = this.#createFilter(id); 15931 this.#addLuminosityConversion(filter); 15932 if (map) { 15933 this.#addTransferMapAlphaConversion(tableA, filter); 15934 } 15935 return url; 15936 } 15937 addKnockoutFilter(alpha = 0) { 15938 const slope = alpha > 0 ? Math.min(1 / alpha, 1e6) : 1e6; 15939 const key = `knockout_${slope}`; 15940 const value = this.#cache.get(key); 15941 if (value) { 15942 return value; 15943 } 15944 const id = `g_${this.#docId}_knockout_filter_${this.#id++}`; 15945 const url = this.#createUrl(id); 15946 this.#cache.set(key, url); 15947 const filter = this.#createFilter(id); 15948 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 15949 filter.append(feComponentTransfer); 15950 const feFuncA = this.#document.createElementNS(SVG_NS, "feFuncA"); 15951 feFuncA.setAttribute("type", "linear"); 15952 feFuncA.setAttribute("slope", `${slope}`); 15953 feFuncA.setAttribute("intercept", "0"); 15954 feComponentTransfer.append(feFuncA); 15955 return url; 15956 } 15957 addHighlightHCMFilter(filterName, fgColor, bgColor, newFgColor, newBgColor) { 15958 const key = `${fgColor}-${bgColor}-${newFgColor}-${newBgColor}`; 15959 let info = this.#hcmCache.get(filterName); 15960 if (info?.key === key) { 15961 return info.url; 15962 } 15963 if (info) { 15964 info.filter?.remove(); 15965 info.key = key; 15966 info.url = "none"; 15967 info.filter = null; 15968 } else { 15969 info = { 15970 key, 15971 url: "none", 15972 filter: null 15973 }; 15974 this.#hcmCache.set(filterName, info); 15975 } 15976 if (!fgColor || !bgColor) { 15977 return info.url; 15978 } 15979 const [fgRGB, bgRGB] = [fgColor, bgColor].map(this.#getRGB.bind(this)); 15980 let fgGray = Math.round(0.2126 * fgRGB[0] + 0.7152 * fgRGB[1] + 0.0722 * fgRGB[2]); 15981 let bgGray = Math.round(0.2126 * bgRGB[0] + 0.7152 * bgRGB[1] + 0.0722 * bgRGB[2]); 15982 let [newFgRGB, newBgRGB] = [newFgColor, newBgColor].map(this.#getOpaqueTextColor.bind(this)); 15983 if (bgGray < fgGray) { 15984 [fgGray, bgGray, newFgRGB, newBgRGB] = [bgGray, fgGray, newBgRGB, newFgRGB]; 15985 } 15986 this.#resetDefsColor(); 15987 const getSteps = (fg, bg, n) => { 15988 const arr = new Array(256); 15989 const step = (bgGray - fgGray) / n; 15990 const newStart = fg / 255; 15991 const newStep = (bg - fg) / (255 * n); 15992 let prev = 0; 15993 for (let i = 0; i <= n; i++) { 15994 const k = Math.round(fgGray + i * step); 15995 const value = newStart + i * newStep; 15996 for (let j = prev; j <= k; j++) { 15997 arr[j] = value; 15998 } 15999 prev = k + 1; 16000 } 16001 for (let i = prev; i < 256; i++) { 16002 arr[i] = arr[prev - 1]; 16003 } 16004 return arr.join(","); 16005 }; 16006 const id = `g_${this.#docId}_hcm_${filterName}_filter`; 16007 const filter = info.filter = this.#createFilter(id); 16008 this.#addGrayConversion(filter); 16009 this.#addTransferMapConversion(getSteps(newFgRGB[0], newBgRGB[0], 5), getSteps(newFgRGB[1], newBgRGB[1], 5), getSteps(newFgRGB[2], newBgRGB[2], 5), filter); 16010 info.url = this.#createUrl(id); 16011 return info.url; 16012 } 16013 destroy(keepHCM = false) { 16014 if (keepHCM && this.#_hcmCache?.size) { 16015 return; 16016 } 16017 this.#_defs?.parentNode.parentNode.remove(); 16018 this.#_defs = null; 16019 this.#_cache?.clear(); 16020 this.#_cache = null; 16021 this.#_hcmCache?.clear(); 16022 this.#_hcmCache = null; 16023 this.#id = 0; 16024 } 16025 #addLuminosityConversion(filter) { 16026 const feColorMatrix = this.#document.createElementNS(SVG_NS, "feColorMatrix"); 16027 feColorMatrix.setAttribute("type", "matrix"); 16028 feColorMatrix.setAttribute("values", "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0.59 0.11 0 0"); 16029 filter.append(feColorMatrix); 16030 } 16031 #addGrayConversion(filter) { 16032 const feColorMatrix = this.#document.createElementNS(SVG_NS, "feColorMatrix"); 16033 feColorMatrix.setAttribute("type", "matrix"); 16034 feColorMatrix.setAttribute("values", "0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"); 16035 filter.append(feColorMatrix); 16036 } 16037 #createFilter(id) { 16038 const filter = this.#document.createElementNS(SVG_NS, "filter"); 16039 filter.setAttribute("color-interpolation-filters", "sRGB"); 16040 filter.setAttribute("id", id); 16041 this.#defs.append(filter); 16042 return filter; 16043 } 16044 #appendFeFunc(feComponentTransfer, func, table) { 16045 const feFunc = this.#document.createElementNS(SVG_NS, func); 16046 feFunc.setAttribute("type", "discrete"); 16047 feFunc.setAttribute("tableValues", table); 16048 feComponentTransfer.append(feFunc); 16049 } 16050 #addTransferMapConversion(rTable, gTable, bTable, filter) { 16051 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 16052 filter.append(feComponentTransfer); 16053 this.#appendFeFunc(feComponentTransfer, "feFuncR", rTable); 16054 this.#appendFeFunc(feComponentTransfer, "feFuncG", gTable); 16055 this.#appendFeFunc(feComponentTransfer, "feFuncB", bTable); 16056 } 16057 #addTransferMapAlphaConversion(aTable, filter) { 16058 const feComponentTransfer = this.#document.createElementNS(SVG_NS, "feComponentTransfer"); 16059 filter.append(feComponentTransfer); 16060 this.#appendFeFunc(feComponentTransfer, "feFuncA", aTable); 16061 } 16062 #getRGB(color) { 16063 this.#defs.style.color = "CanvasText"; 16064 this.#defs.style.backgroundColor = color; 16065 return getRGB(getComputedStyle(this.#defs).getPropertyValue("background-color")); 16066 } 16067 #getRGBA(color) { 16068 this.#defs.style.color = "CanvasText"; 16069 this.#defs.style.backgroundColor = color; 16070 return getRGBA(getComputedStyle(this.#defs).getPropertyValue("background-color")); 16071 } 16072 #resetDefsColor() { 16073 this.#defs.style.color = ""; 16074 this.#defs.style.backgroundColor = ""; 16075 } 16076 #getOpaqueTextColor(color) { 16077 const [r, g, b, alpha] = this.#getRGBA(color); 16078 if (alpha === 1) { 16079 return [r, g, b]; 16080 } 16081 const [canvasR, canvasG, canvasB] = this.#getRGB("Canvas"); 16082 return [blend(r, canvasR, alpha), blend(g, canvasG, alpha), blend(b, canvasB, alpha)]; 16083 } 16084} 16085function blend(fg, bg, alpha) { 16086 return Math.round(alpha * fg + (1 - alpha) * bg); 16087} 16088 16089;// ./src/display/node_utils.js 16090 16091 16092 16093
16094 16095 16096 16097 16098 16099if (isNodeJS) { 16100 let canvas; 16101 try { 16102 const require = process.getBuiltinModule("module").createRequire(import.meta.url); 16103 try { 16104 canvas = require("@napi-rs/canvas"); 16105 } catch (ex) { 16106 warn(`Cannot load "@napi-rs/canvas" package: "${ex}".`); 16107 } 16108 } catch (ex) { 16109 warn(`Cannot access the \`require\` function: "${ex}".`); 16110 } 16111 if (!globalThis.DOMMatrix) { 16112 if (canvas?.DOMMatrix) { 16113 globalThis.DOMMatrix = canvas.DOMMatrix; 16114 } else { 16115 warn("Cannot polyfill `DOMMatrix`, rendering may be broken."); 16116 } 16117 } 16118 if (!globalThis.Path2D) { 16119 if (canvas?.Path2D) { 16120 globalThis.Path2D = canvas.Path2D; 16121 } else { 16122 warn("Cannot polyfill `Path2D`, rendering may be broken."); 16123 } 16124 } 16125 if (!globalThis.navigator?.language) { 16126 globalThis.navigator = { 16127 language: "en-US", 16128 platform: "", 16129 userAgent: "" 16130 }; 16131 } 16132} 16133async function node_utils_fetchData(url) { 16134 const fs = process.getBuiltinModule("fs/promises"); 16135 const data = await fs.readFile(url); 16136 return new Uint8Array(data); 16137} 16138class NodeFilterFactory extends BaseFilterFactory {} 16139class NodeCanvasFactory extends BaseCanvasFactory { 16140 _createCanvas(width, height) { 16141 const require = process.getBuiltinModule("module").createRequire(import.meta.url); 16142 const canvas = require("@napi-rs/canvas"); 16143 return canvas.createCanvas(width, height); 16144 } 16145} 16146class NodeBinaryDataFactory extends BaseBinaryDataFactory { 16147 async _fetch(url, kind) { 16148 return node_utils_fetchData(url); 16149 } 16150} 16151 16152;// ./src/shared/image_utils.js 16153/* unused harmony import specifier */ var image_utils_ImageKind; 16154/* unused harmony import specifier */ var image_utils_FeatureTest;
vendor: 3,493 bytes, lines 16155-16265
16155 16156 16157function convertToRGBA(params) { 16158 switch (params.kind) { 16159 case image_utils_ImageKind.GRAYSCALE_1BPP: 16160 return convertBlackAndWhiteToRGBA(params); 16161 case image_utils_ImageKind.RGB_24BPP: 16162 return convertRGBToRGBA(params); 16163 } 16164 return null; 16165} 16166function convertBlackAndWhiteToRGBA({ 16167 src, 16168 srcPos = 0, 16169 dest, 16170 width, 16171 height, 16172 nonBlackColor = 0xffffffff, 16173 inverseDecode = false 16174}) { 16175 const black = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff; 16176 const [zeroMapping, oneMapping] = inverseDecode ? [nonBlackColor, black] : [black, nonBlackColor]; 16177 const widthInSource = width >> 3; 16178 const widthRemainder = width & 7; 16179 const xorMask = zeroMapping ^ oneMapping; 16180 const srcLength = src.length; 16181 dest = new Uint32Array(dest.buffer); 16182 let destPos = 0; 16183 for (let i = 0; i < height; ++i) { 16184 for (const max = srcPos + widthInSource; srcPos < max; ++srcPos, destPos += 8) { 16185 const elem = src[srcPos]; 16186 dest[destPos] = zeroMapping ^ -(elem >> 7 & 1) & xorMask; 16187 dest[destPos + 1] = zeroMapping ^ -(elem >> 6 & 1) & xorMask; 16188 dest[destPos + 2] = zeroMapping ^ -(elem >> 5 & 1) & xorMask; 16189 dest[destPos + 3] = zeroMapping ^ -(elem >> 4 & 1) & xorMask; 16190 dest[destPos + 4] = zeroMapping ^ -(elem >> 3 & 1) & xorMask; 16191 dest[destPos + 5] = zeroMapping ^ -(elem >> 2 & 1) & xorMask; 16192 dest[destPos + 6] = zeroMapping ^ -(elem >> 1 & 1) & xorMask; 16193 dest[destPos + 7] = zeroMapping ^ -(elem & 1) & xorMask; 16194 } 16195 if (widthRemainder === 0) { 16196 continue; 16197 } 16198 const elem = srcPos < srcLength ? src[srcPos++] : 255; 16199 for (let j = 0; j < widthRemainder; ++j, ++destPos) { 16200 dest[destPos] = zeroMapping ^ -(elem >> 7 - j & 1) & xorMask; 16201 } 16202 } 16203 return { 16204 srcPos, 16205 destPos 16206 }; 16207} 16208function convertRGBToRGBA({ 16209 src, 16210 srcPos = 0, 16211 dest, 16212 destPos = 0, 16213 width, 16214 height 16215}) { 16216 let i = 0; 16217 const len = width * height * 3; 16218 const len32 = len >> 2; 16219 const src32 = new Uint32Array(src.buffer, srcPos, len32); 16220 const alphaMask = FeatureTest.isLittleEndian ? 0xff000000 : 0xff; 16221 if (FeatureTest.isLittleEndian) { 16222 for (; i < len32 - 2; i += 3, destPos += 4) { 16223 const s1 = src32[i], 16224 s2 = src32[i + 1], 16225 s3 = src32[i + 2]; 16226 dest[destPos] = s1 | alphaMask; 16227 dest[destPos + 1] = s1 >>> 24 | s2 << 8 | alphaMask; 16228 dest[destPos + 2] = s2 >>> 16 | s3 << 16 | alphaMask; 16229 dest[destPos + 3] = s3 >>> 8 | alphaMask; 16230 } 16231 for (let j = i * 4, jj = srcPos + len; j < jj; j += 3) { 16232 dest[destPos++] = src[j] | src[j + 1] << 8 | src[j + 2] << 16 | alphaMask; 16233 } 16234 } else { 16235 for (; i < len32 - 2; i += 3, destPos += 4) { 16236 const s1 = src32[i], 16237 s2 = src32[i + 1], 16238 s3 = src32[i + 2]; 16239 dest[destPos] = s1 | alphaMask; 16240 dest[destPos + 1] = s1 << 24 | s2 >>> 8 | alphaMask; 16241 dest[destPos + 2] = s2 << 16 | s3 >>> 16 | alphaMask; 16242 dest[destPos + 3] = s3 << 8 | alphaMask; 16243 } 16244 for (let j = i * 4, jj = srcPos + len; j < jj; j += 3) { 16245 dest[destPos++] = src[j] << 24 | src[j + 1] << 16 | src[j + 2] << 8 | alphaMask; 16246 } 16247 } 16248 return { 16249 srcPos: srcPos + len, 16250 destPos 16251 }; 16252} 16253function grayToRGBA(src, dest) { 16254 if (image_utils_FeatureTest.isLittleEndian) { 16255 for (let i = 0, ii = src.length; i < ii; i++) { 16256 dest[i] = src[i] * 0x10101 | 0xff000000; 16257 } 16258 } else { 16259 for (let i = 0, ii = src.length; i < ii; i++) { 16260 dest[i] = src[i] * 0x1010100 | 0x000000ff; 16261 } 16262 } 16263} 16264 16265;// ./src/display/webgpu.js
vendor: 5,490 bytes, lines 16266-16474
16266 16267const MESH_WGSL = ` 16268struct Uniforms { 16269 offsetX : f32, 16270 offsetY : f32, 16271 scaleX : f32, 16272 scaleY : f32, 16273 paddedWidth : f32, 16274 paddedHeight : f32, 16275 borderSize : f32, 16276 _pad : f32, 16277}; 16278 16279@group(0) @binding(0) var<uniform> u : Uniforms; 16280 16281struct VertexInput { 16282 @location(0) position : vec2<f32>, 16283 @location(1) color : vec4<f32>, 16284}; 16285 16286struct VertexOutput { 16287 @builtin(position) position : vec4<f32>, 16288 @location(0) color : vec3<f32>, 16289}; 16290 16291@vertex 16292fn vs_main(in : VertexInput) -> VertexOutput { 16293 var out : VertexOutput; 16294 let cx = (in.position.x + u.offsetX) * u.scaleX; 16295 let cy = (in.position.y + u.offsetY) * u.scaleY; 16296 out.position = vec4<f32>( 16297 ((cx + u.borderSize) / u.paddedWidth) * 2.0 - 1.0, 16298 1.0 - ((cy + u.borderSize) / u.paddedHeight) * 2.0, 16299 0.0, 16300 1.0 16301 ); 16302 out.color = in.color.rgb; 16303 return out; 16304} 16305 16306@fragment 16307fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> { 16308 return vec4<f32>(in.color, 1.0); 16309} 16310`; 16311class WebGPU { 16312 #initPromise = null; 16313 #device = null; 16314 #meshPipeline = null; 16315 #preferredFormat = null; 16316 async #initGPU() { 16317 if (!globalThis.navigator?.gpu) { 16318 return false; 16319 } 16320 try { 16321 const adapter = await navigator.gpu.requestAdapter(); 16322 if (!adapter) { 16323 return false; 16324 } 16325 this.#preferredFormat = navigator.gpu.getPreferredCanvasFormat(); 16326 this.#device = await adapter.requestDevice(); 16327 return true; 16328 } catch { 16329 return false; 16330 } 16331 } 16332 init() { 16333 return this.#initPromise ||= this.#initGPU(); 16334 } 16335 get isReady() { 16336 return this.#device !== null; 16337 } 16338 loadMeshShader() { 16339 if (!this.#device || this.#meshPipeline) { 16340 return; 16341 } 16342 const shaderModule = this.#device.createShaderModule({ 16343 code: MESH_WGSL 16344 }); 16345 this.#meshPipeline = this.#device.createRenderPipeline({ 16346 layout: "auto", 16347 vertex: { 16348 module: shaderModule, 16349 entryPoint: "vs_main", 16350 buffers: [{ 16351 arrayStride: 2 * 4, 16352 attributes: [{ 16353 shaderLocation: 0, 16354 offset: 0, 16355 format: "float32x2" 16356 }] 16357 }, { 16358 arrayStride: 4, 16359 attributes: [{ 16360 shaderLocation: 1, 16361 offset: 0, 16362 format: "unorm8x4" 16363 }] 16364 }] 16365 }, 16366 fragment: { 16367 module: shaderModule, 16368 entryPoint: "fs_main", 16369 targets: [{ 16370 format: this.#preferredFormat 16371 }] 16372 }, 16373 primitive: { 16374 topology: "triangle-list" 16375 } 16376 }); 16377 } 16378 draw(posData, colData, vertexCount, context, backgroundColor, paddedWidth, paddedHeight, borderSize) { 16379 this.loadMeshShader(); 16380 const device = this.#device; 16381 const { 16382 offsetX, 16383 offsetY, 16384 scaleX, 16385 scaleY 16386 } = context; 16387 const posBuffer = device.createBuffer({ 16388 size: Math.max(posData.byteLength, 4), 16389 usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST 16390 }); 16391 if (posData.byteLength > 0) { 16392 device.queue.writeBuffer(posBuffer, 0, posData); 16393 } 16394 const colBuffer = device.createBuffer({ 16395 size: Math.max(colData.byteLength, 4), 16396 usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST 16397 }); 16398 if (colData.byteLength > 0) { 16399 device.queue.writeBuffer(colBuffer, 0, colData); 16400 } 16401 const uniformBuffer = device.createBuffer({ 16402 size: 8 * 4, 16403 usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST 16404 }); 16405 device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([offsetX, offsetY, scaleX, scaleY, paddedWidth, paddedHeight, borderSize, 0])); 16406 const bindGroup = device.createBindGroup({ 16407 layout: this.#meshPipeline.getBindGroupLayout(0), 16408 entries: [{ 16409 binding: 0, 16410 resource: { 16411 buffer: uniformBuffer 16412 } 16413 }] 16414 }); 16415 const offscreen = new OffscreenCanvas(paddedWidth, paddedHeight); 16416 const gpuCtx = offscreen.getContext("webgpu"); 16417 gpuCtx.configure({ 16418 device, 16419 format: this.#preferredFormat, 16420 alphaMode: backgroundColor ? "opaque" : "premultiplied" 16421 }); 16422 const clearValue = backgroundColor ? { 16423 r: backgroundColor[0] / 255, 16424 g: backgroundColor[1] / 255, 16425 b: backgroundColor[2] / 255, 16426 a: 1 16427 } : { 16428 r: 0, 16429 g: 0, 16430 b: 0, 16431 a: 0 16432 }; 16433 const commandEncoder = device.createCommandEncoder(); 16434 const renderPass = commandEncoder.beginRenderPass({ 16435 colorAttachments: [{ 16436 view: gpuCtx.getCurrentTexture().createView(), 16437 clearValue, 16438 loadOp: "clear", 16439 storeOp: "store" 16440 }] 16441 }); 16442 if (vertexCount > 0) { 16443 renderPass.setPipeline(this.#meshPipeline); 16444 renderPass.setBindGroup(0, bindGroup); 16445 renderPass.setVertexBuffer(0, posBuffer); 16446 renderPass.setVertexBuffer(1, colBuffer); 16447 renderPass.draw(vertexCount); 16448 } 16449 renderPass.end(); 16450 device.queue.submit([commandEncoder.finish()]); 16451 posBuffer.destroy(); 16452 colBuffer.destroy(); 16453 uniformBuffer.destroy(); 16454 return offscreen.transferToImageBitmap(); 16455 } 16456} 16457const _webGPU = new WebGPU(); 16458function initGPU() { 16459 return _webGPU.init(); 16460} 16461function isGPUReady() { 16462 return _webGPU.isReady; 16463} 16464function loadMeshShader() { 16465 _webGPU.loadMeshShader(); 16466} 16467function drawMeshWithGPU(posData, colData, vertexCount, context, backgroundColor, paddedWidth, paddedHeight, borderSize) { 16468 return _webGPU.draw(posData, colData, vertexCount, context, backgroundColor, paddedWidth, paddedHeight, borderSize); 16469} 16470 16471;// ./src/display/pattern_helper.js 16472 16473 16474
vendor: 21,296 bytes, lines 16475-17091
16475 16476 16477 16478 16479 16480const PathType = { 16481 FILL: "Fill", 16482 STROKE: "Stroke", 16483 SHADING: "Shading" 16484}; 16485function applyBoundingBox(ctx, bbox) { 16486 if (!bbox) { 16487 return; 16488 } 16489 const width = bbox[2] - bbox[0]; 16490 const height = bbox[3] - bbox[1]; 16491 const region = new Path2D(); 16492 region.rect(bbox[0], bbox[1], width, height); 16493 ctx.clip(region); 16494} 16495class BaseShadingPattern { 16496 matrix = null; 16497 isModifyingCurrentTransform() { 16498 return false; 16499 } 16500 getPattern() { 16501 unreachable("Abstract method `getPattern` called."); 16502 } 16503} 16504class RadialAxialShadingPattern extends BaseShadingPattern { 16505 constructor(IR) { 16506 super(); 16507 this._type = IR[1]; 16508 this._bbox = IR[2]; 16509 this._colorStops = IR[3]; 16510 this._p0 = IR[4]; 16511 this._p1 = IR[5]; 16512 this._r0 = IR[6]; 16513 this._r1 = IR[7]; 16514 } 16515 isOriginBased() { 16516 return this._p0[0] === 0 && this._p0[1] === 0 && (!this.isRadial() || this._p1[0] === 0 && this._p1[1] === 0); 16517 } 16518 isRadial() { 16519 return this._type === "radial"; 16520 } 16521 areConic() { 16522 if (!this.isRadial()) { 16523 return false; 16524 } 16525 const dist = Math.hypot(this._p0[0] - this._p1[0], this._p0[1] - this._p1[1]); 16526 return dist + this._r1 > this._r0 && dist + this._r0 > this._r1; 16527 } 16528 _createGradient(ctx, transform = null) { 16529 let grad; 16530 let firstPoint = this._p0; 16531 let secondPoint = this._p1; 16532 if (transform) { 16533 firstPoint = firstPoint.slice(); 16534 secondPoint = secondPoint.slice(); 16535 Util.applyTransform(firstPoint, transform); 16536 Util.applyTransform(secondPoint, transform); 16537 } 16538 if (this._type === "axial") { 16539 grad = ctx.createLinearGradient(firstPoint[0], firstPoint[1], secondPoint[0], secondPoint[1]); 16540 } else if (this._type === "radial") { 16541 let r0 = this._r0; 16542 let r1 = this._r1; 16543 if (transform) { 16544 const scale = new Float32Array(2); 16545 Util.singularValueDecompose2dScale(transform, scale); 16546 r0 *= scale[0]; 16547 r1 *= scale[0]; 16548 } 16549 grad = ctx.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1); 16550 } 16551 for (const colorStop of this._colorStops) { 16552 grad.addColorStop(colorStop[0], colorStop[1]); 16553 } 16554 return grad; 16555 } 16556 _createReversedGradient(ctx, transform = null) { 16557 let firstPoint = this._p1; 16558 let secondPoint = this._p0; 16559 if (transform) { 16560 firstPoint = firstPoint.slice(); 16561 secondPoint = secondPoint.slice(); 16562 Util.applyTransform(firstPoint, transform); 16563 Util.applyTransform(secondPoint, transform); 16564 } 16565 let r0 = this._r1; 16566 let r1 = this._r0; 16567 if (transform) { 16568 const scale = new Float32Array(2); 16569 Util.singularValueDecompose2dScale(transform, scale); 16570 r0 *= scale[0]; 16571 r1 *= scale[0]; 16572 } 16573 const grad = ctx.createRadialGradient(firstPoint[0], firstPoint[1], r0, secondPoint[0], secondPoint[1], r1); 16574 const reversedStops = this._colorStops.map(([t, c]) => [1 - t, c]).reverse(); 16575 for (const [t, c] of reversedStops) { 16576 grad.addColorStop(t, c); 16577 } 16578 return grad; 16579 } 16580 getPattern(ctx, owner, inverse, pathType) { 16581 let pattern; 16582 if (pathType === PathType.STROKE || pathType === PathType.FILL) { 16583 if (this.isOriginBased()) { 16584 let transf = Util.transform(inverse, owner.baseTransform); 16585 if (this.matrix) { 16586 transf = Util.transform(transf, this.matrix); 16587 } 16588 const precision = 1e-3; 16589 const n1 = Math.hypot(transf[0], transf[1]); 16590 const n2 = Math.hypot(transf[2], transf[3]); 16591 const ps = (transf[0] * transf[2] + transf[1] * transf[3]) / (n1 * n2); 16592 if (Math.abs(ps) < precision) { 16593 if (this.isRadial()) { 16594 if (Math.abs(n1 - n2) < precision) { 16595 return this._createGradient(ctx, transf); 16596 } 16597 } else { 16598 return this._createGradient(ctx, transf); 16599 } 16600 } 16601 } 16602 const ownerBBox = owner.current.getClippedPathBoundingBox(pathType, getCurrentTransform(ctx)) || [0, 0, 0, 0]; 16603 const width = Math.ceil(ownerBBox[2] - ownerBBox[0]) || 1; 16604 const height = Math.ceil(ownerBBox[3] - ownerBBox[1]) || 1; 16605 const tmpCanvas = owner.canvasFactory.create(width, height); 16606 const tmpCtx = tmpCanvas.context; 16607 tmpCtx.clearRect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 16608 tmpCtx.beginPath(); 16609 tmpCtx.rect(0, 0, tmpCtx.canvas.width, tmpCtx.canvas.height); 16610 tmpCtx.translate(-ownerBBox[0], -ownerBBox[1]); 16611 inverse = Util.transform(inverse, [1, 0, 0, 1, ownerBBox[0], ownerBBox[1]]); 16612 tmpCtx.transform(...owner.baseTransform); 16613 if (this.matrix) { 16614 tmpCtx.transform(...this.matrix); 16615 } 16616 applyBoundingBox(tmpCtx, this._bbox); 16617 if (this.areConic()) { 16618 tmpCtx.fillStyle = this._createReversedGradient(tmpCtx); 16619 tmpCtx.fill(); 16620 } 16621 tmpCtx.fillStyle = this._createGradient(tmpCtx); 16622 tmpCtx.fill(); 16623 pattern = ctx.createPattern(tmpCanvas.canvas, "no-repeat"); 16624 owner.canvasFactory.destroy(tmpCanvas); 16625 const domMatrix = new DOMMatrix(inverse); 16626 pattern.setTransform(domMatrix); 16627 } else { 16628 if (this.areConic()) { 16629 ctx.save(); 16630 applyBoundingBox(ctx, this._bbox); 16631 ctx.fillStyle = this._createReversedGradient(ctx); 16632 ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 16633 ctx.restore(); 16634 } 16635 applyBoundingBox(ctx, this._bbox); 16636 pattern = this._createGradient(ctx); 16637 } 16638 return pattern; 16639 } 16640} 16641function drawTriangle(data, context, p1, p2, p3, c1, c2, c3) { 16642 const coords = context.coords, 16643 colors = context.colors; 16644 const bytes = data.data, 16645 rowSize = data.width * 4; 16646 let tmp; 16647 if (coords[p1 * 2 + 1] > coords[p2 * 2 + 1]) { 16648 tmp = p1; 16649 p1 = p2; 16650 p2 = tmp; 16651 tmp = c1; 16652 c1 = c2; 16653 c2 = tmp; 16654 } 16655 if (coords[p2 * 2 + 1] > coords[p3 * 2 + 1]) { 16656 tmp = p2; 16657 p2 = p3; 16658 p3 = tmp; 16659 tmp = c2; 16660 c2 = c3; 16661 c3 = tmp; 16662 } 16663 if (coords[p1 * 2 + 1] > coords[p2 * 2 + 1]) { 16664 tmp = p1; 16665 p1 = p2; 16666 p2 = tmp; 16667 tmp = c1; 16668 c1 = c2; 16669 c2 = tmp; 16670 } 16671 const x1 = (coords[p1 * 2] + context.offsetX) * context.scaleX; 16672 const y1 = (coords[p1 * 2 + 1] + context.offsetY) * context.scaleY; 16673 const x2 = (coords[p2 * 2] + context.offsetX) * context.scaleX; 16674 const y2 = (coords[p2 * 2 + 1] + context.offsetY) * context.scaleY; 16675 const x3 = (coords[p3 * 2] + context.offsetX) * context.scaleX; 16676 const y3 = (coords[p3 * 2 + 1] + context.offsetY) * context.scaleY; 16677 if (y1 >= y3) { 16678 return; 16679 } 16680 const c1r = colors[c1 * 4], 16681 c1g = colors[c1 * 4 + 1], 16682 c1b = colors[c1 * 4 + 2]; 16683 const c2r = colors[c2 * 4], 16684 c2g = colors[c2 * 4 + 1], 16685 c2b = colors[c2 * 4 + 2]; 16686 const c3r = colors[c3 * 4], 16687 c3g = colors[c3 * 4 + 1], 16688 c3b = colors[c3 * 4 + 2]; 16689 const minY = Math.round(y1), 16690 maxY = Math.round(y3); 16691 let xa, car, cag, cab; 16692 let xb, cbr, cbg, cbb; 16693 for (let y = minY; y <= maxY; y++) { 16694 if (y < y2) { 16695 const k = y < y1 ? 0 : (y1 - y) / (y1 - y2); 16696 xa = x1 - (x1 - x2) * k; 16697 car = c1r - (c1r - c2r) * k; 16698 cag = c1g - (c1g - c2g) * k; 16699 cab = c1b - (c1b - c2b) * k; 16700 } else { 16701 let k; 16702 if (y > y3) { 16703 k = 1; 16704 } else if (y2 === y3) { 16705 k = 0; 16706 } else { 16707 k = (y2 - y) / (y2 - y3); 16708 } 16709 xa = x2 - (x2 - x3) * k; 16710 car = c2r - (c2r - c3r) * k; 16711 cag = c2g - (c2g - c3g) * k; 16712 cab = c2b - (c2b - c3b) * k; 16713 } 16714 let k; 16715 if (y < y1) { 16716 k = 0; 16717 } else if (y > y3) { 16718 k = 1; 16719 } else { 16720 k = (y1 - y) / (y1 - y3); 16721 } 16722 xb = x1 - (x1 - x3) * k; 16723 cbr = c1r - (c1r - c3r) * k; 16724 cbg = c1g - (c1g - c3g) * k; 16725 cbb = c1b - (c1b - c3b) * k; 16726 const x1_ = Math.round(Math.min(xa, xb)); 16727 const x2_ = Math.round(Math.max(xa, xb)); 16728 let j = rowSize * y + x1_ * 4; 16729 for (let x = x1_; x <= x2_; x++) { 16730 k = (xa - x) / (xa - xb); 16731 if (k < 0) { 16732 k = 0; 16733 } else if (k > 1) { 16734 k = 1; 16735 } 16736 bytes[j++] = car - (car - cbr) * k | 0; 16737 bytes[j++] = cag - (cag - cbg) * k | 0; 16738 bytes[j++] = cab - (cab - cbb) * k | 0; 16739 bytes[j++] = 255; 16740 } 16741 } 16742} 16743class MeshShadingPattern extends BaseShadingPattern { 16744 constructor(IR) { 16745 super(); 16746 this._posData = IR[2]; 16747 this._colData = IR[3]; 16748 this._vertexCount = IR[4]; 16749 this._bounds = IR[5]; 16750 this._bbox = IR[6]; 16751 this._background = IR[7]; 16752 loadMeshShader(); 16753 } 16754 _createMeshCanvas(combinedScale, backgroundColor, canvasFactory) { 16755 const EXPECTED_SCALE = 1.1; 16756 const MAX_PATTERN_SIZE = 3000; 16757 const BORDER_SIZE = 2; 16758 const offsetX = Math.floor(this._bounds[0]); 16759 const offsetY = Math.floor(this._bounds[1]); 16760 const boundsWidth = Math.ceil(this._bounds[2]) - offsetX; 16761 const boundsHeight = Math.ceil(this._bounds[3]) - offsetY; 16762 const width = Math.min(Math.ceil(Math.abs(boundsWidth * combinedScale[0] * EXPECTED_SCALE)), MAX_PATTERN_SIZE) || 1; 16763 const height = Math.min(Math.ceil(Math.abs(boundsHeight * combinedScale[1] * EXPECTED_SCALE)), MAX_PATTERN_SIZE) || 1; 16764 const scaleX = boundsWidth ? boundsWidth / width : 1; 16765 const scaleY = boundsHeight ? boundsHeight / height : 1; 16766 const context = { 16767 coords: this._posData, 16768 colors: this._colData, 16769 offsetX: -offsetX, 16770 offsetY: -offsetY, 16771 scaleX: 1 / scaleX, 16772 scaleY: 1 / scaleY 16773 }; 16774 const paddedWidth = width + BORDER_SIZE * 2; 16775 const paddedHeight = height + BORDER_SIZE * 2; 16776 const tmpCanvas = canvasFactory.create(paddedWidth, paddedHeight); 16777 if (isGPUReady() && this._vertexCount > 48) { 16778 tmpCanvas.context.drawImage(drawMeshWithGPU(this._posData, this._colData, this._vertexCount, context, backgroundColor, paddedWidth, paddedHeight, BORDER_SIZE), 0, 0); 16779 } else { 16780 const data = tmpCanvas.context.createImageData(width, height); 16781 if (backgroundColor) { 16782 const bytes = data.data; 16783 for (let i = 0, ii = bytes.length; i < ii; i += 4) { 16784 bytes[i] = backgroundColor[0]; 16785 bytes[i + 1] = backgroundColor[1]; 16786 bytes[i + 2] = backgroundColor[2]; 16787 bytes[i + 3] = 255; 16788 } 16789 } 16790 for (let i = 0, ii = this._vertexCount; i < ii; i += 3) { 16791 drawTriangle(data, context, i, i + 1, i + 2, i, i + 1, i + 2); 16792 } 16793 tmpCanvas.context.putImageData(data, BORDER_SIZE, BORDER_SIZE); 16794 } 16795 return { 16796 canvas: tmpCanvas.canvas, 16797 offsetX: offsetX - BORDER_SIZE * scaleX, 16798 offsetY: offsetY - BORDER_SIZE * scaleY, 16799 scaleX, 16800 scaleY 16801 }; 16802 } 16803 isModifyingCurrentTransform() { 16804 return true; 16805 } 16806 getPattern(ctx, owner, inverse, pathType) { 16807 applyBoundingBox(ctx, this._bbox); 16808 const scale = new Float32Array(2); 16809 if (pathType === PathType.SHADING) { 16810 Util.singularValueDecompose2dScale(getCurrentTransform(ctx), scale); 16811 } else if (this.matrix) { 16812 Util.singularValueDecompose2dScale(this.matrix, scale); 16813 const [matrixScaleX, matrixScaleY] = scale; 16814 Util.singularValueDecompose2dScale(owner.baseTransform, scale); 16815 scale[0] *= matrixScaleX; 16816 scale[1] *= matrixScaleY; 16817 } else { 16818 Util.singularValueDecompose2dScale(owner.baseTransform, scale); 16819 } 16820 const temporaryPatternCanvas = this._createMeshCanvas(scale, pathType === PathType.SHADING ? null : this._background, owner.canvasFactory); 16821 if (pathType !== PathType.SHADING) { 16822 ctx.setTransform(...owner.baseTransform); 16823 if (this.matrix) { 16824 ctx.transform(...this.matrix); 16825 } 16826 } 16827 ctx.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 16828 ctx.scale(temporaryPatternCanvas.scaleX, temporaryPatternCanvas.scaleY); 16829 const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "no-repeat"); 16830 owner.canvasFactory.destroy(temporaryPatternCanvas); 16831 return pattern; 16832 } 16833} 16834class DummyShadingPattern extends BaseShadingPattern { 16835 getPattern() { 16836 return "hotpink"; 16837 } 16838} 16839function getShadingPattern(IR) { 16840 switch (IR[0]) { 16841 case "RadialAxial": 16842 return new RadialAxialShadingPattern(IR); 16843 case "Mesh": 16844 return new MeshShadingPattern(IR); 16845 case "Dummy": 16846 return new DummyShadingPattern(); 16847 } 16848 throw new Error(`Unknown IR type: ${IR[0]}`); 16849} 16850const PaintType = { 16851 COLORED: 1, 16852 UNCOLORED: 2 16853}; 16854class TilingPattern { 16855 static MAX_PATTERN_SIZE = 3000; 16856 constructor(IR, ctx, canvasGraphicsFactory, baseTransform) { 16857 this.color = IR[1]; 16858 this.operatorList = IR[2]; 16859 this.matrix = IR[3]; 16860 this.bbox = IR[4]; 16861 this.xstep = IR[5]; 16862 this.ystep = IR[6]; 16863 this.paintType = IR[7]; 16864 this.tilingType = IR[8]; 16865 this.needsIsolation = IR[9] ?? true; 16866 this.ctx = ctx; 16867 this.canvasGraphicsFactory = canvasGraphicsFactory; 16868 this.baseTransform = baseTransform; 16869 this.patternBaseMatrix = this.matrix ? Util.transform(baseTransform, this.matrix) : baseTransform; 16870 } 16871 canSkipPatternCanvas([width, height, offsetX, offsetY]) { 16872 const [x0, y0, x1, y1] = this.bbox; 16873 const absXStep = Math.abs(this.xstep); 16874 const absYStep = Math.abs(this.ystep); 16875 if (width > absXStep + 1e-6 || height > absYStep + 1e-6) { 16876 return null; 16877 } 16878 const nXFirst = Math.floor((offsetX - x1) / absXStep) + 1; 16879 const nXLast = Math.ceil((offsetX + width - x0) / absXStep) - 1; 16880 const nYFirst = Math.floor((offsetY - y1) / absYStep) + 1; 16881 const nYLast = Math.ceil((offsetY + height - y0) / absYStep) - 1; 16882 return nXLast <= nXFirst && nYLast <= nYFirst ? [nXFirst, nYFirst] : null; 16883 } 16884 updatePatternDims(clippedBBox, dims) { 16885 const inv = Util.inverseTransform(this.patternBaseMatrix); 16886 const c1 = [clippedBBox[0], clippedBBox[1]]; 16887 const c2 = [clippedBBox[2], clippedBBox[3]]; 16888 Util.applyTransform(c1, inv); 16889 Util.applyTransform(c2, inv); 16890 dims[0] = Math.abs(c2[0] - c1[0]); 16891 dims[1] = Math.abs(c2[1] - c1[1]); 16892 dims[2] = Math.min(c1[0], c2[0]); 16893 dims[3] = Math.min(c1[1], c2[1]); 16894 } 16895 _renderTileCanvas(owner, opIdx, dimx, dimy) { 16896 const [x0, y0, x1, y1] = this.bbox; 16897 const tmpCanvas = owner.canvasFactory.create(dimx.size, dimy.size); 16898 const tmpCtx = tmpCanvas.context; 16899 const graphics = this.canvasGraphicsFactory.createCanvasGraphics(tmpCtx, opIdx); 16900 graphics.groupLevel = owner.groupLevel; 16901 this.setFillAndStrokeStyleToContext(graphics, this.paintType, this.color); 16902 tmpCtx.translate(-dimx.scale * x0, -dimy.scale * y0); 16903 graphics.transform(0, dimx.scale, 0, 0, dimy.scale, 0, 0); 16904 tmpCtx.save(); 16905 graphics.dependencyTracker?.save(); 16906 this.clipBbox(graphics, x0, y0, x1, y1); 16907 graphics.baseTransform = getCurrentTransform(graphics.ctx); 16908 graphics.executeOperatorList(this.operatorList); 16909 graphics.endDrawing(); 16910 graphics.dependencyTracker?.restore(); 16911 tmpCtx.restore(); 16912 return tmpCanvas; 16913 } 16914 _getCombinedScales() { 16915 const scale = new Float32Array(2); 16916 Util.singularValueDecompose2dScale(this.matrix, scale); 16917 const [matrixScaleX, matrixScaleY] = scale; 16918 Util.singularValueDecompose2dScale(this.baseTransform, scale); 16919 return [matrixScaleX * scale[0], matrixScaleY * scale[1]]; 16920 } 16921 drawPattern(owner, path, useEOFill = false, [n, m], opIdx) { 16922 const [x0, y0, x1, y1] = this.bbox; 16923 const dependencyTracker = owner.dependencyTracker; 16924 if (dependencyTracker) { 16925 owner.dependencyTracker = new CanvasNestedDependencyTracker(dependencyTracker, opIdx); 16926 } 16927 owner.save(); 16928 if (useEOFill) { 16929 owner.ctx.clip(path, "evenodd"); 16930 } else { 16931 owner.ctx.clip(path); 16932 } 16933 owner.ctx.setTransform(...this.patternBaseMatrix); 16934 owner.ctx.translate(n * this.xstep, m * this.ystep); 16935 if (this.needsIsolation || owner.ctx.globalAlpha !== 1 || owner.ctx.globalCompositeOperation !== "source-over" || owner.inSMaskMode) { 16936 const bboxWidth = x1 - x0; 16937 const bboxHeight = y1 - y0; 16938 const [combinedScaleX, combinedScaleY] = this._getCombinedScales(); 16939 const dimx = this.getSizeAndScale(bboxWidth, this.ctx.canvas.width, combinedScaleX); 16940 const dimy = this.getSizeAndScale(bboxHeight, this.ctx.canvas.height, combinedScaleY); 16941 const tmpCanvas = this._renderTileCanvas(owner, opIdx, dimx, dimy); 16942 owner.ctx.drawImage(tmpCanvas.canvas, x0, y0, bboxWidth, bboxHeight); 16943 owner.canvasFactory.destroy(tmpCanvas); 16944 } else { 16945 this.setFillAndStrokeStyleToContext(owner, this.paintType, this.color); 16946 this.clipBbox(owner, x0, y0, x1, y1); 16947 owner.baseTransformStack.push(owner.baseTransform); 16948 owner.baseTransform = getCurrentTransform(owner.ctx); 16949 owner.executeOperatorList(this.operatorList); 16950 owner.baseTransform = owner.baseTransformStack.pop(); 16951 } 16952 owner.restore(); 16953 if (dependencyTracker) { 16954 owner.dependencyTracker = dependencyTracker; 16955 } 16956 } 16957 createPatternCanvas(owner, opIdx) { 16958 const [x0, y0, x1, y1] = this.bbox; 16959 const width = x1 - x0; 16960 const height = y1 - y0; 16961 let { 16962 xstep, 16963 ystep 16964 } = this; 16965 xstep = Math.abs(xstep); 16966 ystep = Math.abs(ystep); 16967 info("TilingType: " + this.tilingType); 16968 const [combinedScaleX, combinedScaleY] = this._getCombinedScales(); 16969 let canvasWidth = width, 16970 canvasHeight = height, 16971 redrawHorizontally = false, 16972 redrawVertically = false; 16973 if (Math.ceil(xstep * combinedScaleX) >= Math.ceil(width * combinedScaleX)) { 16974 canvasWidth = xstep; 16975 } else { 16976 redrawHorizontally = true; 16977 } 16978 if (Math.ceil(ystep * combinedScaleY) >= Math.ceil(height * combinedScaleY)) { 16979 canvasHeight = ystep; 16980 } else { 16981 redrawVertically = true; 16982 } 16983 const dimx = this.getSizeAndScale(canvasWidth, this.ctx.canvas.width, combinedScaleX); 16984 const dimy = this.getSizeAndScale(canvasHeight, this.ctx.canvas.height, combinedScaleY); 16985 const tmpCanvas = this._renderTileCanvas(owner, opIdx, dimx, dimy); 16986 if (redrawHorizontally || redrawVertically) { 16987 const image = tmpCanvas.canvas; 16988 if (redrawHorizontally) { 16989 canvasWidth = xstep; 16990 } 16991 if (redrawVertically) { 16992 canvasHeight = ystep; 16993 } 16994 const dimx2 = this.getSizeAndScale(canvasWidth, this.ctx.canvas.width, combinedScaleX); 16995 const dimy2 = this.getSizeAndScale(canvasHeight, this.ctx.canvas.height, combinedScaleY); 16996 const xSize = dimx2.size; 16997 const ySize = dimy2.size; 16998 const tmpCanvas2 = owner.canvasFactory.create(xSize, ySize); 16999 const tmpCtx2 = tmpCanvas2.context; 17000 const ii = redrawHorizontally ? Math.floor(width / xstep) : 0; 17001 const jj = redrawVertically ? Math.floor(height / ystep) : 0; 17002 for (let i = 0; i <= ii; i++) { 17003 for (let j = 0; j <= jj; j++) { 17004 tmpCtx2.drawImage(image, xSize * i, ySize * j, xSize, ySize, 0, 0, xSize, ySize); 17005 } 17006 } 17007 owner.canvasFactory.destroy(tmpCanvas); 17008 return { 17009 canvas: tmpCanvas2.canvas, 17010 canvasEntry: tmpCanvas2, 17011 scaleX: dimx2.scale, 17012 scaleY: dimy2.scale, 17013 offsetX: x0, 17014 offsetY: y0 17015 }; 17016 } 17017 return { 17018 canvas: tmpCanvas.canvas, 17019 canvasEntry: tmpCanvas, 17020 scaleX: dimx.scale, 17021 scaleY: dimy.scale, 17022 offsetX: x0, 17023 offsetY: y0 17024 }; 17025 } 17026 getSizeAndScale(step, realOutputSize, scale) { 17027 const maxSize = Math.max(TilingPattern.MAX_PATTERN_SIZE, realOutputSize); 17028 let size = Math.ceil(step * scale); 17029 if (size >= maxSize) { 17030 size = maxSize; 17031 } else { 17032 scale = size / step; 17033 } 17034 return { 17035 scale, 17036 size 17037 }; 17038 } 17039 clipBbox(graphics, x0, y0, x1, y1) { 17040 const bboxWidth = x1 - x0; 17041 const bboxHeight = y1 - y0; 17042 const clip = new Path2D(); 17043 clip.rect(x0, y0, bboxWidth, bboxHeight); 17044 Util.axialAlignedBoundingBox([x0, y0, x1, y1], getCurrentTransform(graphics.ctx), graphics.current.minMax); 17045 graphics.ctx.clip(clip); 17046 graphics.current.updateClipFromPath(); 17047 } 17048 setFillAndStrokeStyleToContext(graphics, paintType, color) { 17049 const context = graphics.ctx, 17050 current = graphics.current; 17051 current.patternFill = current.patternStroke = false; 17052 switch (paintType) { 17053 case PaintType.COLORED: 17054 const { 17055 fillStyle, 17056 strokeStyle 17057 } = this.ctx; 17058 context.fillStyle = current.fillColor = fillStyle; 17059 context.strokeStyle = current.strokeColor = strokeStyle; 17060 break; 17061 case PaintType.UNCOLORED: 17062 context.fillStyle = context.strokeStyle = color; 17063 current.fillColor = current.strokeColor = color; 17064 break; 17065 default: 17066 throw new FormatError(`Unsupported paint type: ${paintType}`); 17067 } 17068 } 17069 isModifyingCurrentTransform() { 17070 return false; 17071 } 17072 getPattern(ctx, owner, inverse, pathType, opIdx) { 17073 const matrix = pathType !== PathType.SHADING ? Util.transform(inverse, this.patternBaseMatrix) : inverse; 17074 const temporaryPatternCanvas = this.createPatternCanvas(owner, opIdx); 17075 let domMatrix = new DOMMatrix(matrix); 17076 domMatrix = domMatrix.translate(temporaryPatternCanvas.offsetX, temporaryPatternCanvas.offsetY); 17077 domMatrix = domMatrix.scale(1 / temporaryPatternCanvas.scaleX, 1 / temporaryPatternCanvas.scaleY); 17078 const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat"); 17079 owner.canvasFactory.destroy(temporaryPatternCanvas.canvasEntry); 17080 pattern.setTransform(domMatrix); 17081 return pattern; 17082 } 17083} 17084 17085;// ./src/display/canvas.js 17086 17087 17088 17089 17090 17091
17092
vendor: 96,411 bytes, lines 17093-19753
17093 17094 17095 17096 17097 17098 17099 17100const MIN_FONT_SIZE = 16; 17101const MAX_FONT_SIZE = 100; 17102const EXECUTION_TIME = 15; 17103const EXECUTION_STEPS = 10; 17104const FULL_CHUNK_HEIGHT = 16; 17105const XY = new Float32Array(2); 17106function mirrorContextOperations(ctx, destCtx) { 17107 if (ctx._removeMirroring) { 17108 throw new Error("Context is already forwarding operations."); 17109 } 17110 const originalMethods = new Map(); 17111 for (const name of ["save", "restore", "rotate", "scale", "translate", "transform", "setTransform", "resetTransform", "clip", "moveTo", "lineTo", "bezierCurveTo", "quadraticCurveTo", "arc", "arcTo", "ellipse", "rect", "roundRect", "closePath", "beginPath"]) { 17112 const original = ctx[name]; 17113 if (typeof original !== "function" || typeof destCtx[name] !== "function") { 17114 continue; 17115 } 17116 originalMethods.set(name, original); 17117 ctx[name] = function (...args) { 17118 destCtx[name](...args); 17119 return original.apply(this, args); 17120 }; 17121 } 17122 ctx._removeMirroring = () => { 17123 for (const [name, original] of originalMethods) { 17124 ctx[name] = original; 17125 } 17126 delete ctx._removeMirroring; 17127 }; 17128} 17129function drawImageAtIntegerCoords(ctx, srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH) { 17130 const [a, b, c, d, tx, ty] = getCurrentTransform(ctx); 17131 if (b === 0 && c === 0) { 17132 const tlX = destX * a + tx; 17133 const rTlX = Math.round(tlX); 17134 const tlY = destY * d + ty; 17135 const rTlY = Math.round(tlY); 17136 const brX = (destX + destW) * a + tx; 17137 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 17138 const brY = (destY + destH) * d + ty; 17139 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 17140 ctx.setTransform(Math.sign(a), 0, 0, Math.sign(d), rTlX, rTlY); 17141 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rWidth, rHeight); 17142 ctx.setTransform(a, b, c, d, tx, ty); 17143 return [rWidth, rHeight]; 17144 } 17145 if (a === 0 && d === 0) { 17146 const tlX = destY * c + tx; 17147 const rTlX = Math.round(tlX); 17148 const tlY = destX * b + ty; 17149 const rTlY = Math.round(tlY); 17150 const brX = (destY + destH) * c + tx; 17151 const rWidth = Math.abs(Math.round(brX) - rTlX) || 1; 17152 const brY = (destX + destW) * b + ty; 17153 const rHeight = Math.abs(Math.round(brY) - rTlY) || 1; 17154 ctx.setTransform(0, Math.sign(b), Math.sign(c), 0, rTlX, rTlY); 17155 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, 0, 0, rHeight, rWidth); 17156 ctx.setTransform(a, b, c, d, tx, ty); 17157 return [rHeight, rWidth]; 17158 } 17159 ctx.drawImage(srcImg, srcX, srcY, srcW, srcH, destX, destY, destW, destH); 17160 const scaleX = Math.hypot(a, b); 17161 const scaleY = Math.hypot(c, d); 17162 return [scaleX * destW, scaleY * destH]; 17163} 17164class CanvasExtraState { 17165 alphaIsShape = false; 17166 fontSize = 0; 17167 fontSizeScale = 1; 17168 textMatrix = null; 17169 textMatrixScale = 1; 17170 fontMatrix = FONT_IDENTITY_MATRIX; 17171 leading = 0; 17172 x = 0; 17173 y = 0; 17174 lineX = 0; 17175 lineY = 0; 17176 charSpacing = 0; 17177 wordSpacing = 0; 17178 textHScale = 1; 17179 textRenderingMode = TextRenderingMode.FILL; 17180 textRise = 0; 17181 fillColor = "#000000"; 17182 strokeColor = "#000000"; 17183 tilingPatternDims = null; 17184 patternFill = false; 17185 patternStroke = false; 17186 fillAlpha = 1; 17187 strokeAlpha = 1; 17188 lineWidth = 1; 17189 activeSMask = null; 17190 transferMaps = "none"; 17191 minMax = F32_BBOX_INIT.slice(); 17192 constructor(width, height) { 17193 this.clipBox = new Float32Array([0, 0, width, height]); 17194 } 17195 clone() { 17196 const clone = Object.create(this); 17197 clone.clipBox = this.clipBox.slice(); 17198 clone.minMax = this.minMax.slice(); 17199 clone.tilingPatternDims = this.tilingPatternDims?.slice(); 17200 return clone; 17201 } 17202 getPathBoundingBox(pathType = PathType.FILL, transform = null) { 17203 const box = this.minMax.slice(); 17204 if (pathType === PathType.STROKE) { 17205 if (!transform) { 17206 unreachable("Stroke bounding box must include transform."); 17207 } 17208 Util.singularValueDecompose2dScale(transform, XY); 17209 const xStrokePad = XY[0] * this.lineWidth / 2; 17210 const yStrokePad = XY[1] * this.lineWidth / 2; 17211 box[0] -= xStrokePad; 17212 box[1] -= yStrokePad; 17213 box[2] += xStrokePad; 17214 box[3] += yStrokePad; 17215 } 17216 return box; 17217 } 17218 updateClipFromPath() { 17219 const intersect = Util.intersect(this.clipBox, this.getPathBoundingBox()); 17220 this.startNewPathAndClipBox(intersect || [0, 0, 0, 0]); 17221 } 17222 isEmptyClip() { 17223 return this.minMax[0] === Infinity; 17224 } 17225 startNewPathAndClipBox(box) { 17226 this.clipBox.set(box, 0); 17227 this.minMax.set(F32_BBOX_INIT, 0); 17228 } 17229 getClippedPathBoundingBox(pathType = PathType.FILL, transform = null) { 17230 return Util.intersect(this.clipBox, this.getPathBoundingBox(pathType, transform)); 17231 } 17232} 17233function putBinaryImageData(ctx, imgData) { 17234 const { 17235 width, 17236 height, 17237 kind 17238 } = imgData; 17239 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 17240 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 17241 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 17242 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 17243 let srcPos = 0; 17244 const src = imgData.data; 17245 const dest = chunkImgData.data; 17246 let i; 17247 if (kind === ImageKind.GRAYSCALE_1BPP) { 17248 for (i = 0; i < totalChunks; i++) { 17249 ({ 17250 srcPos 17251 } = convertBlackAndWhiteToRGBA({ 17252 src, 17253 srcPos, 17254 dest, 17255 width, 17256 height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight 17257 })); 17258 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 17259 } 17260 } else if (kind === ImageKind.RGBA_32BPP) { 17261 let j = 0; 17262 let elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 17263 for (i = 0; i < fullChunks; i++) { 17264 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 17265 srcPos += elemsInThisChunk; 17266 ctx.putImageData(chunkImgData, 0, j); 17267 j += FULL_CHUNK_HEIGHT; 17268 } 17269 if (i < totalChunks) { 17270 elemsInThisChunk = width * partialChunkHeight * 4; 17271 dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 17272 ctx.putImageData(chunkImgData, 0, j); 17273 } 17274 } else if (kind === ImageKind.RGB_24BPP) { 17275 for (i = 0; i < totalChunks; i++) { 17276 ({ 17277 srcPos 17278 } = convertRGBToRGBA({ 17279 src, 17280 srcPos, 17281 dest: new Uint32Array(dest.buffer), 17282 width, 17283 height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight 17284 })); 17285 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 17286 } 17287 } else { 17288 throw new Error(`bad image kind: ${kind}`); 17289 } 17290} 17291function putBinaryImageMask(ctx, imgData) { 17292 if (imgData.bitmap) { 17293 ctx.drawImage(imgData.bitmap, 0, 0); 17294 return; 17295 } 17296 const { 17297 width, 17298 height 17299 } = imgData; 17300 const partialChunkHeight = height % FULL_CHUNK_HEIGHT; 17301 const fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 17302 const totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 17303 const chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 17304 let srcPos = 0; 17305 const src = imgData.data; 17306 const dest = chunkImgData.data; 17307 for (let i = 0; i < totalChunks; i++) { 17308 ({ 17309 srcPos 17310 } = convertBlackAndWhiteToRGBA({ 17311 src, 17312 srcPos, 17313 dest, 17314 width, 17315 height: i < fullChunks ? FULL_CHUNK_HEIGHT : partialChunkHeight, 17316 nonBlackColor: 0 17317 })); 17318 ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 17319 } 17320} 17321function copyCtxState(sourceCtx, destCtx) { 17322 const properties = ["strokeStyle", "fillStyle", "fillRule", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "globalCompositeOperation", "font", "filter"]; 17323 for (const property of properties) { 17324 if (sourceCtx[property] !== undefined) { 17325 destCtx[property] = sourceCtx[property]; 17326 } 17327 } 17328 if (sourceCtx.setLineDash !== undefined) { 17329 destCtx.setLineDash(sourceCtx.getLineDash()); 17330 destCtx.lineDashOffset = sourceCtx.lineDashOffset; 17331 } 17332} 17333function resetCtxToDefault(ctx) { 17334 ctx.strokeStyle = ctx.fillStyle = "#000000"; 17335 ctx.fillRule = "nonzero"; 17336 ctx.globalAlpha = 1; 17337 ctx.lineWidth = 1; 17338 ctx.lineCap = "butt"; 17339 ctx.lineJoin = "miter"; 17340 ctx.miterLimit = 10; 17341 ctx.globalCompositeOperation = "source-over"; 17342 ctx.font = "10px sans-serif"; 17343 if (ctx.setLineDash !== undefined) { 17344 ctx.setLineDash([]); 17345 ctx.lineDashOffset = 0; 17346 } 17347 const { 17348 filter 17349 } = ctx; 17350 if (filter !== "none" && filter !== "") { 17351 ctx.filter = "none"; 17352 } 17353} 17354function getImageSmoothingEnabled(transform, interpolate) { 17355 if (interpolate) { 17356 return true; 17357 } 17358 Util.singularValueDecompose2dScale(transform, XY); 17359 const actualScale = Math.fround(OutputScale.pixelRatio * PixelsPerInch.PDF_TO_CSS_UNITS); 17360 return XY[0] <= actualScale && XY[1] <= actualScale; 17361} 17362const LINE_CAP_STYLES = ["butt", "round", "square"]; 17363const LINE_JOIN_STYLES = ["miter", "round", "bevel"]; 17364const NORMAL_CLIP = {}; 17365const EO_CLIP = {}; 17366class CanvasGraphics { 17367 static #SCALE_MATRIX = null; 17368 #knockoutGroupLevel = 0; 17369 #knockoutElementDepth = 0; 17370 #knockoutTempCanvasEntry = null; 17371 #knockoutSavedCtx = null; 17372 #knockoutSavedSMaskCtx = null; 17373 #knockoutSavedGCO = null; 17374 #knockoutElementAlpha = 1; 17375 #knockoutFilterCache; 17376 #knockoutElementGroupMeta = null; 17377 #groupStackMeta = []; 17378 constructor(canvasCtx, commonObjs, objs, canvasFactory, filterFactory, { 17379 optionalContentConfig, 17380 markedContentStack = null 17381 }, annotationCanvasMap, pageColors, dependencyTracker, imagesTracker) { 17382 this.ctx = canvasCtx; 17383 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 17384 this.stateStack = []; 17385 this.pendingClip = null; 17386 this.pendingEOFill = false; 17387 this.commonObjs = commonObjs; 17388 this.objs = objs; 17389 this.canvasFactory = canvasFactory; 17390 this.filterFactory = filterFactory; 17391 this.groupStack = []; 17392 this.baseTransform = null; 17393 this.baseTransformStack = []; 17394 this.groupLevel = 0; 17395 this.smaskStack = []; 17396 this.tempSMask = null; 17397 this.smaskGroupCanvases = []; 17398 this.smaskPreparedEntry = null; 17399 this.smaskPreparedFor = null; 17400 this.smaskPreparedOffsetX = 0; 17401 this.smaskPreparedOffsetY = 0; 17402 this.smaskPreparedOOBAlpha = null; 17403 this.suspendedCtx = null; 17404 this.contentVisible = true; 17405 this.markedContentStack = markedContentStack || []; 17406 this.optionalContentConfig = optionalContentConfig; 17407 this.cachedPatterns = new Map(); 17408 this.annotationCanvasMap = annotationCanvasMap; 17409 this.viewportScale = 1; 17410 this.outputScaleX = 1; 17411 this.outputScaleY = 1; 17412 this.pageColors = pageColors; 17413 this._cachedScaleForStroking = [-1, 0]; 17414 this._cachedGetSinglePixelWidth = null; 17415 this._cachedBitmapsMap = new Map(); 17416 this.dependencyTracker = dependencyTracker ?? null; 17417 this.imagesTracker = imagesTracker ?? null; 17418 } 17419 getObject(opIdx, data, fallback = null) { 17420 if (typeof data === "string") { 17421 this.dependencyTracker?.recordNamedDependency(opIdx, data); 17422 return data.startsWith("g_") ? this.commonObjs.get(data) : this.objs.get(data); 17423 } 17424 return fallback; 17425 } 17426 beginDrawing({ 17427 transform, 17428 viewport, 17429 transparency = false, 17430 background = null 17431 }) { 17432 const width = this.ctx.canvas.width; 17433 const height = this.ctx.canvas.height; 17434 const savedFillStyle = this.ctx.fillStyle; 17435 this.ctx.fillStyle = background || "#ffffff"; 17436 this.ctx.fillRect(0, 0, width, height); 17437 this.ctx.fillStyle = savedFillStyle; 17438 if (transparency) { 17439 const transparentCanvas = this.transparentCanvasEntry = this.canvasFactory.create(width, height); 17440 this.compositeCtx = this.ctx; 17441 ({ 17442 canvas: this.transparentCanvas, 17443 context: this.ctx 17444 } = transparentCanvas); 17445 this.ctx.save(); 17446 this.ctx.transform(...getCurrentTransform(this.compositeCtx)); 17447 } 17448 this.ctx.save(); 17449 resetCtxToDefault(this.ctx); 17450 if (transform) { 17451 this.ctx.transform(...transform); 17452 this.outputScaleX = transform[0]; 17453 this.outputScaleY = transform[3]; 17454 } 17455 this.ctx.transform(...viewport.transform); 17456 this.viewportScale = viewport.scale; 17457 this.baseTransform = getCurrentTransform(this.ctx); 17458 } 17459 executeOperatorList(operatorList, executionStartIdx, continueCallback, stepper, operationsFilter) { 17460 const argsArray = operatorList.argsArray; 17461 const fnArray = operatorList.fnArray; 17462 let i = executionStartIdx || 0; 17463 const argsArrayLen = argsArray.length; 17464 if (argsArrayLen === i) { 17465 return i; 17466 } 17467 const chunkOperations = argsArrayLen - i > EXECUTION_STEPS && typeof continueCallback === "function"; 17468 const endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 17469 let steps = 0; 17470 const commonObjs = this.commonObjs; 17471 const objs = this.objs; 17472 let fnId, fnArgs; 17473 while (true) { 17474 if (stepper !== undefined) { 17475 if (i === stepper.nextBreakPoint) { 17476 stepper.breakIt(i, continueCallback); 17477 return i; 17478 } 17479 if (stepper.shouldSkip(i)) { 17480 if (++i === argsArrayLen) { 17481 return i; 17482 } 17483 continue; 17484 } 17485 } 17486 if (!operationsFilter || operationsFilter(i)) { 17487 fnId = fnArray[i]; 17488 fnArgs = argsArray[i] ?? null; 17489 if (fnId !== OPS.dependency) { 17490 if (fnArgs === null) { 17491 this[fnId](i); 17492 } else { 17493 this[fnId](i, ...fnArgs); 17494 } 17495 } else { 17496 for (const depObjId of fnArgs) { 17497 this.dependencyTracker?.recordNamedData(depObjId, i); 17498 const objsPool = depObjId.startsWith("g_") ? commonObjs : objs; 17499 if (!objsPool.has(depObjId)) { 17500 objsPool.get(depObjId, continueCallback); 17501 return i; 17502 } 17503 } 17504 } 17505 } 17506 i++; 17507 if (i === argsArrayLen) { 17508 return i; 17509 } 17510 if (chunkOperations && ++steps > EXECUTION_STEPS) { 17511 if (Date.now() > endTime) { 17512 continueCallback(); 17513 return i; 17514 } 17515 steps = 0; 17516 } 17517 } 17518 } 17519 #restoreInitialState() { 17520 while (this.stateStack.length || this.inSMaskMode) { 17521 this.restore(); 17522 } 17523 this.current.activeSMask = null; 17524 this.ctx.restore(); 17525 if (this.transparentCanvas) { 17526 this.ctx = this.compositeCtx; 17527 this.ctx.save(); 17528 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 17529 this.ctx.drawImage(this.transparentCanvas, 0, 0); 17530 this.ctx.restore(); 17531 this.canvasFactory.destroy(this.transparentCanvasEntry); 17532 this.transparentCanvas = null; 17533 this.transparentCanvasEntry = null; 17534 } 17535 } 17536 endDrawing() { 17537 this.#restoreInitialState(); 17538 for (const canvas of this.smaskGroupCanvases) { 17539 this.canvasFactory.destroy(canvas); 17540 } 17541 this.smaskGroupCanvases.length = 0; 17542 this._clearPreparedSMask(); 17543 this.tempSMask = null; 17544 this.smaskStack.length = 0; 17545 for (const meta of this.#groupStackMeta) { 17546 this.#destroyKnockoutPools(meta); 17547 } 17548 this.#groupStackMeta.length = 0; 17549 this.#knockoutTempCanvasEntry = null; 17550 this.#knockoutSavedCtx = null; 17551 this.#knockoutSavedSMaskCtx = null; 17552 this.#knockoutSavedGCO = null; 17553 this.#knockoutElementAlpha = 1; 17554 this.#knockoutElementGroupMeta = null; 17555 this.#knockoutElementDepth = 0; 17556 this.#knockoutGroupLevel = 0; 17557 this.cachedPatterns.clear(); 17558 for (const cache of this._cachedBitmapsMap.values()) { 17559 for (const canvas of cache.values()) { 17560 if (typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) { 17561 canvas.width = canvas.height = 0; 17562 } 17563 } 17564 cache.clear(); 17565 } 17566 this._cachedBitmapsMap.clear(); 17567 this.#drawFilter(); 17568 } 17569 #drawFilter() { 17570 if (this.pageColors) { 17571 const hcmFilterId = this.filterFactory.addHCMFilter(this.pageColors.foreground, this.pageColors.background); 17572 if (hcmFilterId !== "none") { 17573 const savedFilter = this.ctx.filter; 17574 this.ctx.filter = hcmFilterId; 17575 this.ctx.drawImage(this.ctx.canvas, 0, 0); 17576 this.ctx.filter = savedFilter; 17577 } 17578 } 17579 } 17580 _scaleImage(img, inverseTransform) { 17581 const width = img.width ?? img.displayWidth; 17582 const height = img.height ?? img.displayHeight; 17583 const widthScale = Math.max(Math.hypot(inverseTransform[0], inverseTransform[1]), 1); 17584 const heightScale = Math.max(Math.hypot(inverseTransform[2], inverseTransform[3]), 1); 17585 const scaleSteps = []; 17586 let ws = widthScale, 17587 hs = heightScale, 17588 pw = width, 17589 ph = height; 17590 while (ws > 2 && pw > 1 || hs > 2 && ph > 1) { 17591 let nw = pw, 17592 nh = ph; 17593 if (ws > 2 && pw > 1) { 17594 nw = Math.ceil(pw / 2); 17595 ws /= pw / nw; 17596 } 17597 if (hs > 2 && ph > 1) { 17598 nh = Math.ceil(ph / 2); 17599 hs /= ph / nh; 17600 } 17601 scaleSteps.push({ 17602 newWidth: nw, 17603 newHeight: nh 17604 }); 17605 pw = nw; 17606 ph = nh; 17607 } 17608 if (scaleSteps.length === 0) { 17609 return { 17610 img, 17611 paintWidth: width, 17612 paintHeight: height, 17613 tmpCanvas: null 17614 }; 17615 } 17616 if (scaleSteps.length === 1) { 17617 const { 17618 newWidth, 17619 newHeight 17620 } = scaleSteps[0]; 17621 const tmpCanvas = this.canvasFactory.create(newWidth, newHeight); 17622 tmpCanvas.context.drawImage(img, 0, 0, width, height, 0, 0, newWidth, newHeight); 17623 return { 17624 img: tmpCanvas.canvas, 17625 paintWidth: newWidth, 17626 paintHeight: newHeight, 17627 tmpCanvas 17628 }; 17629 } 17630 let readEntry = this.canvasFactory.create(1, 1); 17631 let writeEntry = this.canvasFactory.create(1, 1); 17632 let paintWidth = width, 17633 paintHeight = height; 17634 let source = img; 17635 for (const { 17636 newWidth, 17637 newHeight 17638 } of scaleSteps) { 17639 this.canvasFactory.reset(writeEntry, newWidth, newHeight); 17640 writeEntry.context.drawImage(source, 0, 0, paintWidth, paintHeight, 0, 0, newWidth, newHeight); 17641 [readEntry, writeEntry] = [writeEntry, readEntry]; 17642 source = readEntry.canvas; 17643 paintWidth = newWidth; 17644 paintHeight = newHeight; 17645 } 17646 this.canvasFactory.destroy(writeEntry); 17647 return { 17648 img: readEntry.canvas, 17649 paintWidth, 17650 paintHeight, 17651 tmpCanvas: readEntry 17652 }; 17653 } 17654 _createMaskCanvas(opIdx, img) { 17655 const ctx = this.ctx; 17656 const { 17657 width, 17658 height 17659 } = img; 17660 const fillColor = this.current.fillColor; 17661 const isPatternFill = this.current.patternFill; 17662 const currentTransform = getCurrentTransform(ctx); 17663 let cache, cacheKey, scaled, maskCanvas; 17664 if ((img.bitmap || img.data) && img.count > 1) { 17665 const mainKey = img.bitmap || img.data.buffer; 17666 cacheKey = JSON.stringify(isPatternFill ? currentTransform : [currentTransform.slice(0, 4), fillColor]); 17667 cache = this._cachedBitmapsMap.getOrInsertComputed(mainKey, makeMap); 17668 const cachedImage = cache.get(cacheKey); 17669 if (cachedImage && !isPatternFill) { 17670 const offsetX = Math.round(Math.min(currentTransform[0], currentTransform[2]) + currentTransform[4]); 17671 const offsetY = Math.round(Math.min(currentTransform[1], currentTransform[3]) + currentTransform[5]); 17672 this.dependencyTracker?.recordDependencies(opIdx, Dependencies.transformAndFill); 17673 return { 17674 canvas: cachedImage, 17675 offsetX, 17676 offsetY 17677 }; 17678 } 17679 scaled = cachedImage; 17680 } 17681 if (!scaled) { 17682 maskCanvas = this.canvasFactory.create(width, height); 17683 putBinaryImageMask(maskCanvas.context, img); 17684 } 17685 let maskToCanvas = Util.transform(currentTransform, [1 / width, 0, 0, -1 / height, 0, 0]); 17686 maskToCanvas = Util.transform(maskToCanvas, [1, 0, 0, 1, 0, -height]); 17687 const minMax = F32_BBOX_INIT.slice(); 17688 Util.axialAlignedBoundingBox([0, 0, width, height], maskToCanvas, minMax); 17689 const [minX, minY, maxX, maxY] = minMax; 17690 const drawnWidth = Math.round(maxX - minX) || 1; 17691 const drawnHeight = Math.round(maxY - minY) || 1; 17692 const fillCanvas = this.canvasFactory.create(drawnWidth, drawnHeight); 17693 const fillCtx = fillCanvas.context; 17694 const offsetX = minX; 17695 const offsetY = minY; 17696 fillCtx.translate(-offsetX, -offsetY); 17697 fillCtx.transform(...maskToCanvas); 17698 let scaledEntry = null; 17699 if (!scaled) { 17700 const scaleResult = this._scaleImage(maskCanvas.canvas, getCurrentTransformInverse(fillCtx)); 17701 scaled = scaleResult.img; 17702 scaledEntry = scaleResult.tmpCanvas; 17703 if (scaled !== maskCanvas.canvas) { 17704 this.canvasFactory.destroy(maskCanvas); 17705 maskCanvas = null; 17706 } 17707 if (cache && isPatternFill) { 17708 cache.set(cacheKey, scaled); 17709 scaledEntry = null; 17710 maskCanvas = null; 17711 } 17712 } 17713 fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(getCurrentTransform(fillCtx), img.interpolate); 17714 drawImageAtIntegerCoords(fillCtx, scaled, 0, 0, scaled.width, scaled.height, 0, 0, width, height); 17715 if (scaledEntry) { 17716 this.canvasFactory.destroy(scaledEntry); 17717 } 17718 if (maskCanvas) { 17719 this.canvasFactory.destroy(maskCanvas); 17720 } 17721 fillCtx.globalCompositeOperation = "source-in"; 17722 const inverse = Util.transform(getCurrentTransformInverse(fillCtx), [1, 0, 0, 1, -offsetX, -offsetY]); 17723 fillCtx.fillStyle = isPatternFill ? fillColor.getPattern(ctx, this, inverse, PathType.FILL, opIdx) : fillColor; 17724 fillCtx.fillRect(0, 0, width, height); 17725 if (cache && !isPatternFill) { 17726 cache.set(cacheKey, fillCanvas.canvas); 17727 } 17728 this.dependencyTracker?.recordDependencies(opIdx, Dependencies.transformAndFill); 17729 return { 17730 canvas: fillCanvas.canvas, 17731 canvasEntry: cache && !isPatternFill ? null : fillCanvas, 17732 offsetX: Math.round(offsetX), 17733 offsetY: Math.round(offsetY) 17734 }; 17735 } 17736 setLineWidth(opIdx, width) { 17737 this.dependencyTracker?.recordSimpleData("lineWidth", opIdx); 17738 if (width !== this.current.lineWidth) { 17739 this._cachedScaleForStroking[0] = -1; 17740 } 17741 this.current.lineWidth = width; 17742 this.ctx.lineWidth = width; 17743 } 17744 setLineCap(opIdx, style) { 17745 this.dependencyTracker?.recordSimpleData("lineCap", opIdx); 17746 this.ctx.lineCap = LINE_CAP_STYLES[style]; 17747 } 17748 setLineJoin(opIdx, style) { 17749 this.dependencyTracker?.recordSimpleData("lineJoin", opIdx); 17750 this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 17751 } 17752 setMiterLimit(opIdx, limit) { 17753 this.dependencyTracker?.recordSimpleData("miterLimit", opIdx); 17754 this.ctx.miterLimit = limit; 17755 } 17756 setDash(opIdx, dashArray, dashPhase) { 17757 this.dependencyTracker?.recordSimpleData("dash", opIdx); 17758 const ctx = this.ctx; 17759 if (ctx.setLineDash !== undefined) { 17760 ctx.setLineDash(dashArray); 17761 ctx.lineDashOffset = dashPhase; 17762 } 17763 } 17764 setRenderingIntent(opIdx, intent) {} 17765 setFlatness(opIdx, flatness) {} 17766 setGState(opIdx, states) { 17767 for (const [key, value] of states) { 17768 switch (key) { 17769 case "LW": 17770 this.setLineWidth(opIdx, value); 17771 break; 17772 case "LC": 17773 this.setLineCap(opIdx, value); 17774 break; 17775 case "LJ": 17776 this.setLineJoin(opIdx, value); 17777 break; 17778 case "ML": 17779 this.setMiterLimit(opIdx, value); 17780 break; 17781 case "D": 17782 this.setDash(opIdx, value[0], value[1]); 17783 break; 17784 case "RI": 17785 this.setRenderingIntent(opIdx, value); 17786 break; 17787 case "FL": 17788 this.setFlatness(opIdx, value); 17789 break; 17790 case "Font": 17791 this.setFont(opIdx, value[0], value[1]); 17792 break; 17793 case "CA": 17794 this.dependencyTracker?.recordSimpleData("strokeAlpha", opIdx); 17795 this.current.strokeAlpha = value; 17796 break; 17797 case "ca": 17798 this.dependencyTracker?.recordSimpleData("fillAlpha", opIdx); 17799 this.ctx.globalAlpha = this.current.fillAlpha = value; 17800 break; 17801 case "BM": 17802 this.dependencyTracker?.recordSimpleData("globalCompositeOperation", opIdx); 17803 this.ctx.globalCompositeOperation = value; 17804 break; 17805 case "SMask": 17806 this.dependencyTracker?.recordSimpleData("SMask", opIdx); 17807 this.current.activeSMask = value ? this.tempSMask : null; 17808 if (this.current.activeSMask) { 17809 this.current.activeSMask.blendMode = this.ctx.globalCompositeOperation; 17810 } 17811 this.tempSMask = null; 17812 this.checkSMaskState(opIdx); 17813 break; 17814 case "TR": 17815 this.dependencyTracker?.recordSimpleData("filter", opIdx); 17816 this.ctx.filter = this.current.transferMaps = this.filterFactory.addFilter(value); 17817 break; 17818 } 17819 } 17820 } 17821 get inSMaskMode() { 17822 return !!this.suspendedCtx; 17823 } 17824 _clearPreparedSMask() { 17825 if (this.smaskPreparedEntry) { 17826 this.canvasFactory.destroy(this.smaskPreparedEntry); 17827 this.smaskPreparedEntry = null; 17828 } 17829 this.smaskPreparedFor = null; 17830 this.smaskPreparedOffsetX = 0; 17831 this.smaskPreparedOffsetY = 0; 17832 this.smaskPreparedOOBAlpha = null; 17833 } 17834 _ensurePreparedSMask(smask) { 17835 if (smask === this.smaskPreparedFor) { 17836 return; 17837 } 17838 this._clearPreparedSMask(); 17839 this._prepareSMaskCanvas(smask); 17840 } 17841 checkSMaskState(opIdx) { 17842 const inSMaskMode = this.inSMaskMode; 17843 if (this.current.activeSMask && !inSMaskMode) { 17844 this.beginSMaskMode(opIdx); 17845 } else if (!this.current.activeSMask && inSMaskMode) { 17846 this.endSMaskMode(); 17847 } else if (this.current.activeSMask && inSMaskMode) { 17848 this._ensurePreparedSMask(this.current.activeSMask); 17849 } 17850 } 17851 _prepareSMaskCanvas(smask) { 17852 const { 17853 canvas: maskCanvas, 17854 subtype, 17855 backdrop, 17856 transferMap 17857 } = smask; 17858 const hasFilter = subtype === "Luminosity" || subtype === "Alpha" && transferMap; 17859 if (!hasFilter && !(subtype === "Luminosity" && backdrop)) { 17860 this.smaskPreparedFor = smask; 17861 return; 17862 } 17863 let filteredOOBAlpha; 17864 if (subtype === "Luminosity" && backdrop) { 17865 const [r, g, b] = getRGBA(backdrop); 17866 const inputAlpha = Math.round(0.3 * r + 0.59 * g + 0.11 * b); 17867 filteredOOBAlpha = transferMap?.[inputAlpha] ?? inputAlpha; 17868 } else { 17869 filteredOOBAlpha = transferMap?.[0] ?? 0; 17870 } 17871 const SMASK_LAYER_TO_MASK_AREA_RATIO = 4; 17872 const { 17873 width: layerW, 17874 height: layerH 17875 } = this.ctx.canvas; 17876 const maskArea = maskCanvas.width * maskCanvas.height; 17877 const useLayerSize = layerW * layerH < SMASK_LAYER_TO_MASK_AREA_RATIO * maskArea; 17878 const filterSpec = hasFilter ? { 17879 url: subtype === "Alpha" ? this.filterFactory.addAlphaFilter(transferMap) : this.filterFactory.addLuminosityFilter(transferMap), 17880 subtype, 17881 transferMap 17882 } : null; 17883 const bakedBackdrop = subtype === "Luminosity" ? backdrop : null; 17884 let preparedEntry, offsetX, offsetY; 17885 if (useLayerSize) { 17886 preparedEntry = this._bakeSMaskCanvas(maskCanvas, smask.offsetX, smask.offsetY, layerW, layerH, bakedBackdrop, filterSpec); 17887 offsetX = 0; 17888 offsetY = 0; 17889 } else { 17890 preparedEntry = this._bakeSMaskCanvas(maskCanvas, 0, 0, maskCanvas.width, maskCanvas.height, bakedBackdrop, filterSpec); 17891 offsetX = smask.offsetX; 17892 offsetY = smask.offsetY; 17893 } 17894 this.smaskPreparedEntry = preparedEntry; 17895 this.smaskPreparedFor = smask; 17896 this.smaskPreparedOffsetX = offsetX; 17897 this.smaskPreparedOffsetY = offsetY; 17898 this.smaskPreparedOOBAlpha = !useLayerSize && filteredOOBAlpha !== 0 ? filteredOOBAlpha : null; 17899 } 17900 _bakeSMaskCanvas(maskCanvas, drawX, drawY, w, h, backdrop, filterSpec) { 17901 if (!backdrop && !filterSpec) { 17902 unreachable("_bakeSMaskCanvas with neither backdrop nor filter"); 17903 } 17904 const srcEntry = this.canvasFactory.create(w, h); 17905 const sCtx = srcEntry.context; 17906 sCtx.drawImage(maskCanvas, drawX, drawY); 17907 if (backdrop) { 17908 sCtx.globalCompositeOperation = "destination-atop"; 17909 sCtx.fillStyle = backdrop; 17910 sCtx.fillRect(0, 0, w, h); 17911 } 17912 if (!filterSpec) { 17913 return srcEntry; 17914 } 17915 const preparedEntry = this.canvasFactory.create(w, h); 17916 const pCtx = preparedEntry.context; 17917 pCtx.filter = filterSpec.url; 17918 const filterApplied = FeatureTest.isCanvasFilterSupported && pCtx.filter !== "none" && pCtx.filter !== ""; 17919 pCtx.drawImage(srcEntry.canvas, 0, 0); 17920 if (FeatureTest.isCanvasFilterSupported) { 17921 pCtx.filter = "none"; 17922 } 17923 if (!filterApplied) { 17924 const img = pCtx.getImageData(0, 0, w, h); 17925 const { 17926 data 17927 } = img; 17928 const { 17929 transferMap 17930 } = filterSpec; 17931 if (filterSpec.subtype === "Luminosity") { 17932 for (let i = 0, ii = data.length; i < ii; i += 4) { 17933 const a = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2] + 0.5 | 0; 17934 data[i] = data[i + 1] = data[i + 2] = 0; 17935 data[i + 3] = transferMap?.[a] ?? a; 17936 } 17937 } else { 17938 for (let i = 3, ii = data.length; i < ii; i += 4) { 17939 data[i] = transferMap[data[i]]; 17940 } 17941 } 17942 pCtx.putImageData(img, 0, 0); 17943 } 17944 this.canvasFactory.destroy(srcEntry); 17945 return preparedEntry; 17946 } 17947 beginSMaskMode(opIdx) { 17948 if (this.inSMaskMode) { 17949 throw new Error("beginSMaskMode called while already in smask mode"); 17950 } 17951 const { 17952 width: drawnWidth, 17953 height: drawnHeight 17954 } = this.ctx.canvas; 17955 const scratchCanvas = this.canvasFactory.create(drawnWidth, drawnHeight); 17956 this.smaskScratchCanvas = scratchCanvas; 17957 this.suspendedCtx = this.ctx; 17958 const ctx = this.ctx = scratchCanvas.context; 17959 ctx.setTransform(this.suspendedCtx.getTransform()); 17960 copyCtxState(this.suspendedCtx, ctx); 17961 mirrorContextOperations(ctx, this.suspendedCtx); 17962 this._ensurePreparedSMask(this.current.activeSMask); 17963 this.setGState(opIdx, [["BM", "source-over"]]); 17964 } 17965 endSMaskMode() { 17966 if (!this.inSMaskMode) { 17967 throw new Error("endSMaskMode called while not in smask mode"); 17968 } 17969 this.ctx._removeMirroring(); 17970 copyCtxState(this.ctx, this.suspendedCtx); 17971 this.ctx = this.suspendedCtx; 17972 this.suspendedCtx = null; 17973 this.canvasFactory.destroy(this.smaskScratchCanvas); 17974 this.smaskScratchCanvas = null; 17975 this._clearPreparedSMask(); 17976 } 17977 #createKnockoutMaskCanvas(sourceCanvas, reuseEntry = null, alpha = 1) { 17978 const { 17979 width, 17980 height 17981 } = sourceCanvas; 17982 const maskEntry = reuseEntry ?? this.canvasFactory.create(width, height); 17983 const maskCtx = maskEntry.context; 17984 alpha = Math.round(alpha * 255) / 255; 17985 const needsAlphaScaling = alpha < 1; 17986 if (needsAlphaScaling && this.#knockoutFilterCache === undefined) { 17987 this.#knockoutFilterCache = FeatureTest.isCanvasFilterSupported ? new Map() : "none"; 17988 } 17989 let knockoutFilter = "none"; 17990 if (needsAlphaScaling && this.#knockoutFilterCache instanceof Map) { 17991 knockoutFilter = this.#knockoutFilterCache.getOrInsertComputed(alpha, () => this.filterFactory.addKnockoutFilter(alpha)); 17992 } 17993 if (!needsAlphaScaling || knockoutFilter !== "none") { 17994 if (reuseEntry) { 17995 maskCtx.save(); 17996 maskCtx.setTransform(1, 0, 0, 1, 0, 0); 17997 maskCtx.clearRect(0, 0, width, height); 17998 maskCtx.restore(); 17999 } 18000 maskCtx.filter = knockoutFilter; 18001 maskCtx.drawImage(sourceCanvas, 0, 0); 18002 maskCtx.filter = "none"; 18003 return maskEntry; 18004 } 18005 const sourceData = sourceCanvas.getContext("2d", { 18006 willReadFrequently: true 18007 }).getImageData(0, 0, width, height); 18008 const maskData = maskCtx.createImageData(width, height); 18009 const sourcePixels = sourceData.data, 18010 maskPixels = maskData.data; 18011 const alphaScale = alpha > 0 ? 1 / alpha : 1e6; 18012 for (let i = 3, ii = sourcePixels.length; i < ii; i += 4) { 18013 maskPixels[i] = Math.min(Math.round(sourcePixels[i] * alphaScale), 255); 18014 } 18015 maskCtx.putImageData(maskData, 0, 0); 18016 return maskEntry; 18017 } 18018 #getOrCreatePooledEntry(meta, key, width, height) { 18019 let entry = meta?.[key] ?? null; 18020 if (entry && (entry.canvas.width !== width || entry.canvas.height !== height)) { 18021 this.canvasFactory.destroy(entry); 18022 entry = null; 18023 } 18024 if (!entry) { 18025 entry = this.canvasFactory.create(width, height); 18026 if (meta) { 18027 meta[key] = entry; 18028 } 18029 return entry; 18030 } 18031 const ctx = entry.context; 18032 ctx.save(); 18033 ctx.setTransform(1, 0, 0, 1, 0, 0); 18034 ctx.clearRect(0, 0, width, height); 18035 ctx.restore(); 18036 return entry; 18037 } 18038 #compositeKnockoutSurface(destCtx, surfaceCanvas, options = {}) { 18039 const { 18040 backdropCanvas = null, 18041 destTransform = [1, 0, 0, 1, 0, 0], 18042 backdropOffset = [0, 0], 18043 reuseMaskEntry = null, 18044 poolMeta = null, 18045 sourceAlpha = 1, 18046 sourceFilter = "none", 18047 knockoutAlpha = 1 18048 } = options; 18049 const { 18050 width, 18051 height 18052 } = surfaceCanvas; 18053 const knockoutMaskEntry = this.#createKnockoutMaskCanvas(surfaceCanvas, reuseMaskEntry, knockoutAlpha); 18054 const sourceCompositeOperation = destCtx.globalCompositeOperation; 18055 destCtx.save(); 18056 destCtx.setTransform(...destTransform); 18057 destCtx.globalAlpha = 1; 18058 if (FeatureTest.isCanvasFilterSupported) { 18059 destCtx.filter = "none"; 18060 } 18061 destCtx.globalCompositeOperation = "destination-out"; 18062 destCtx.drawImage(knockoutMaskEntry.canvas, 0, 0); 18063 if (backdropCanvas) { 18064 const [bx, by] = backdropOffset; 18065 const backdropEntry = this.#getOrCreatePooledEntry(poolMeta, "knockoutBackdropEntry", width, height); 18066 const backdropCtx = backdropEntry.context; 18067 backdropCtx.drawImage(backdropCanvas, bx, by, width, height, 0, 0, width, height); 18068 backdropCtx.globalCompositeOperation = "destination-in"; 18069 backdropCtx.drawImage(knockoutMaskEntry.canvas, 0, 0); 18070 backdropCtx.globalCompositeOperation = "source-over"; 18071 destCtx.globalCompositeOperation = "destination-over"; 18072 destCtx.drawImage(backdropEntry.canvas, 0, 0); 18073 if (!poolMeta) { 18074 this.canvasFactory.destroy(backdropEntry); 18075 } 18076 } 18077 destCtx.globalCompositeOperation = sourceCompositeOperation; 18078 destCtx.globalAlpha = sourceAlpha; 18079 if (FeatureTest.isCanvasFilterSupported) { 18080 destCtx.filter = sourceFilter ?? "none"; 18081 } 18082 destCtx.drawImage(surfaceCanvas, 0, 0); 18083 destCtx.restore(); 18084 if (!reuseMaskEntry) { 18085 this.canvasFactory.destroy(knockoutMaskEntry); 18086 } 18087 } 18088 #beginKnockoutElement(alpha = 1) { 18089 if (this.#knockoutGroupLevel === 0 || this.#knockoutElementDepth > 0 || !this.contentVisible) { 18090 return false; 18091 } 18092 this.#knockoutElementDepth++; 18093 this.#knockoutElementAlpha = alpha; 18094 const groupMeta = this.#groupStackMeta.at(-1); 18095 const { 18096 canvas 18097 } = this.ctx; 18098 const tempEntry = this.#getOrCreatePooledEntry(groupMeta, "knockoutTempEntry", canvas.width, canvas.height); 18099 this.#knockoutTempCanvasEntry = tempEntry; 18100 const tempCtx = tempEntry.context; 18101 tempCtx.save(); 18102 tempCtx.setTransform(this.ctx.getTransform()); 18103 copyCtxState(this.ctx, tempCtx); 18104 this.#knockoutSavedGCO = tempCtx.globalCompositeOperation; 18105 tempCtx.globalCompositeOperation = "source-over"; 18106 mirrorContextOperations(tempCtx, this.ctx); 18107 this.#knockoutElementGroupMeta = groupMeta; 18108 this.#knockoutSavedCtx = this.ctx; 18109 this.#knockoutSavedSMaskCtx = this.suspendedCtx; 18110 this.ctx = tempCtx; 18111 if (this.inSMaskMode) { 18112 this.suspendedCtx = tempCtx; 18113 } 18114 return true; 18115 } 18116 #endKnockoutElement(started) { 18117 if (!started) { 18118 return; 18119 } 18120 const tempEntry = this.#knockoutTempCanvasEntry; 18121 const savedCtx = this.#knockoutSavedCtx; 18122 const savedSMaskCtx = this.#knockoutSavedSMaskCtx; 18123 const tempCtx = tempEntry.context; 18124 this.#knockoutTempCanvasEntry = null; 18125 this.#knockoutSavedCtx = null; 18126 this.#knockoutSavedSMaskCtx = null; 18127 if (this.inSMaskMode && this.suspendedCtx === tempCtx && this.ctx !== tempCtx) { 18128 this.endSMaskMode(); 18129 } 18130 if (this.inSMaskMode) { 18131 this.suspendedCtx = savedSMaskCtx; 18132 } 18133 this.ctx._removeMirroring(); 18134 this.ctx.globalCompositeOperation = this.#knockoutSavedGCO; 18135 this.#knockoutSavedGCO = null; 18136 copyCtxState(this.ctx, savedCtx); 18137 this.ctx = savedCtx; 18138 const groupMeta = this.#knockoutElementGroupMeta; 18139 this.#knockoutElementGroupMeta = null; 18140 const knockoutAlpha = this.#knockoutElementAlpha; 18141 this.#knockoutElementAlpha = 1; 18142 try { 18143 this.#compositeKnockoutSurface(savedSMaskCtx ?? savedCtx, tempEntry.canvas, { 18144 backdropCanvas: groupMeta?.backdropCtx?.canvas ?? null, 18145 backdropOffset: groupMeta?.backdropCtx ? [groupMeta.offsetX, groupMeta.offsetY] : [0, 0], 18146 reuseMaskEntry: groupMeta?.knockoutMaskEntry ?? null, 18147 poolMeta: groupMeta, 18148 knockoutAlpha 18149 }); 18150 } finally { 18151 tempCtx.restore(); 18152 this.#knockoutElementDepth--; 18153 if (!groupMeta) { 18154 this.canvasFactory.destroy(tempEntry); 18155 } 18156 } 18157 } 18158 compose(dirtyBox) { 18159 if (!this.current.activeSMask) { 18160 return; 18161 } 18162 dirtyBox = dirtyBox ? [Math.floor(dirtyBox[0]), Math.floor(dirtyBox[1]), Math.ceil(dirtyBox[2]), Math.ceil(dirtyBox[3])] : [0, 0, this.ctx.canvas.width, this.ctx.canvas.height]; 18163 const smask = this.current.activeSMask; 18164 const suspendedCtx = this.suspendedCtx; 18165 const applySMaskInPlace = this.#knockoutElementDepth > 0 && suspendedCtx === this.ctx; 18166 this.composeSMask(applySMaskInPlace ? null : suspendedCtx, smask, this.ctx, dirtyBox); 18167 if (applySMaskInPlace) { 18168 return; 18169 } 18170 this.ctx.save(); 18171 this.ctx.setTransform(1, 0, 0, 1, 0, 0); 18172 this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); 18173 this.ctx.restore(); 18174 } 18175 composeSMask(ctx, smask, layerCtx, layerBox) { 18176 const layerOffsetX = layerBox[0]; 18177 const layerOffsetY = layerBox[1]; 18178 const layerWidth = layerBox[2] - layerOffsetX; 18179 const layerHeight = layerBox[3] - layerOffsetY; 18180 if (layerWidth === 0 || layerHeight === 0) { 18181 return; 18182 } 18183 const preparedEntry = this.smaskPreparedEntry; 18184 if (preparedEntry) { 18185 let clipX = layerOffsetX; 18186 let clipY = layerOffsetY; 18187 let clipW = layerWidth; 18188 let clipH = layerHeight; 18189 const oobAlpha = this.smaskPreparedOOBAlpha; 18190 const hasOOBAlpha = oobAlpha !== null; 18191 if (hasOOBAlpha) { 18192 clipX = Math.max(layerOffsetX, smask.offsetX); 18193 clipY = Math.max(layerOffsetY, smask.offsetY); 18194 const x1 = Math.min(layerOffsetX + layerWidth, smask.offsetX + smask.canvas.width); 18195 const y1 = Math.min(layerOffsetY + layerHeight, smask.offsetY + smask.canvas.height); 18196 clipW = x1 - clipX; 18197 clipH = y1 - clipY; 18198 } 18199 if (clipW > 0 && clipH > 0) { 18200 const srcX = clipX - this.smaskPreparedOffsetX; 18201 const srcY = clipY - this.smaskPreparedOffsetY; 18202 layerCtx.save(); 18203 layerCtx.globalAlpha = 1; 18204 layerCtx.setTransform(1, 0, 0, 1, 0, 0); 18205 const clip = new Path2D(); 18206 clip.rect(clipX, clipY, clipW, clipH); 18207 layerCtx.clip(clip); 18208 layerCtx.globalCompositeOperation = "destination-in"; 18209 layerCtx.drawImage(preparedEntry.canvas, srcX, srcY, clipW, clipH, clipX, clipY, clipW, clipH); 18210 layerCtx.restore(); 18211 } 18212 if (hasOOBAlpha && oobAlpha < 255) { 18213 this._applySMaskOOBAlpha(layerCtx, layerOffsetX, layerOffsetY, layerWidth, layerHeight, clipX, clipY, clipX + clipW, clipY + clipH, oobAlpha); 18214 } 18215 } else { 18216 this.genericComposeSMask(smask, layerCtx, layerWidth, layerHeight, layerOffsetX, layerOffsetY); 18217 } 18218 if (!ctx) { 18219 return; 18220 } 18221 ctx.save(); 18222 ctx.globalAlpha = 1; 18223 ctx.globalCompositeOperation = smask.blendMode || "source-over"; 18224 ctx.setTransform(1, 0, 0, 1, 0, 0); 18225 ctx.drawImage(layerCtx.canvas, layerOffsetX, layerOffsetY, layerWidth, layerHeight, layerOffsetX, layerOffsetY, layerWidth, layerHeight); 18226 ctx.restore(); 18227 } 18228 _applySMaskOOBAlpha(layerCtx, layerOffsetX, layerOffsetY, layerWidth, layerHeight, maskX0, maskY0, maskX1, maskY1, alpha) { 18229 const hasInnerCutout = maskX0 < maskX1 && maskY0 < maskY1; 18230 if (hasInnerCutout && maskX0 === layerOffsetX && maskY0 === layerOffsetY && maskX1 === layerOffsetX + layerWidth && maskY1 === layerOffsetY + layerHeight) { 18231 return; 18232 } 18233 const path = new Path2D(); 18234 path.rect(layerOffsetX, layerOffsetY, layerWidth, layerHeight); 18235 if (hasInnerCutout) { 18236 path.rect(maskX0, maskY0, maskX1 - maskX0, maskY1 - maskY0); 18237 } 18238 layerCtx.save(); 18239 layerCtx.globalAlpha = alpha / 255; 18240 layerCtx.setTransform(1, 0, 0, 1, 0, 0); 18241 layerCtx.clip(path, "evenodd"); 18242 layerCtx.globalCompositeOperation = "destination-in"; 18243 layerCtx.fillStyle = "#000000"; 18244 layerCtx.fillRect(layerOffsetX, layerOffsetY, layerWidth, layerHeight); 18245 layerCtx.restore(); 18246 } 18247 genericComposeSMask(smask, layerCtx, width, height, layerOffsetX, layerOffsetY) { 18248 const { 18249 context: maskCtx, 18250 offsetX: maskOffsetX, 18251 offsetY: maskOffsetY 18252 } = smask; 18253 layerCtx.save(); 18254 layerCtx.globalAlpha = 1; 18255 layerCtx.setTransform(1, 0, 0, 1, 0, 0); 18256 const clip = new Path2D(); 18257 clip.rect(layerOffsetX, layerOffsetY, width, height); 18258 layerCtx.clip(clip); 18259 layerCtx.globalCompositeOperation = "destination-in"; 18260 layerCtx.drawImage(maskCtx.canvas, layerOffsetX - maskOffsetX, layerOffsetY - maskOffsetY, width, height, layerOffsetX, layerOffsetY, width, height); 18261 layerCtx.restore(); 18262 } 18263 save(opIdx) { 18264 if (this.inSMaskMode) { 18265 copyCtxState(this.ctx, this.suspendedCtx); 18266 } 18267 this.ctx.save(); 18268 const old = this.current; 18269 this.stateStack.push(old); 18270 this.current = old.clone(); 18271 this.dependencyTracker?.save(opIdx); 18272 } 18273 restore(opIdx) { 18274 this.dependencyTracker?.restore(opIdx); 18275 if (this.stateStack.length === 0) { 18276 if (this.inSMaskMode) { 18277 this.endSMaskMode(); 18278 } 18279 return; 18280 } 18281 this.current = this.stateStack.pop(); 18282 this.ctx.restore(); 18283 if (this.inSMaskMode) { 18284 copyCtxState(this.suspendedCtx, this.ctx); 18285 this.ctx.setTransform(this.suspendedCtx.getTransform()); 18286 } 18287 this.checkSMaskState(opIdx); 18288 this.pendingClip = null; 18289 this._cachedScaleForStroking[0] = -1; 18290 this._cachedGetSinglePixelWidth = null; 18291 } 18292 transform(opIdx, a, b, c, d, e, f) { 18293 this.dependencyTracker?.recordIncrementalData("transform", opIdx); 18294 this.ctx.transform(a, b, c, d, e, f); 18295 this._cachedScaleForStroking[0] = -1; 18296 this._cachedGetSinglePixelWidth = null; 18297 } 18298 constructPath(opIdx, op, data, minMax) { 18299 let [path] = data; 18300 if (!minMax) { 18301 path ||= data[0] = new Path2D(); 18302 if (op !== OPS.stroke && op !== OPS.closeStroke) { 18303 this.current.tilingPatternDims = null; 18304 } 18305 this[op](opIdx, path); 18306 return; 18307 } 18308 if (this.dependencyTracker !== null) { 18309 const outerExtraSize = op === OPS.stroke ? this.current.lineWidth / 2 : 0; 18310 this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, this.ctx, minMax[0] - outerExtraSize, minMax[2] + outerExtraSize, minMax[1] - outerExtraSize, minMax[3] + outerExtraSize).recordDependencies(opIdx, ["transform"]); 18311 } 18312 if (!(path instanceof Path2D)) { 18313 path = data[0] = makePathFromDrawOPS(path); 18314 } 18315 Util.axialAlignedBoundingBox(minMax, getCurrentTransform(this.ctx), this.current.minMax); 18316 const tilingDims = this.current.tilingPatternDims; 18317 if (tilingDims && op !== OPS.stroke && op !== OPS.closeStroke && this.current.fillColor instanceof TilingPattern) { 18318 const clippedBBox = Util.intersect(this.current.clipBox, this.current.minMax); 18319 if (!clippedBBox) { 18320 this.current.tilingPatternDims = null; 18321 } else { 18322 this.current.fillColor.updatePatternDims(clippedBBox, tilingDims); 18323 } 18324 } 18325 this[op](opIdx, path); 18326 this._pathStartIdx = opIdx; 18327 } 18328 closePath(opIdx) { 18329 this.ctx.closePath(); 18330 } 18331 stroke(opIdx, path, consumePath = true) { 18332 const started = consumePath && this.#beginKnockoutElement(this.current.strokeAlpha); 18333 const ctx = this.ctx; 18334 const strokeColor = this.current.strokeColor; 18335 ctx.globalAlpha = this.current.strokeAlpha; 18336 if (this.contentVisible) { 18337 if (typeof strokeColor === "object" && strokeColor?.getPattern) { 18338 const baseTransform = strokeColor.isModifyingCurrentTransform() ? ctx.getTransform() : null; 18339 ctx.save(); 18340 ctx.strokeStyle = strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx); 18341 if (baseTransform) { 18342 const newPath = new Path2D(); 18343 newPath.addPath(path, ctx.getTransform().invertSelf().multiplySelf(baseTransform)); 18344 path = newPath; 18345 } 18346 this.rescaleAndStroke(path, false); 18347 ctx.restore(); 18348 } else { 18349 this.rescaleAndStroke(path, true); 18350 } 18351 } 18352 this.dependencyTracker?.recordDependencies(opIdx, Dependencies.stroke); 18353 if (consumePath) { 18354 this.consumePath(opIdx, path, this.current.getClippedPathBoundingBox(PathType.STROKE, getCurrentTransform(this.ctx))); 18355 } 18356 ctx.globalAlpha = this.current.fillAlpha; 18357 this.#endKnockoutElement(started); 18358 } 18359 closeStroke(opIdx, path) { 18360 this.stroke(opIdx, path); 18361 } 18362 fill(opIdx, path, consumePath = true) { 18363 const started = consumePath && this.#beginKnockoutElement(this.current.fillAlpha); 18364 const ctx = this.ctx; 18365 const fillColor = this.current.fillColor; 18366 const isPatternFill = this.current.patternFill; 18367 let needRestore = false; 18368 const intersect = this.current.getClippedPathBoundingBox(); 18369 this.dependencyTracker?.recordDependencies(opIdx, Dependencies.fill); 18370 if (isPatternFill) { 18371 const dims = this.current.tilingPatternDims; 18372 const tileIdx = dims && fillColor.canSkipPatternCanvas(dims); 18373 if (tileIdx) { 18374 fillColor.drawPattern(this, path, this.pendingEOFill, tileIdx, opIdx); 18375 this.pendingEOFill = false; 18376 if (consumePath) { 18377 this.consumePath(opIdx, path, intersect); 18378 } 18379 this.current.tilingPatternDims = null; 18380 this.#endKnockoutElement(started); 18381 return; 18382 } 18383 const baseTransform = fillColor.isModifyingCurrentTransform() ? ctx.getTransform() : null; 18384 this.dependencyTracker?.save(opIdx); 18385 ctx.save(); 18386 ctx.fillStyle = fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx); 18387 if (baseTransform) { 18388 const newPath = new Path2D(); 18389 newPath.addPath(path, ctx.getTransform().invertSelf().multiplySelf(baseTransform)); 18390 path = newPath; 18391 } 18392 needRestore = true; 18393 } 18394 if (this.contentVisible && intersect !== null) { 18395 if (this.pendingEOFill) { 18396 ctx.fill(path, "evenodd"); 18397 this.pendingEOFill = false; 18398 } else { 18399 ctx.fill(path); 18400 } 18401 } 18402 if (needRestore) { 18403 ctx.restore(); 18404 this.dependencyTracker?.restore(opIdx); 18405 } 18406 if (consumePath) { 18407 this.consumePath(opIdx, path, intersect); 18408 } 18409 this.#endKnockoutElement(started); 18410 } 18411 eoFill(opIdx, path) { 18412 this.pendingEOFill = true; 18413 this.fill(opIdx, path); 18414 } 18415 fillStroke(opIdx, path) { 18416 const started = this.#beginKnockoutElement(Math.min(this.current.fillAlpha, this.current.strokeAlpha)); 18417 this.fill(opIdx, path, false); 18418 this.stroke(opIdx, path, false); 18419 this.consumePath(opIdx, path); 18420 this.#endKnockoutElement(started); 18421 } 18422 eoFillStroke(opIdx, path) { 18423 this.pendingEOFill = true; 18424 this.fillStroke(opIdx, path); 18425 } 18426 closeFillStroke(opIdx, path) { 18427 this.fillStroke(opIdx, path); 18428 } 18429 closeEOFillStroke(opIdx, path) { 18430 this.pendingEOFill = true; 18431 this.fillStroke(opIdx, path); 18432 } 18433 endPath(opIdx, path) { 18434 this.consumePath(opIdx, path); 18435 } 18436 rawFillPath(opIdx, path) { 18437 const started = this.#beginKnockoutElement(this.current.fillAlpha); 18438 this.ctx.fill(path); 18439 this.dependencyTracker?.recordDependencies(opIdx, Dependencies.rawFillPath).recordOperation(opIdx); 18440 this.#endKnockoutElement(started); 18441 } 18442 clip(opIdx) { 18443 this.dependencyTracker?.recordFutureForcedDependency("clipMode", opIdx); 18444 this.pendingClip = NORMAL_CLIP; 18445 } 18446 eoClip(opIdx) { 18447 this.dependencyTracker?.recordFutureForcedDependency("clipMode", opIdx); 18448 this.pendingClip = EO_CLIP; 18449 } 18450 beginText(opIdx) { 18451 this.current.textMatrix = null; 18452 this.current.textMatrixScale = 1; 18453 this.current.x = this.current.lineX = 0; 18454 this.current.y = this.current.lineY = 0; 18455 this.dependencyTracker?.recordOpenMarker(opIdx).resetIncrementalData("sameLineText").resetIncrementalData("moveText", opIdx); 18456 } 18457 endText(opIdx) { 18458 const paths = this.pendingTextPaths; 18459 const ctx = this.ctx; 18460 if (this.dependencyTracker) { 18461 const { 18462 dependencyTracker 18463 } = this; 18464 if (paths !== undefined) { 18465 dependencyTracker.recordFutureForcedDependency("textClip", dependencyTracker.getOpenMarker()).recordFutureForcedDependency("textClip", opIdx); 18466 } 18467 dependencyTracker.recordCloseMarker(opIdx); 18468 } 18469 if (paths !== undefined) { 18470 const newPath = new Path2D(); 18471 const invTransf = ctx.getTransform().invertSelf(); 18472 for (const { 18473 transform, 18474 x, 18475 y, 18476 fontSize, 18477 path 18478 } of paths) { 18479 if (!path) { 18480 continue; 18481 } 18482 newPath.addPath(path, new DOMMatrix(transform).preMultiplySelf(invTransf).translate(x, y).scale(fontSize, -fontSize)); 18483 } 18484 ctx.clip(newPath); 18485 } 18486 delete this.pendingTextPaths; 18487 } 18488 setCharSpacing(opIdx, spacing) { 18489 this.dependencyTracker?.recordSimpleData("charSpacing", opIdx); 18490 this.current.charSpacing = spacing; 18491 } 18492 setWordSpacing(opIdx, spacing) { 18493 this.dependencyTracker?.recordSimpleData("wordSpacing", opIdx); 18494 this.current.wordSpacing = spacing; 18495 } 18496 setHScale(opIdx, scale) { 18497 this.dependencyTracker?.recordSimpleData("hScale", opIdx); 18498 this.current.textHScale = scale / 100; 18499 } 18500 setLeading(opIdx, leading) { 18501 this.dependencyTracker?.recordSimpleData("leading", opIdx); 18502 this.current.leading = -leading; 18503 } 18504 setFont(opIdx, fontRefName, size) { 18505 this.dependencyTracker?.recordSimpleData("font", opIdx).recordSimpleDataFromNamed("fontObj", fontRefName, opIdx); 18506 const fontObj = this.commonObjs.get(fontRefName); 18507 const current = this.current; 18508 if (!fontObj) { 18509 throw new Error(`Can't find font for ${fontRefName}`); 18510 } 18511 current.fontMatrix = fontObj.fontMatrix || FONT_IDENTITY_MATRIX; 18512 if (current.fontMatrix[0] === 0 || current.fontMatrix[3] === 0) { 18513 warn("Invalid font matrix for font " + fontRefName); 18514 } 18515 if (size < 0) { 18516 size = -size; 18517 current.fontDirection = -1; 18518 } else { 18519 current.fontDirection = 1; 18520 } 18521 this.current.font = fontObj; 18522 this.current.fontSize = size; 18523 if (fontObj.isType3Font) { 18524 return; 18525 } 18526 const name = fontObj.loadedName || "sans-serif"; 18527 const typeface = fontObj.systemFontInfo?.css || `"${name}", ${fontObj.fallbackName}`; 18528 let bold = "normal"; 18529 if (fontObj.black) { 18530 bold = "900"; 18531 } else if (fontObj.bold) { 18532 bold = "bold"; 18533 } 18534 const italic = fontObj.italic ? "italic" : "normal"; 18535 const browserFontSize = MathClamp(size, MIN_FONT_SIZE, MAX_FONT_SIZE); 18536 this.current.fontSizeScale = size / browserFontSize; 18537 this.ctx.font = `${italic} ${bold} ${browserFontSize}px ${typeface}`; 18538 } 18539 setTextRenderingMode(opIdx, mode) { 18540 this.dependencyTracker?.recordSimpleData("textRenderingMode", opIdx); 18541 this.current.textRenderingMode = mode; 18542 } 18543 setTextRise(opIdx, rise) { 18544 this.dependencyTracker?.recordSimpleData("textRise", opIdx); 18545 this.current.textRise = rise; 18546 } 18547 moveText(opIdx, x, y) { 18548 this.dependencyTracker?.resetIncrementalData("sameLineText").recordIncrementalData("moveText", opIdx); 18549 this.current.x = this.current.lineX += x; 18550 this.current.y = this.current.lineY += y; 18551 } 18552 setLeadingMoveText(opIdx, x, y) { 18553 this.setLeading(opIdx, -y); 18554 this.moveText(opIdx, x, y); 18555 } 18556 setTextMatrix(opIdx, matrix) { 18557 this.dependencyTracker?.resetIncrementalData("sameLineText").recordSimpleData("textMatrix", opIdx); 18558 const { 18559 current 18560 } = this; 18561 current.textMatrix = matrix; 18562 current.textMatrixScale = Math.hypot(matrix[0], matrix[1]); 18563 current.x = current.lineX = 0; 18564 current.y = current.lineY = 0; 18565 } 18566 nextLine(opIdx) { 18567 this.moveText(opIdx, 0, this.current.leading); 18568 this.dependencyTracker?.recordIncrementalData("moveText", this.dependencyTracker.getSimpleIndex("leading") ?? opIdx); 18569 } 18570 #getScaledPath(path, currentTransform, transform) { 18571 const newPath = new Path2D(); 18572 newPath.addPath(path, new DOMMatrix(transform).invertSelf().multiplySelf(currentTransform)); 18573 return newPath; 18574 } 18575 paintChar(opIdx, character, x, y, patternFillTransform, patternStrokeTransform) { 18576 const ctx = this.ctx; 18577 const current = this.current; 18578 const font = current.font; 18579 const textRenderingMode = current.textRenderingMode; 18580 const fontSize = current.fontSize / current.fontSizeScale; 18581 const fillStrokeMode = textRenderingMode & TextRenderingMode.FILL_STROKE_MASK; 18582 const isAddToPathSet = !!(textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG); 18583 const patternFill = current.patternFill && !font.missingFile; 18584 const patternStroke = current.patternStroke && !font.missingFile; 18585 let path; 18586 if ((font.disableFontFace || isAddToPathSet || patternFill || patternStroke) && !font.missingFile) { 18587 path = font.getPathGenerator(this.commonObjs, character); 18588 } 18589 if (path && (font.disableFontFace || patternFill || patternStroke)) { 18590 ctx.save(); 18591 ctx.translate(x, y); 18592 ctx.scale(fontSize, -fontSize); 18593 this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font); 18594 let currentTransform; 18595 if (fillStrokeMode === TextRenderingMode.FILL || fillStrokeMode === TextRenderingMode.FILL_STROKE) { 18596 if (patternFillTransform) { 18597 currentTransform = ctx.getTransform(); 18598 ctx.setTransform(...patternFillTransform); 18599 const scaledPath = this.#getScaledPath(path, currentTransform, patternFillTransform); 18600 ctx.fill(scaledPath); 18601 } else { 18602 ctx.fill(path); 18603 } 18604 } 18605 if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) { 18606 if (patternStrokeTransform) { 18607 currentTransform ||= ctx.getTransform(); 18608 ctx.setTransform(...patternStrokeTransform); 18609 const { 18610 a, 18611 b, 18612 c, 18613 d 18614 } = currentTransform; 18615 const invPatternTransform = Util.inverseTransform(patternStrokeTransform); 18616 const transf = Util.transform([a, b, c, d, 0, 0], invPatternTransform); 18617 Util.singularValueDecompose2dScale(transf, XY); 18618 ctx.lineWidth *= Math.max(XY[0], XY[1]) / fontSize; 18619 ctx.stroke(this.#getScaledPath(path, currentTransform, patternStrokeTransform)); 18620 } else { 18621 ctx.lineWidth /= fontSize; 18622 ctx.stroke(path); 18623 } 18624 } 18625 ctx.restore(); 18626 } else { 18627 if (fillStrokeMode === TextRenderingMode.FILL || fillStrokeMode === TextRenderingMode.FILL_STROKE) { 18628 ctx.fillText(character, x, y); 18629 this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y, () => ctx.measureText(character)); 18630 } 18631 if (fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE) { 18632 if (this.dependencyTracker) { 18633 this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y, () => ctx.measureText(character)).recordDependencies(opIdx, Dependencies.stroke); 18634 } 18635 ctx.strokeText(character, x, y); 18636 } 18637 } 18638 if (isAddToPathSet) { 18639 const paths = this.pendingTextPaths ||= []; 18640 paths.push({ 18641 transform: getCurrentTransform(ctx), 18642 x, 18643 y, 18644 fontSize, 18645 path 18646 }); 18647 this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, font, fontSize, x, y); 18648 } 18649 } 18650 get isFontSubpixelAAEnabled() { 18651 const tmpCanvas = this.canvasFactory.create(10, 10); 18652 const ctx = tmpCanvas.context; 18653 ctx.scale(1.5, 1); 18654 ctx.fillText("I", 0, 10); 18655 const data = ctx.getImageData(0, 0, 10, 10).data; 18656 this.canvasFactory.destroy(tmpCanvas); 18657 let enabled = false; 18658 for (let i = 3; i < data.length; i += 4) { 18659 if (data[i] > 0 && data[i] < 255) { 18660 enabled = true; 18661 break; 18662 } 18663 } 18664 return shadow(this, "isFontSubpixelAAEnabled", enabled); 18665 } 18666 showText(opIdx, glyphs) { 18667 if (this.dependencyTracker) { 18668 this.dependencyTracker.recordDependencies(opIdx, Dependencies.showText).resetBBox(opIdx); 18669 if (this.current.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG) { 18670 this.dependencyTracker.recordFutureForcedDependency("textClip", opIdx).inheritPendingDependenciesAsFutureForcedDependencies(); 18671 } 18672 } 18673 const current = this.current; 18674 const font = current.font; 18675 if (font.isType3Font) { 18676 const started = this.#beginKnockoutElement(current.fillAlpha); 18677 this.showType3Text(opIdx, glyphs); 18678 this.dependencyTracker?.recordShowTextOperation(opIdx); 18679 this.#endKnockoutElement(started); 18680 return; 18681 } 18682 const fontSize = current.fontSize; 18683 if (fontSize === 0) { 18684 this.dependencyTracker?.recordOperation(opIdx); 18685 return; 18686 } 18687 const started = this.#beginKnockoutElement(current.fillAlpha); 18688 const ctx = this.ctx; 18689 const fontSizeScale = current.fontSizeScale; 18690 const charSpacing = current.charSpacing; 18691 const wordSpacing = current.wordSpacing; 18692 const fontDirection = current.fontDirection; 18693 const textHScale = current.textHScale * fontDirection; 18694 const glyphsLength = glyphs.length; 18695 const vertical = font.vertical; 18696 const spacingDir = vertical ? 1 : -1; 18697 const defaultVMetrics = font.defaultVMetrics; 18698 const widthAdvanceScale = fontSize * current.fontMatrix[0]; 18699 const simpleFillText = current.textRenderingMode === TextRenderingMode.FILL && !font.disableFontFace && !current.patternFill; 18700 ctx.save(); 18701 if (current.textMatrix) { 18702 ctx.transform(...current.textMatrix); 18703 } 18704 ctx.translate(current.x, current.y + current.textRise); 18705 if (fontDirection > 0) { 18706 ctx.scale(textHScale, -1); 18707 } else { 18708 ctx.scale(textHScale, 1); 18709 } 18710 let patternFillTransform, patternStrokeTransform; 18711 const fillStrokeMode = current.textRenderingMode & TextRenderingMode.FILL_STROKE_MASK; 18712 const needsFill = fillStrokeMode === TextRenderingMode.FILL || fillStrokeMode === TextRenderingMode.FILL_STROKE; 18713 const needsStroke = fillStrokeMode === TextRenderingMode.STROKE || fillStrokeMode === TextRenderingMode.FILL_STROKE; 18714 let lineWidth = current.lineWidth; 18715 const scale = current.textMatrixScale; 18716 if (scale === 0 || lineWidth === 0) { 18717 if (needsStroke) { 18718 lineWidth = this.getSinglePixelWidth(); 18719 } 18720 } else { 18721 lineWidth /= scale; 18722 } 18723 if (fontSizeScale !== 1.0) { 18724 ctx.scale(fontSizeScale, fontSizeScale); 18725 lineWidth /= fontSizeScale; 18726 } 18727 ctx.lineWidth = lineWidth; 18728 if (needsFill && current.patternFill) { 18729 ctx.save(); 18730 const pattern = current.fillColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx); 18731 patternFillTransform = getCurrentTransform(ctx); 18732 ctx.restore(); 18733 ctx.fillStyle = pattern; 18734 } 18735 if (needsStroke && current.patternStroke) { 18736 ctx.save(); 18737 const pattern = current.strokeColor.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.STROKE, opIdx); 18738 patternStrokeTransform = getCurrentTransform(ctx); 18739 ctx.restore(); 18740 ctx.strokeStyle = pattern; 18741 } 18742 if (font.isInvalidPDFjsFont) { 18743 const chars = []; 18744 let width = 0; 18745 for (const glyph of glyphs) { 18746 chars.push(glyph.unicode); 18747 width += glyph.width; 18748 } 18749 const joinedChars = chars.join(""); 18750 ctx.fillText(joinedChars, 0, 0); 18751 if (this.dependencyTracker !== null) { 18752 const measure = ctx.measureText(joinedChars); 18753 this.dependencyTracker.recordBBox(opIdx, this.ctx, -measure.actualBoundingBoxLeft, measure.actualBoundingBoxRight, -measure.actualBoundingBoxAscent, measure.actualBoundingBoxDescent).recordShowTextOperation(opIdx); 18754 } 18755 current.x += width * widthAdvanceScale * textHScale; 18756 ctx.restore(); 18757 this.compose(); 18758 this.#endKnockoutElement(started); 18759 return; 18760 } 18761 let x = 0, 18762 i; 18763 for (i = 0; i < glyphsLength; ++i) { 18764 const glyph = glyphs[i]; 18765 if (typeof glyph === "number") { 18766 x += spacingDir * glyph * fontSize / 1000; 18767 continue; 18768 } 18769 let restoreNeeded = false; 18770 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 18771 const character = glyph.fontChar; 18772 const accent = glyph.accent; 18773 let scaledX, scaledY; 18774 let width = glyph.width; 18775 if (vertical) { 18776 const vmetric = glyph.vmetric || defaultVMetrics; 18777 const vx = -(glyph.vmetric ? vmetric[1] : width * 0.5) * widthAdvanceScale; 18778 const vy = vmetric[2] * widthAdvanceScale; 18779 width = vmetric ? -vmetric[0] : width; 18780 scaledX = vx / fontSizeScale; 18781 scaledY = (x + vy) / fontSizeScale; 18782 } else { 18783 scaledX = x / fontSizeScale; 18784 scaledY = 0; 18785 } 18786 let measure; 18787 if (font.remeasure && width > 0) { 18788 measure = ctx.measureText(character); 18789 const measuredWidth = measure.width * 1000 / fontSize * fontSizeScale; 18790 if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 18791 const characterScaleX = width / measuredWidth; 18792 restoreNeeded = true; 18793 ctx.save(); 18794 ctx.scale(characterScaleX, 1); 18795 scaledX /= characterScaleX; 18796 } else if (width !== measuredWidth) { 18797 scaledX += (width - measuredWidth) / 2000 * fontSize / fontSizeScale; 18798 } 18799 } 18800 if (this.contentVisible && (glyph.isInFont || font.missingFile)) { 18801 if (simpleFillText && !accent) { 18802 ctx.fillText(character, scaledX, scaledY); 18803 this.dependencyTracker?.recordCharacterBBox(opIdx, ctx, measure ? { 18804 bbox: null 18805 } : font, fontSize / fontSizeScale, scaledX, scaledY, () => measure ?? ctx.measureText(character)); 18806 } else { 18807 this.paintChar(opIdx, character, scaledX, scaledY, patternFillTransform, patternStrokeTransform); 18808 if (accent) { 18809 const scaledAccentX = scaledX + fontSize * accent.offset.x / fontSizeScale; 18810 const scaledAccentY = scaledY - fontSize * accent.offset.y / fontSizeScale; 18811 this.paintChar(opIdx, accent.fontChar, scaledAccentX, scaledAccentY, patternFillTransform, patternStrokeTransform); 18812 } 18813 } 18814 } 18815 const charWidth = vertical ? width * widthAdvanceScale - spacing * fontDirection : width * widthAdvanceScale + spacing * fontDirection; 18816 x += charWidth; 18817 if (restoreNeeded) { 18818 ctx.restore(); 18819 } 18820 } 18821 if (vertical) { 18822 current.y -= x; 18823 } else { 18824 current.x += x * textHScale; 18825 } 18826 ctx.restore(); 18827 this.compose(); 18828 this.dependencyTracker?.recordShowTextOperation(opIdx); 18829 this.#endKnockoutElement(started); 18830 } 18831 showType3Text(opIdx, glyphs) { 18832 const ctx = this.ctx; 18833 const current = this.current; 18834 const font = current.font; 18835 const fontSize = current.fontSize; 18836 const fontDirection = current.fontDirection; 18837 const spacingDir = font.vertical ? 1 : -1; 18838 const charSpacing = current.charSpacing; 18839 const wordSpacing = current.wordSpacing; 18840 const textHScale = current.textHScale * fontDirection; 18841 const fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX; 18842 const glyphsLength = glyphs.length; 18843 const isTextInvisible = current.textRenderingMode === TextRenderingMode.INVISIBLE; 18844 let i, glyph, width, spacingLength; 18845 if (isTextInvisible || fontSize === 0) { 18846 return; 18847 } 18848 this._cachedScaleForStroking[0] = -1; 18849 this._cachedGetSinglePixelWidth = null; 18850 ctx.save(); 18851 if (current.textMatrix) { 18852 ctx.transform(...current.textMatrix); 18853 } 18854 ctx.translate(current.x, current.y + current.textRise); 18855 ctx.scale(textHScale, fontDirection); 18856 const dependencyTracker = this.dependencyTracker; 18857 this.dependencyTracker = dependencyTracker ? new CanvasNestedDependencyTracker(dependencyTracker, opIdx) : null; 18858 for (i = 0; i < glyphsLength; ++i) { 18859 glyph = glyphs[i]; 18860 if (typeof glyph === "number") { 18861 spacingLength = spacingDir * glyph * fontSize / 1000; 18862 this.ctx.translate(spacingLength, 0); 18863 current.x += spacingLength * textHScale; 18864 continue; 18865 } 18866 const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 18867 const operatorList = font.charProcOperatorList.get(glyph.operatorListId); 18868 if (!operatorList) { 18869 warn(`Type3 character "${glyph.operatorListId}" is not available.`); 18870 } else if (this.contentVisible) { 18871 this.save(); 18872 if (operatorList.fnArray[0] === OPS.setCharWidth) { 18873 current.fillAlpha = current.strokeAlpha = 1; 18874 ctx.globalAlpha = 1; 18875 } 18876 ctx.scale(fontSize, fontSize); 18877 ctx.transform(...fontMatrix); 18878 this.executeOperatorList(operatorList); 18879 this.restore(); 18880 } 18881 const p = [glyph.width, 0]; 18882 Util.applyTransform(p, fontMatrix); 18883 width = p[0] * fontSize + spacing; 18884 ctx.translate(width, 0); 18885 current.x += width * textHScale; 18886 } 18887 ctx.restore(); 18888 if (dependencyTracker) { 18889 this.dependencyTracker = dependencyTracker; 18890 } 18891 } 18892 setCharWidth(opIdx, xWidth, yWidth) {} 18893 setCharWidthAndBounds(opIdx, xWidth, yWidth, llx, lly, urx, ury) { 18894 const clip = new Path2D(); 18895 clip.rect(llx, lly, urx - llx, ury - lly); 18896 this.ctx.clip(clip); 18897 this.dependencyTracker?.recordBBox(opIdx, this.ctx, llx, urx, lly, ury).recordClipBox(opIdx, this.ctx, llx, urx, lly, ury); 18898 this.endPath(opIdx); 18899 } 18900 getColorN_Pattern(opIdx, IR) { 18901 let pattern; 18902 if (IR[0] === "TilingPattern") { 18903 const baseTransform = this.baseTransform || getCurrentTransform(this.ctx); 18904 const canvasGraphicsFactory = { 18905 createCanvasGraphics: (ctx, renderingOpIdx) => new CanvasGraphics(ctx, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 18906 optionalContentConfig: this.optionalContentConfig, 18907 markedContentStack: this.markedContentStack 18908 }, undefined, undefined, this.dependencyTracker ? new CanvasNestedDependencyTracker(this.dependencyTracker, renderingOpIdx, true) : null) 18909 }; 18910 pattern = new TilingPattern(IR, this.ctx, canvasGraphicsFactory, baseTransform); 18911 } else { 18912 pattern = this._getPattern(opIdx, IR[1], IR[2]); 18913 } 18914 return pattern; 18915 } 18916 setStrokeColorN(opIdx, ...args) { 18917 this.dependencyTracker?.recordSimpleData("strokeColor", opIdx); 18918 this.current.strokeColor = this.getColorN_Pattern(opIdx, args); 18919 this.current.patternStroke = true; 18920 } 18921 setFillColorN(opIdx, ...args) { 18922 this.dependencyTracker?.recordSimpleData("fillColor", opIdx); 18923 const pattern = this.current.fillColor = this.getColorN_Pattern(opIdx, args); 18924 this.current.patternFill = true; 18925 this.current.tilingPatternDims = pattern instanceof TilingPattern ? [0, 0, 0, 0] : null; 18926 } 18927 setStrokeRGBColor(opIdx, color) { 18928 this.dependencyTracker?.recordSimpleData("strokeColor", opIdx); 18929 this.ctx.strokeStyle = this.current.strokeColor = color; 18930 this.current.patternStroke = false; 18931 } 18932 setStrokeTransparent(opIdx) { 18933 this.dependencyTracker?.recordSimpleData("strokeColor", opIdx); 18934 this.ctx.strokeStyle = this.current.strokeColor = "transparent"; 18935 this.current.patternStroke = false; 18936 } 18937 setFillRGBColor(opIdx, color) { 18938 this.dependencyTracker?.recordSimpleData("fillColor", opIdx); 18939 this.ctx.fillStyle = this.current.fillColor = color; 18940 this.current.patternFill = false; 18941 this.current.tilingPatternDims = null; 18942 } 18943 setFillTransparent(opIdx) { 18944 this.dependencyTracker?.recordSimpleData("fillColor", opIdx); 18945 this.ctx.fillStyle = this.current.fillColor = "transparent"; 18946 this.current.patternFill = false; 18947 this.current.tilingPatternDims = null; 18948 } 18949 _getPattern(opIdx, objId, matrix = null) { 18950 const pattern = this.cachedPatterns.getOrInsertComputed(objId, () => getShadingPattern(this.getObject(opIdx, objId))); 18951 if (matrix) { 18952 pattern.matrix = matrix; 18953 } 18954 return pattern; 18955 } 18956 shadingFill(opIdx, objId) { 18957 if (!this.contentVisible) { 18958 return; 18959 } 18960 const started = this.#beginKnockoutElement(this.current.fillAlpha); 18961 const ctx = this.ctx; 18962 this.save(opIdx); 18963 const pattern = this._getPattern(opIdx, objId); 18964 ctx.fillStyle = pattern.getPattern(ctx, this, getCurrentTransformInverse(ctx), PathType.SHADING, opIdx); 18965 const inv = getCurrentTransformInverse(ctx); 18966 if (inv) { 18967 const { 18968 width, 18969 height 18970 } = ctx.canvas; 18971 const minMax = F32_BBOX_INIT.slice(); 18972 Util.axialAlignedBoundingBox([0, 0, width, height], inv, minMax); 18973 const [x0, y0, x1, y1] = minMax; 18974 this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 18975 } else { 18976 this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 18977 } 18978 this.dependencyTracker?.resetBBox(opIdx).recordFullPageBBox(opIdx).recordDependencies(opIdx, Dependencies.transform).recordDependencies(opIdx, Dependencies.fill).recordOperation(opIdx); 18979 this.compose(this.current.getClippedPathBoundingBox()); 18980 this.restore(opIdx); 18981 this.#endKnockoutElement(started); 18982 } 18983 beginInlineImage() { 18984 unreachable("Should not call beginInlineImage"); 18985 } 18986 beginImageData() { 18987 unreachable("Should not call beginImageData"); 18988 } 18989 paintFormXObjectBegin(opIdx, matrix, bbox) { 18990 if (!this.contentVisible) { 18991 return; 18992 } 18993 this.save(opIdx); 18994 this.baseTransformStack.push(this.baseTransform); 18995 if (matrix) { 18996 this.transform(opIdx, ...matrix); 18997 } 18998 this.baseTransform = getCurrentTransform(this.ctx); 18999 if (bbox) { 19000 Util.axialAlignedBoundingBox(bbox, this.baseTransform, this.current.minMax); 19001 const [x0, y0, x1, y1] = bbox; 19002 const clip = new Path2D(); 19003 clip.rect(x0, y0, x1 - x0, y1 - y0); 19004 this.ctx.clip(clip); 19005 this.dependencyTracker?.recordClipBox(opIdx, this.ctx, x0, x1, y0, y1); 19006 this.endPath(opIdx); 19007 } 19008 } 19009 paintFormXObjectEnd(opIdx) { 19010 if (!this.contentVisible) { 19011 return; 19012 } 19013 this.restore(opIdx); 19014 this.baseTransform = this.baseTransformStack.pop(); 19015 } 19016 beginGroup(opIdx, group) { 19017 if (!this.contentVisible) { 19018 return; 19019 } 19020 this.save(opIdx); 19021 const { 19022 inSMaskMode 19023 } = this; 19024 if (inSMaskMode) { 19025 this.endSMaskMode(); 19026 this.current.activeSMask = null; 19027 } 19028 const currentCtx = this.ctx; 19029 if ((!group.needsIsolation || !group.isolated && !group.hasSoftMask) && !group.knockout && !group.isGray && this.#knockoutGroupLevel === 0 && currentCtx.globalAlpha === 1 && currentCtx.globalCompositeOperation === "source-over" && !inSMaskMode) { 19030 if (group.bbox) { 19031 let clip = new Path2D(); 19032 const [x0, y0, x1, y1] = group.bbox; 19033 clip.rect(x0, y0, x1 - x0, y1 - y0); 19034 if (group.matrix) { 19035 const path = new Path2D(); 19036 path.addPath(clip, new DOMMatrix(group.matrix)); 19037 clip = path; 19038 } 19039 currentCtx.clip(clip); 19040 } 19041 this.groupStack.push(null); 19042 this.#groupStackMeta.push(null); 19043 this.groupLevel++; 19044 return; 19045 } 19046 if (!group.isolated && !group.knockout && this.#knockoutGroupLevel === 0) { 19047 info("TODO: Fully support non-isolated non-knockout groups."); 19048 } 19049 const currentTransform = getCurrentTransform(currentCtx); 19050 if (group.matrix) { 19051 currentCtx.transform(...group.matrix); 19052 } 19053 const canvasBounds = [0, 0, currentCtx.canvas.width, currentCtx.canvas.height]; 19054 let bounds; 19055 if (group.bbox) { 19056 bounds = F32_BBOX_INIT.slice(); 19057 Util.axialAlignedBoundingBox(group.bbox, getCurrentTransform(currentCtx), bounds); 19058 bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 19059 } else { 19060 bounds = canvasBounds; 19061 } 19062 const offsetX = Math.floor(bounds[0]); 19063 const offsetY = Math.floor(bounds[1]); 19064 const drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 19065 const drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 19066 this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]); 19067 const scratchCanvas = this.canvasFactory.create(drawnWidth, drawnHeight); 19068 if (group.smask) { 19069 this.smaskGroupCanvases.push(scratchCanvas); 19070 } 19071 const groupCtx = scratchCanvas.context; 19072 const backdropCtx = group.knockout && !group.isolated ? currentCtx : null; 19073 const hasInnerBackdrop = !group.isolated && !group.knockout && !group.smask && group.needsIsolation && this.#knockoutGroupLevel > 0; 19074 const knockoutMaskEntry = group.knockout ? this.canvasFactory.create(drawnWidth, drawnHeight) : null; 19075 const savedKnockoutLevel = this.#knockoutGroupLevel; 19076 if (group.knockout) { 19077 this.#knockoutGroupLevel++; 19078 } else { 19079 this.#knockoutGroupLevel = 0; 19080 } 19081 groupCtx.translate(-offsetX, -offsetY); 19082 groupCtx.transform(...currentTransform); 19083 const needsBackdropCopy = !group.isolated && !group.smask && group.needsIsolation; 19084 const replaceBackdrop = needsBackdropCopy && !inSMaskMode && savedKnockoutLevel === 0 && !group.knockout && !group.isGray && group.hasSoftMask && currentCtx.globalAlpha === 1 && currentCtx.globalCompositeOperation === "source-over" && this.current.transferMaps === "none"; 19085 if (needsBackdropCopy && (inSMaskMode || replaceBackdrop)) { 19086 groupCtx.save(); 19087 groupCtx.setTransform(1, 0, 0, 1, 0, 0); 19088 groupCtx.drawImage(currentCtx.canvas, -offsetX, -offsetY); 19089 groupCtx.restore(); 19090 } 19091 if (group.bbox) { 19092 let clip = new Path2D(); 19093 const [x0, y0, x1, y1] = group.bbox; 19094 clip.rect(x0, y0, x1 - x0, y1 - y0); 19095 if (group.matrix) { 19096 const path = new Path2D(); 19097 path.addPath(clip, new DOMMatrix(group.matrix)); 19098 clip = path; 19099 } 19100 groupCtx.clip(clip); 19101 } 19102 if (group.smask) { 19103 this.smaskStack.push({ 19104 canvas: scratchCanvas.canvas, 19105 context: groupCtx, 19106 offsetX, 19107 offsetY, 19108 subtype: group.smask.subtype, 19109 backdrop: group.smask.backdrop, 19110 transferMap: group.smask.transferMap || null 19111 }); 19112 } 19113 if (!group.smask || this.dependencyTracker) { 19114 currentCtx.setTransform(1, 0, 0, 1, 0, 0); 19115 currentCtx.translate(offsetX, offsetY); 19116 currentCtx.save(); 19117 } 19118 copyCtxState(currentCtx, groupCtx); 19119 this.ctx = groupCtx; 19120 this.dependencyTracker?.inheritSimpleDataAsFutureForcedDependencies(["fillAlpha", "strokeAlpha", "globalCompositeOperation"]).pushBaseTransform(currentCtx); 19121 this.setGState(opIdx, [["BM", "source-over"], ["ca", 1], ["CA", 1], ["TR", null]]); 19122 this.groupStack.push(currentCtx); 19123 this.#groupStackMeta.push({ 19124 backdropCtx, 19125 savedKnockoutLevel, 19126 offsetX, 19127 offsetY, 19128 hasInnerBackdrop, 19129 replaceBackdrop, 19130 knockoutMaskEntry, 19131 knockoutTempEntry: null, 19132 knockoutBackdropEntry: null 19133 }); 19134 this.groupLevel++; 19135 } 19136 endGroup(opIdx, group) { 19137 if (!this.contentVisible) { 19138 return; 19139 } 19140 this.groupLevel--; 19141 const groupCtx = this.ctx; 19142 const ctx = this.groupStack.pop(); 19143 const groupMeta = this.#groupStackMeta.pop(); 19144 if (groupMeta) { 19145 this.#knockoutGroupLevel = groupMeta.savedKnockoutLevel; 19146 } 19147 if (ctx === null) { 19148 this.restore(opIdx); 19149 return; 19150 } 19151 if (group.isGray) { 19152 this.#convertGroupToGray(groupCtx); 19153 } 19154 this.ctx = ctx; 19155 this.ctx.imageSmoothingEnabled = false; 19156 this.dependencyTracker?.popBaseTransform(); 19157 if (group.smask) { 19158 this.tempSMask = this.smaskStack.pop(); 19159 this.restore(opIdx); 19160 if (this.dependencyTracker) { 19161 this.ctx.restore(); 19162 if (this.inSMaskMode) { 19163 this.ctx.setTransform(this.suspendedCtx.getTransform()); 19164 } 19165 } 19166 this.#destroyKnockoutPools(groupMeta); 19167 } else { 19168 this.ctx.restore(); 19169 const currentMtx = getCurrentTransform(this.ctx); 19170 this.restore(opIdx); 19171 this.ctx.save(); 19172 this.ctx.setTransform(...currentMtx); 19173 const dirtyBox = F32_BBOX_INIT.slice(); 19174 Util.axialAlignedBoundingBox([0, 0, groupCtx.canvas.width, groupCtx.canvas.height], currentMtx, dirtyBox); 19175 const parentGroupMeta = this.#groupStackMeta.at(-1); 19176 if (this.#knockoutGroupLevel > 0) { 19177 if (groupMeta.hasInnerBackdrop) { 19178 const { 19179 width, 19180 height 19181 } = groupCtx.canvas; 19182 const colorEntry = this.canvasFactory.create(width, height); 19183 const colorCtx = colorEntry.context; 19184 colorCtx.drawImage(ctx.canvas, groupMeta.offsetX, groupMeta.offsetY, width, height, 0, 0, width, height); 19185 colorCtx.globalCompositeOperation = "source-over"; 19186 colorCtx.drawImage(groupCtx.canvas, 0, 0); 19187 const shapeMaskEntry = this.#createKnockoutMaskCanvas(groupCtx.canvas); 19188 colorCtx.globalCompositeOperation = "destination-in"; 19189 colorCtx.drawImage(shapeMaskEntry.canvas, 0, 0); 19190 const sourceCompositeOperation = this.ctx.globalCompositeOperation; 19191 const sourceAlpha = this.ctx.globalAlpha; 19192 const sourceFilter = this.ctx.filter; 19193 this.ctx.save(); 19194 this.ctx.setTransform(...currentMtx); 19195 this.ctx.globalAlpha = 1; 19196 if (FeatureTest.isCanvasFilterSupported) { 19197 this.ctx.filter = "none"; 19198 } 19199 this.ctx.globalCompositeOperation = "destination-out"; 19200 this.ctx.drawImage(shapeMaskEntry.canvas, 0, 0); 19201 this.ctx.globalCompositeOperation = sourceCompositeOperation; 19202 this.ctx.globalAlpha = sourceAlpha; 19203 if (FeatureTest.isCanvasFilterSupported) { 19204 this.ctx.filter = sourceFilter ?? "none"; 19205 } 19206 this.ctx.drawImage(colorEntry.canvas, 0, 0); 19207 this.ctx.restore(); 19208 this.canvasFactory.destroy(shapeMaskEntry); 19209 this.canvasFactory.destroy(colorEntry); 19210 } else { 19211 const backdropCtx = parentGroupMeta?.backdropCtx ?? null; 19212 this.#compositeKnockoutSurface(this.ctx, groupCtx.canvas, { 19213 backdropCanvas: backdropCtx?.canvas ?? null, 19214 destTransform: currentMtx, 19215 backdropOffset: backdropCtx ? [parentGroupMeta.offsetX + groupMeta.offsetX, parentGroupMeta.offsetY + groupMeta.offsetY] : [0, 0], 19216 sourceAlpha: this.ctx.globalAlpha, 19217 sourceFilter: this.ctx.filter 19218 }); 19219 } 19220 } else { 19221 if (groupMeta.replaceBackdrop) { 19222 const clip = new Path2D(); 19223 clip.rect(0, 0, groupCtx.canvas.width, groupCtx.canvas.height); 19224 this.ctx.clip(clip); 19225 this.ctx.globalCompositeOperation = "copy"; 19226 } 19227 this.ctx.drawImage(groupCtx.canvas, 0, 0); 19228 } 19229 this.ctx.restore(); 19230 this.canvasFactory.destroy({ 19231 canvas: groupCtx.canvas, 19232 context: groupCtx 19233 }); 19234 this.#destroyKnockoutPools(groupMeta); 19235 this.compose(dirtyBox); 19236 } 19237 } 19238 #convertGroupToGray(groupCtx) { 19239 const { 19240 canvas 19241 } = groupCtx; 19242 const { 19243 width, 19244 height 19245 } = canvas; 19246 if (FeatureTest.isCanvasFilterSupported) { 19247 groupCtx.save(); 19248 groupCtx.setTransform(1, 0, 0, 1, 0, 0); 19249 groupCtx.filter = "grayscale(1)"; 19250 groupCtx.globalAlpha = 1; 19251 groupCtx.globalCompositeOperation = "copy"; 19252 groupCtx.drawImage(canvas, 0, 0); 19253 groupCtx.restore(); 19254 return; 19255 } 19256 const imageData = groupCtx.getImageData(0, 0, width, height); 19257 const { 19258 data 19259 } = imageData; 19260 for (let i = 0, ii = data.length; i < ii; i += 4) { 19261 const gray = data[i] * 0.2126 + data[i + 1] * 0.7152 + data[i + 2] * 0.0722 + 0.5 | 0; 19262 data[i] = data[i + 1] = data[i + 2] = gray; 19263 } 19264 groupCtx.putImageData(imageData, 0, 0); 19265 } 19266 #destroyKnockoutPools(groupMeta) { 19267 if (!groupMeta) { 19268 return; 19269 } 19270 if (groupMeta.knockoutMaskEntry) { 19271 this.canvasFactory.destroy(groupMeta.knockoutMaskEntry); 19272 groupMeta.knockoutMaskEntry = null; 19273 } 19274 if (groupMeta.knockoutTempEntry) { 19275 this.canvasFactory.destroy(groupMeta.knockoutTempEntry); 19276 groupMeta.knockoutTempEntry = null; 19277 } 19278 if (groupMeta.knockoutBackdropEntry) { 19279 this.canvasFactory.destroy(groupMeta.knockoutBackdropEntry); 19280 groupMeta.knockoutBackdropEntry = null; 19281 } 19282 } 19283 beginAnnotation(opIdx, id, rect, transform, matrix, hasOwnCanvas, canvasName) { 19284 this.#restoreInitialState(); 19285 resetCtxToDefault(this.ctx); 19286 this.ctx.save(); 19287 this.save(opIdx); 19288 if (this.baseTransform) { 19289 this.ctx.setTransform(...this.baseTransform); 19290 } 19291 if (rect) { 19292 const width = rect[2] - rect[0]; 19293 const height = rect[3] - rect[1]; 19294 if (hasOwnCanvas && this.annotationCanvasMap) { 19295 transform = transform.slice(); 19296 transform[4] -= rect[0]; 19297 transform[5] -= rect[1]; 19298 Util.singularValueDecompose2dScale(getCurrentTransform(this.ctx), XY); 19299 const { 19300 viewportScale 19301 } = this; 19302 const canvasWidth = Math.ceil(width * this.outputScaleX * viewportScale); 19303 const canvasHeight = Math.ceil(height * this.outputScaleY * viewportScale); 19304 this.annotationCanvas = this.canvasFactory.create(canvasWidth, canvasHeight); 19305 const { 19306 canvas, 19307 context 19308 } = this.annotationCanvas; 19309 if (canvasName) { 19310 const canvases = this.annotationCanvasMap.getOrInsertComputed(id, makeArr); 19311 canvas.setAttribute("data-canvas-name", canvasName); 19312 const index = canvases.findIndex(c => c.getAttribute("data-canvas-name") === canvasName); 19313 if (index === -1) { 19314 canvases.push(canvas); 19315 } else { 19316 canvases[index] = canvas; 19317 } 19318 } else { 19319 this.annotationCanvasMap.set(id, canvas); 19320 } 19321 this.annotationCanvas.savedCtx = this.ctx; 19322 this.ctx = context; 19323 this.ctx.save(); 19324 this.ctx.setTransform(XY[0], 0, 0, -XY[1], 0, height * XY[1]); 19325 resetCtxToDefault(this.ctx); 19326 } else { 19327 resetCtxToDefault(this.ctx); 19328 this.endPath(opIdx); 19329 const clip = new Path2D(); 19330 clip.rect(rect[0], rect[1], width, height); 19331 this.ctx.clip(clip); 19332 } 19333 } 19334 this.current = new CanvasExtraState(this.ctx.canvas.width, this.ctx.canvas.height); 19335 this.baseTransformStack.push(this.baseTransform); 19336 this.transform(opIdx, ...transform); 19337 this.transform(opIdx, ...matrix); 19338 this.baseTransform = getCurrentTransform(this.ctx); 19339 } 19340 endAnnotation(opIdx) { 19341 if (this.annotationCanvas) { 19342 this.ctx.restore(); 19343 this.#drawFilter(); 19344 this.ctx = this.annotationCanvas.savedCtx; 19345 delete this.annotationCanvas.savedCtx; 19346 delete this.annotationCanvas; 19347 } 19348 this.baseTransform = this.baseTransformStack.pop(); 19349 } 19350 paintImageMaskXObject(opIdx, img) { 19351 if (!this.contentVisible) { 19352 return; 19353 } 19354 const count = img.count; 19355 img = this.getObject(opIdx, img.data, img); 19356 img.count = count; 19357 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19358 const ctx = this.ctx; 19359 const mask = this._createMaskCanvas(opIdx, img); 19360 const maskCanvas = mask.canvas; 19361 ctx.save(); 19362 ctx.setTransform(1, 0, 0, 1, 0, 0); 19363 ctx.drawImage(maskCanvas, mask.offsetX, mask.offsetY); 19364 this.dependencyTracker?.resetBBox(opIdx).recordBBox(opIdx, this.ctx, mask.offsetX, mask.offsetX + maskCanvas.width, mask.offsetY, mask.offsetY + maskCanvas.height).recordOperation(opIdx); 19365 ctx.restore(); 19366 if (mask.canvasEntry) { 19367 this.canvasFactory.destroy(mask.canvasEntry); 19368 } 19369 this.compose(); 19370 this.#endKnockoutElement(started); 19371 } 19372 paintImageMaskXObjectRepeat(opIdx, img, scaleX, skewX = 0, skewY = 0, scaleY, positions) { 19373 if (!this.contentVisible) { 19374 return; 19375 } 19376 img = this.getObject(opIdx, img.data, img); 19377 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19378 const ctx = this.ctx; 19379 ctx.save(); 19380 const currentTransform = getCurrentTransform(ctx); 19381 ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0); 19382 const mask = this._createMaskCanvas(opIdx, img); 19383 ctx.setTransform(1, 0, 0, 1, mask.offsetX - currentTransform[4], mask.offsetY - currentTransform[5]); 19384 this.dependencyTracker?.resetBBox(opIdx); 19385 for (let i = 0, ii = positions.length; i < ii; i += 2) { 19386 const trans = Util.transform(currentTransform, [scaleX, skewX, skewY, scaleY, positions[i], positions[i + 1]]); 19387 ctx.drawImage(mask.canvas, trans[4], trans[5]); 19388 this.dependencyTracker?.recordBBox(opIdx, this.ctx, trans[4], trans[4] + mask.canvas.width, trans[5], trans[5] + mask.canvas.height); 19389 } 19390 ctx.restore(); 19391 if (mask.canvasEntry) { 19392 this.canvasFactory.destroy(mask.canvasEntry); 19393 } 19394 this.compose(); 19395 this.dependencyTracker?.recordOperation(opIdx); 19396 this.#endKnockoutElement(started); 19397 } 19398 paintImageMaskXObjectGroup(opIdx, images) { 19399 if (!this.contentVisible) { 19400 return; 19401 } 19402 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19403 const ctx = this.ctx; 19404 const fillColor = this.current.fillColor; 19405 const isPatternFill = this.current.patternFill; 19406 this.dependencyTracker?.resetBBox(opIdx).recordDependencies(opIdx, Dependencies.transformAndFill); 19407 for (const image of images) { 19408 const { 19409 data, 19410 width, 19411 height, 19412 transform 19413 } = image; 19414 const maskCanvas = this.canvasFactory.create(width, height); 19415 const maskCtx = maskCanvas.context; 19416 maskCtx.save(); 19417 const img = this.getObject(opIdx, data, image); 19418 putBinaryImageMask(maskCtx, img); 19419 maskCtx.globalCompositeOperation = "source-in"; 19420 maskCtx.fillStyle = isPatternFill ? fillColor.getPattern(maskCtx, this, getCurrentTransformInverse(ctx), PathType.FILL, opIdx) : fillColor; 19421 maskCtx.fillRect(0, 0, width, height); 19422 maskCtx.restore(); 19423 ctx.save(); 19424 ctx.transform(...transform); 19425 ctx.scale(1, -1); 19426 drawImageAtIntegerCoords(ctx, maskCanvas.canvas, 0, 0, width, height, 0, -1, 1, 1); 19427 this.canvasFactory.destroy(maskCanvas); 19428 this.dependencyTracker?.recordBBox(opIdx, ctx, 0, width, 0, height); 19429 ctx.restore(); 19430 } 19431 this.compose(); 19432 this.dependencyTracker?.recordOperation(opIdx); 19433 this.#endKnockoutElement(started); 19434 } 19435 paintImageXObject(opIdx, objId) { 19436 if (!this.contentVisible) { 19437 return; 19438 } 19439 const imgData = this.getObject(opIdx, objId); 19440 if (!imgData) { 19441 warn("Dependent image isn't ready yet"); 19442 return; 19443 } 19444 this.paintInlineImageXObject(opIdx, imgData); 19445 } 19446 paintImageXObjectRepeat(opIdx, objId, scaleX, scaleY, positions) { 19447 if (!this.contentVisible) { 19448 return; 19449 } 19450 const imgData = this.getObject(opIdx, objId); 19451 if (!imgData) { 19452 warn("Dependent image isn't ready yet"); 19453 return; 19454 } 19455 const width = imgData.width; 19456 const height = imgData.height; 19457 const map = []; 19458 for (let i = 0, ii = positions.length; i < ii; i += 2) { 19459 map.push({ 19460 transform: [scaleX, 0, 0, scaleY, positions[i], positions[i + 1]], 19461 x: 0, 19462 y: 0, 19463 w: width, 19464 h: height 19465 }); 19466 } 19467 this.paintInlineImageXObjectGroup(opIdx, imgData, map); 19468 } 19469 applyTransferMapsToCanvas(ctx) { 19470 if (this.current.transferMaps !== "none") { 19471 ctx.filter = this.current.transferMaps; 19472 ctx.drawImage(ctx.canvas, 0, 0); 19473 ctx.filter = "none"; 19474 } 19475 return ctx.canvas; 19476 } 19477 applyTransferMapsToBitmap(imgData) { 19478 if (this.current.transferMaps === "none") { 19479 return { 19480 img: imgData.bitmap, 19481 canvasEntry: null 19482 }; 19483 } 19484 const { 19485 bitmap, 19486 width, 19487 height 19488 } = imgData; 19489 const tmpCanvas = this.canvasFactory.create(width, height); 19490 const tmpCtx = tmpCanvas.context; 19491 tmpCtx.filter = this.current.transferMaps; 19492 tmpCtx.drawImage(bitmap, 0, 0); 19493 tmpCtx.filter = "none"; 19494 return { 19495 img: tmpCanvas.canvas, 19496 canvasEntry: tmpCanvas 19497 }; 19498 } 19499 paintInlineImageXObject(opIdx, imgData) { 19500 if (!this.contentVisible) { 19501 return; 19502 } 19503 const width = imgData.width; 19504 const height = imgData.height; 19505 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19506 const ctx = this.ctx; 19507 this.save(opIdx); 19508 const { 19509 filter 19510 } = ctx; 19511 if (filter !== "none" && filter !== "") { 19512 ctx.filter = "none"; 19513 } 19514 ctx.scale(1 / width, -1 / height); 19515 let imgToPaint; 19516 let inlineImgCanvas = null; 19517 if (imgData.bitmap) { 19518 const result = this.applyTransferMapsToBitmap(imgData); 19519 imgToPaint = result.img; 19520 inlineImgCanvas = result.canvasEntry; 19521 } else { 19522 const tmpCanvas = this.canvasFactory.create(width, height); 19523 putBinaryImageData(tmpCanvas.context, imgData); 19524 imgToPaint = this.applyTransferMapsToCanvas(tmpCanvas.context); 19525 inlineImgCanvas = tmpCanvas; 19526 } 19527 const scaled = this._scaleImage(imgToPaint, getCurrentTransformInverse(ctx)); 19528 ctx.imageSmoothingEnabled = getImageSmoothingEnabled(getCurrentTransform(ctx), imgData.interpolate); 19529 if (this.dependencyTracker) { 19530 this.dependencyTracker.resetBBox(opIdx).recordBBox(opIdx, ctx, 0, width, -height, 0).recordDependencies(opIdx, Dependencies.imageXObject).recordOperation(opIdx); 19531 this.imagesTracker?.record(ctx, width, height, this.dependencyTracker.clipBox); 19532 } 19533 drawImageAtIntegerCoords(ctx, scaled.img, 0, 0, scaled.paintWidth, scaled.paintHeight, 0, -height, width, height); 19534 if (scaled.tmpCanvas) { 19535 this.canvasFactory.destroy(scaled.tmpCanvas); 19536 } 19537 if (inlineImgCanvas) { 19538 this.canvasFactory.destroy(inlineImgCanvas); 19539 } 19540 this.compose(); 19541 this.restore(opIdx); 19542 this.#endKnockoutElement(started); 19543 } 19544 paintInlineImageXObjectGroup(opIdx, imgData, map) { 19545 if (!this.contentVisible) { 19546 return; 19547 } 19548 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19549 const ctx = this.ctx; 19550 let imgToPaint; 19551 let inlineImgCanvas = null; 19552 if (imgData.bitmap) { 19553 imgToPaint = imgData.bitmap; 19554 } else { 19555 const w = imgData.width; 19556 const h = imgData.height; 19557 const tmpCanvas = this.canvasFactory.create(w, h); 19558 putBinaryImageData(tmpCanvas.context, imgData); 19559 imgToPaint = this.applyTransferMapsToCanvas(tmpCanvas.context); 19560 inlineImgCanvas = tmpCanvas; 19561 } 19562 this.dependencyTracker?.resetBBox(opIdx); 19563 for (const entry of map) { 19564 ctx.save(); 19565 ctx.transform(...entry.transform); 19566 ctx.scale(1, -1); 19567 drawImageAtIntegerCoords(ctx, imgToPaint, entry.x, entry.y, entry.w, entry.h, 0, -1, 1, 1); 19568 this.dependencyTracker?.recordBBox(opIdx, ctx, 0, 1, -1, 0); 19569 ctx.restore(); 19570 } 19571 if (inlineImgCanvas) { 19572 this.canvasFactory.destroy(inlineImgCanvas); 19573 } 19574 this.dependencyTracker?.recordOperation(opIdx); 19575 this.compose(); 19576 this.#endKnockoutElement(started); 19577 } 19578 paintSolidColorImageMask(opIdx) { 19579 if (!this.contentVisible) { 19580 return; 19581 } 19582 const started = this.#beginKnockoutElement(this.current.fillAlpha); 19583 this.dependencyTracker?.resetBBox(opIdx).recordBBox(opIdx, this.ctx, 0, 1, 0, 1).recordDependencies(opIdx, Dependencies.fill).recordOperation(opIdx); 19584 this.ctx.fillRect(0, 0, 1, 1); 19585 this.compose(); 19586 this.#endKnockoutElement(started); 19587 } 19588 markPoint(opIdx, tag) {} 19589 markPointProps(opIdx, tag, properties) {} 19590 beginMarkedContent(opIdx, tag) { 19591 this.dependencyTracker?.beginMarkedContent(opIdx); 19592 this.markedContentStack.push({ 19593 visible: true 19594 }); 19595 } 19596 beginMarkedContentProps(opIdx, tag, properties) { 19597 this.dependencyTracker?.beginMarkedContent(opIdx); 19598 if (tag === "OC") { 19599 this.markedContentStack.push({ 19600 visible: this.optionalContentConfig.isVisible(properties) 19601 }); 19602 } else { 19603 this.markedContentStack.push({ 19604 visible: true 19605 }); 19606 } 19607 this.contentVisible = this.isContentVisible(); 19608 } 19609 endMarkedContent(opIdx) { 19610 this.dependencyTracker?.endMarkedContent(opIdx); 19611 this.markedContentStack.pop(); 19612 this.contentVisible = this.isContentVisible(); 19613 } 19614 beginCompat(opIdx) {} 19615 endCompat(opIdx) {} 19616 consumePath(opIdx, path, clipBox) { 19617 const isEmpty = this.current.isEmptyClip(); 19618 if (this.pendingClip) { 19619 this.current.updateClipFromPath(); 19620 } 19621 if (!this.pendingClip) { 19622 this.compose(clipBox); 19623 } 19624 const ctx = this.ctx; 19625 if (this.pendingClip) { 19626 if (!isEmpty) { 19627 if (this.pendingClip === EO_CLIP) { 19628 ctx.clip(path, "evenodd"); 19629 } else { 19630 ctx.clip(path); 19631 } 19632 } 19633 this.pendingClip = null; 19634 this.dependencyTracker?.bboxToClipBoxDropOperation(opIdx).recordFutureForcedDependency("clipPath", opIdx); 19635 } else { 19636 this.dependencyTracker?.recordOperation(opIdx); 19637 } 19638 this.current.startNewPathAndClipBox(this.current.clipBox); 19639 } 19640 getSinglePixelWidth() { 19641 if (!this._cachedGetSinglePixelWidth) { 19642 const m = getCurrentTransform(this.ctx); 19643 if (m[1] === 0 && m[2] === 0) { 19644 this._cachedGetSinglePixelWidth = 1 / Math.min(Math.abs(m[0]), Math.abs(m[3])); 19645 } else { 19646 const absDet = Math.abs(m[0] * m[3] - m[2] * m[1]); 19647 const normX = Math.hypot(m[0], m[2]); 19648 const normY = Math.hypot(m[1], m[3]); 19649 this._cachedGetSinglePixelWidth = Math.max(normX, normY) / absDet; 19650 } 19651 } 19652 return this._cachedGetSinglePixelWidth; 19653 } 19654 getScaleForStroking() { 19655 if (this._cachedScaleForStroking[0] === -1) { 19656 const { 19657 lineWidth 19658 } = this.current; 19659 const { 19660 a, 19661 b, 19662 c, 19663 d 19664 } = this.ctx.getTransform(); 19665 let scaleX, scaleY; 19666 if (b === 0 && c === 0) { 19667 const normX = Math.abs(a); 19668 const normY = Math.abs(d); 19669 if (normX === normY) { 19670 if (lineWidth === 0) { 19671 scaleX = scaleY = 1 / normX; 19672 } else { 19673 const scaledLineWidth = normX * lineWidth; 19674 scaleX = scaleY = scaledLineWidth < 1 ? 1 / scaledLineWidth : 1; 19675 } 19676 } else if (lineWidth === 0) { 19677 scaleX = 1 / normX; 19678 scaleY = 1 / normY; 19679 } else { 19680 const scaledXLineWidth = normX * lineWidth; 19681 const scaledYLineWidth = normY * lineWidth; 19682 scaleX = scaledXLineWidth < 1 ? 1 / scaledXLineWidth : 1; 19683 scaleY = scaledYLineWidth < 1 ? 1 / scaledYLineWidth : 1; 19684 } 19685 } else { 19686 const absDet = Math.abs(a * d - b * c); 19687 const normX = Math.hypot(a, b); 19688 const normY = Math.hypot(c, d); 19689 if (lineWidth === 0) { 19690 scaleX = normY / absDet; 19691 scaleY = normX / absDet; 19692 } else { 19693 const baseArea = lineWidth * absDet; 19694 scaleX = normY > baseArea ? normY / baseArea : 1; 19695 scaleY = normX > baseArea ? normX / baseArea : 1; 19696 } 19697 } 19698 this._cachedScaleForStroking[0] = scaleX; 19699 this._cachedScaleForStroking[1] = scaleY; 19700 } 19701 return this._cachedScaleForStroking; 19702 } 19703 rescaleAndStroke(path, saveRestore) { 19704 const { 19705 ctx, 19706 current: { 19707 lineWidth 19708 } 19709 } = this; 19710 const [scaleX, scaleY] = this.getScaleForStroking(); 19711 if (scaleX === scaleY) { 19712 ctx.lineWidth = (lineWidth || 1) * scaleX; 19713 ctx.stroke(path); 19714 return; 19715 } 19716 const SCALE_MATRIX = CanvasGraphics.#SCALE_MATRIX ??= new DOMMatrix(); 19717 const dashes = ctx.getLineDash(); 19718 if (saveRestore) { 19719 ctx.save(); 19720 } 19721 ctx.scale(scaleX, scaleY); 19722 SCALE_MATRIX.a = 1 / scaleX; 19723 SCALE_MATRIX.d = 1 / scaleY; 19724 const newPath = new Path2D(); 19725 newPath.addPath(path, SCALE_MATRIX); 19726 if (dashes.length > 0) { 19727 const scale = Math.max(scaleX, scaleY); 19728 ctx.setLineDash(dashes.map(x => x / scale)); 19729 ctx.lineDashOffset /= scale; 19730 } 19731 ctx.lineWidth = lineWidth || 1; 19732 ctx.stroke(newPath); 19733 if (saveRestore) { 19734 ctx.restore(); 19735 } 19736 } 19737 isContentVisible() { 19738 for (let i = this.markedContentStack.length - 1; i >= 0; i--) { 19739 if (!this.markedContentStack[i].visible) { 19740 return false; 19741 } 19742 } 19743 return true; 19744 } 19745} 19746for (const op in OPS) { 19747 if (CanvasGraphics.prototype[op] !== undefined) { 19748 CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; 19749 } 19750} 19751 19752;// ./src/shared/base_pdf_stream.js 19753
vendor: 17,711 bytes, lines 19754-20437
19754 19755 19756 19757 19758 19759 19760 19761class BasePDFStream { 19762 #PDFStreamReader = null; 19763 #PDFStreamRangeReader = null; 19764 _fullReader = null; 19765 _rangeReaders = new Set(); 19766 _source = null; 19767 constructor(source, PDFStreamReader, PDFStreamRangeReader) { 19768 this._source = source; 19769 this.#PDFStreamReader = PDFStreamReader; 19770 this.#PDFStreamRangeReader = PDFStreamRangeReader; 19771 } 19772 get _progressiveDataLength() { 19773 return this._fullReader?._loaded ?? 0; 19774 } 19775 getFullReader() { 19776 assert(!this._fullReader, "BasePDFStream.getFullReader can only be called once."); 19777 return this._fullReader = new this.#PDFStreamReader(this); 19778 } 19779 getRangeReader(begin, end) { 19780 if (end <= this._progressiveDataLength) { 19781 return null; 19782 } 19783 const reader = new this.#PDFStreamRangeReader(this, begin, end); 19784 this._rangeReaders.add(reader); 19785 return reader; 19786 } 19787 cancelAllRequests(reason) { 19788 this._fullReader?.cancel(reason); 19789 for (const reader of new Set(this._rangeReaders)) { 19790 reader.cancel(reason); 19791 } 19792 } 19793} 19794class BasePDFStreamReader { 19795 onProgress = null; 19796 _contentLength = 0; 19797 _filename = null; 19798 _headersCapability = Promise.withResolvers(); 19799 _isRangeSupported = false; 19800 _isStreamingSupported = false; 19801 _loaded = 0; 19802 _stream = null; 19803 constructor(stream) { 19804 this._stream = stream; 19805 } 19806 _callOnProgress() { 19807 this.onProgress?.({ 19808 loaded: this._loaded, 19809 total: this._contentLength 19810 }); 19811 } 19812 get headersReady() { 19813 return this._headersCapability.promise; 19814 } 19815 get filename() { 19816 return this._filename; 19817 } 19818 get contentLength() { 19819 return this._contentLength; 19820 } 19821 get isRangeSupported() { 19822 return this._isRangeSupported; 19823 } 19824 get isStreamingSupported() { 19825 return this._isStreamingSupported; 19826 } 19827 async read() { 19828 unreachable("Abstract method `read` called"); 19829 } 19830 cancel(reason) { 19831 unreachable("Abstract method `cancel` called"); 19832 } 19833} 19834class BasePDFStreamRangeReader { 19835 _stream = null; 19836 constructor(stream, begin, end) { 19837 this._stream = stream; 19838 } 19839 async read() { 19840 unreachable("Abstract method `read` called"); 19841 } 19842 cancel(reason) { 19843 unreachable("Abstract method `cancel` called"); 19844 } 19845} 19846 19847;// ./src/display/content_disposition.js 19848 19849 19850 19851function getFilenameFromContentDispositionHeader(contentDisposition) { 19852 let needsEncodingFixup = true; 19853 let tmp = toParamRegExp("filename\\*", "i").exec(contentDisposition); 19854 if (tmp) { 19855 tmp = tmp[1]; 19856 let filename = rfc2616unquote(tmp); 19857 filename = unescape(filename); 19858 filename = rfc5987decode(filename); 19859 filename = rfc2047decode(filename); 19860 return fixupEncoding(filename); 19861 } 19862 tmp = rfc2231getparam(contentDisposition); 19863 if (tmp) { 19864 const filename = rfc2047decode(tmp); 19865 return fixupEncoding(filename); 19866 } 19867 tmp = toParamRegExp("filename", "i").exec(contentDisposition); 19868 if (tmp) { 19869 tmp = tmp[1]; 19870 let filename = rfc2616unquote(tmp); 19871 filename = rfc2047decode(filename); 19872 return fixupEncoding(filename); 19873 } 19874 function toParamRegExp(attributePattern, flags) { 19875 return new RegExp("(?:^|;)\\s*" + attributePattern + "\\s*=\\s*" + "(" + '[^";\\s][^;\\s]*' + "|" + '"(?:[^"\\\\]|\\\\"?)+"?' + ")", flags); 19876 } 19877 function textdecode(encoding, value) { 19878 if (encoding) { 19879 if (!/^[\x00-\xFF]+$/.test(value)) { 19880 return value; 19881 } 19882 try { 19883 const decoder = new TextDecoder(encoding, { 19884 fatal: true 19885 }); 19886 const buffer = stringToBytes(value); 19887 value = decoder.decode(buffer); 19888 needsEncodingFixup = false; 19889 } catch {} 19890 } 19891 return value; 19892 } 19893 function fixupEncoding(value) { 19894 if (needsEncodingFixup && /[\x80-\xff]/.test(value)) { 19895 value = textdecode("utf-8", value); 19896 if (needsEncodingFixup) { 19897 value = textdecode("iso-8859-1", value); 19898 } 19899 } 19900 return value; 19901 } 19902 function rfc2231getparam(contentDispositionStr) { 19903 const matches = []; 19904 let match; 19905 const iter = toParamRegExp("filename\\*((?!0\\d)\\d+)(\\*?)", "ig"); 19906 while ((match = iter.exec(contentDispositionStr)) !== null) { 19907 let [, n, quot, part] = match; 19908 n = parseInt(n, 10); 19909 if (n in matches) { 19910 if (n === 0) { 19911 break; 19912 } 19913 continue; 19914 } 19915 matches[n] = [quot, part]; 19916 } 19917 const parts = []; 19918 for (let n = 0; n < matches.length; ++n) { 19919 if (!(n in matches)) { 19920 break; 19921 } 19922 let [quot, part] = matches[n]; 19923 part = rfc2616unquote(part); 19924 if (quot) { 19925 part = unescape(part); 19926 if (n === 0) { 19927 part = rfc5987decode(part); 19928 } 19929 } 19930 parts.push(part); 19931 } 19932 return parts.join(""); 19933 } 19934 function rfc2616unquote(value) { 19935 if (value.startsWith('"')) { 19936 const parts = value.slice(1).split('\\"'); 19937 for (let i = 0; i < parts.length; ++i) { 19938 const quotindex = parts[i].indexOf('"'); 19939 if (quotindex !== -1) { 19940 parts[i] = parts[i].slice(0, quotindex); 19941 parts.length = i + 1; 19942 } 19943 parts[i] = parts[i].replaceAll(/\\(.)/g, "$1"); 19944 } 19945 value = parts.join('"'); 19946 } 19947 return value; 19948 } 19949 function rfc5987decode(extvalue) { 19950 const encodingend = extvalue.indexOf("'"); 19951 if (encodingend === -1) { 19952 return extvalue; 19953 } 19954 const encoding = extvalue.slice(0, encodingend); 19955 const langvalue = extvalue.slice(encodingend + 1); 19956 const value = langvalue.replace(/^[^']*'/, ""); 19957 return textdecode(encoding, value); 19958 } 19959 function rfc2047decode(value) { 19960 if (!value.startsWith("=?") || /[\x00-\x19\x80-\xff]/.test(value)) { 19961 return value; 19962 } 19963 return value.replaceAll(/=\?([\w-]*)\?([QB])\?((?:[^?]|\?(?!=))*)\?=/gi, function (matches, charset, encoding, text) { 19964 if (encoding === "q" || encoding === "Q") { 19965 text = text.replaceAll("_", " "); 19966 text = text.replaceAll(/=([0-9a-f]{2})/gi, function (match, hex) { 19967 return String.fromCharCode(parseInt(hex, 16)); 19968 }); 19969 return textdecode(charset, text); 19970 } 19971 try { 19972 text = atob(text); 19973 } catch {} 19974 return textdecode(charset, text); 19975 }); 19976 } 19977 return ""; 19978} 19979 19980;// ./src/display/network_utils.js 19981 19982 19983 19984 19985 19986function createHeaders(isHttp, httpHeaders) { 19987 const headers = new Headers(); 19988 if (!isHttp || !httpHeaders || typeof httpHeaders !== "object") { 19989 return headers; 19990 } 19991 for (const key in httpHeaders) { 19992 const val = httpHeaders[key]; 19993 if (val !== undefined) { 19994 headers.append(key, val); 19995 } 19996 } 19997 return headers; 19998} 19999function trimHeadersEnd(str) { 20000 let end = str.length; 20001 while (end > 0 && str[end - 1] !== " " && /\s/.test(str[end - 1])) { 20002 end--; 20003 } 20004 return str.slice(0, end); 20005} 20006function getResponseOrigin(url) { 20007 return URL.parse(url)?.origin ?? null; 20008} 20009function validateRangeRequestCapabilities({ 20010 responseHeaders, 20011 isHttp, 20012 rangeChunkSize, 20013 disableRange 20014}) { 20015 const rv = { 20016 contentLength: 0, 20017 isRangeSupported: false 20018 }; 20019 const length = parseInt(responseHeaders.get("Content-Length"), 10); 20020 if (!Number.isInteger(length)) { 20021 return rv; 20022 } 20023 rv.contentLength = length; 20024 if (length <= 2 * rangeChunkSize) { 20025 return rv; 20026 } 20027 if (disableRange || !isHttp) { 20028 return rv; 20029 } 20030 if (responseHeaders.get("Accept-Ranges") !== "bytes") { 20031 return rv; 20032 } 20033 const contentEncoding = responseHeaders.get("Content-Encoding") || "identity"; 20034 if (contentEncoding === "identity") { 20035 rv.isRangeSupported = true; 20036 } 20037 return rv; 20038} 20039function extractFilenameFromHeader(responseHeaders) { 20040 const contentDisposition = responseHeaders.get("Content-Disposition"); 20041 if (contentDisposition) { 20042 let filename = getFilenameFromContentDispositionHeader(contentDisposition); 20043 if (filename.includes("%")) { 20044 try { 20045 filename = decodeURIComponent(filename); 20046 } catch {} 20047 } 20048 if (isPdfFile(filename)) { 20049 return filename; 20050 } 20051 } 20052 return null; 20053} 20054function createResponseError(status, url) { 20055 return new ResponseException(`Unexpected server response (${status}) while retrieving PDF "${url.href}".`, status, status === 404 || status === 0 && url.protocol === "file:"); 20056} 20057function ensureResponseOrigin(rangeOrigin, origin) { 20058 if (rangeOrigin !== origin) { 20059 throw new Error(`Expected range response-origin "${rangeOrigin}" to match "${origin}".`); 20060 } 20061} 20062 20063;// ./src/display/fetch_stream.js 20064 20065 20066 20067 20068 20069 20070 20071 20072function fetchUrl(url, headers, withCredentials, abortController) { 20073 return fetch(url, { 20074 method: "GET", 20075 headers, 20076 signal: abortController.signal, 20077 mode: "cors", 20078 credentials: withCredentials ? "include" : "same-origin", 20079 redirect: "follow" 20080 }); 20081} 20082function ensureResponseStatus(status, url) { 20083 if (status !== 200 && status !== 206) { 20084 throw createResponseError(status, url); 20085 } 20086} 20087function getArrayBuffer(val) { 20088 if (val instanceof Uint8Array) { 20089 return val.buffer; 20090 } 20091 if (val instanceof ArrayBuffer) { 20092 return val; 20093 } 20094 throw new Error(`getArrayBuffer - unexpected data: ${val}`); 20095} 20096class PDFFetchStream extends BasePDFStream { 20097 _responseOrigin = null; 20098 constructor(source) { 20099 super(source, PDFFetchStreamReader, PDFFetchStreamRangeReader); 20100 const { 20101 httpHeaders, 20102 url 20103 } = source; 20104 assert(/https?:/.test(url.protocol), "PDFFetchStream only supports http(s):// URLs."); 20105 this.headers = createHeaders(true, httpHeaders); 20106 } 20107} 20108class PDFFetchStreamReader extends BasePDFStreamReader { 20109 _abortController = new AbortController(); 20110 _reader = null; 20111 constructor(stream) { 20112 super(stream); 20113 const { 20114 disableRange, 20115 disableStream, 20116 rangeChunkSize, 20117 url, 20118 withCredentials 20119 } = stream._source; 20120 this._isStreamingSupported = !disableStream; 20121 const headers = new Headers(stream.headers); 20122 fetchUrl(url, headers, withCredentials, this._abortController).then(response => { 20123 stream._responseOrigin = getResponseOrigin(response.url); 20124 ensureResponseStatus(response.status, url); 20125 this._reader = response.body.getReader(); 20126 const responseHeaders = response.headers; 20127 const { 20128 contentLength, 20129 isRangeSupported 20130 } = validateRangeRequestCapabilities({ 20131 responseHeaders, 20132 isHttp: true, 20133 rangeChunkSize, 20134 disableRange 20135 }); 20136 this._contentLength = contentLength; 20137 this._isRangeSupported = isRangeSupported; 20138 this._filename = extractFilenameFromHeader(responseHeaders); 20139 if (!this._isStreamingSupported && this._isRangeSupported) { 20140 this.cancel(new AbortException("Streaming is disabled.")); 20141 } 20142 this._headersCapability.resolve(); 20143 }).catch(this._headersCapability.reject); 20144 } 20145 async read() { 20146 await this._headersCapability.promise; 20147 const { 20148 value, 20149 done 20150 } = await this._reader.read(); 20151 if (done) { 20152 return { 20153 value, 20154 done 20155 }; 20156 } 20157 this._loaded += value.byteLength; 20158 this._callOnProgress(); 20159 return { 20160 value: getArrayBuffer(value), 20161 done: false 20162 }; 20163 } 20164 cancel(reason) { 20165 this._reader?.cancel(reason); 20166 this._abortController.abort(); 20167 } 20168} 20169class PDFFetchStreamRangeReader extends BasePDFStreamRangeReader { 20170 _abortController = new AbortController(); 20171 _readCapability = Promise.withResolvers(); 20172 _reader = null; 20173 constructor(stream, begin, end) { 20174 super(stream, begin, end); 20175 const { 20176 url, 20177 withCredentials 20178 } = stream._source; 20179 const headers = new Headers(stream.headers); 20180 headers.append("Range", `bytes=${begin}-${end - 1}`); 20181 fetchUrl(url, headers, withCredentials, this._abortController).then(response => { 20182 const responseOrigin = getResponseOrigin(response.url); 20183 ensureResponseOrigin(responseOrigin, stream._responseOrigin); 20184 ensureResponseStatus(response.status, url); 20185 this._reader = response.body.getReader(); 20186 this._readCapability.resolve(); 20187 }).catch(this._readCapability.reject); 20188 } 20189 async read() { 20190 await this._readCapability.promise; 20191 const { 20192 value, 20193 done 20194 } = await this._reader.read(); 20195 if (done) { 20196 return { 20197 value, 20198 done 20199 }; 20200 } 20201 return { 20202 value: getArrayBuffer(value), 20203 done: false 20204 }; 20205 } 20206 cancel(reason) { 20207 this._reader?.cancel(reason); 20208 this._abortController.abort(); 20209 } 20210} 20211 20212;// ./src/display/transport_stream.js 20213 20214 20215 20216 20217 20218 20219 20220 20221 20222 20223 20224function transport_stream_getArrayBuffer(val) { 20225 return val instanceof Uint8Array && val.byteLength === val.buffer.byteLength ? val.buffer : new Uint8Array(val).buffer; 20226} 20227function endRequests() { 20228 for (const capability of this._requests) { 20229 capability.resolve({ 20230 value: undefined, 20231 done: true 20232 }); 20233 } 20234 this._requests.length = 0; 20235} 20236class PDFDataTransportStream extends BasePDFStream { 20237 _progressiveDone = false; 20238 _queuedChunks = []; 20239 constructor(source) { 20240 super(source, PDFDataTransportStreamReader, PDFDataTransportStreamRangeReader); 20241 const { 20242 pdfDataRangeTransport 20243 } = source; 20244 const { 20245 initialData, 20246 progressiveDone 20247 } = pdfDataRangeTransport; 20248 if (initialData?.length > 0) { 20249 const buffer = transport_stream_getArrayBuffer(initialData); 20250 this._queuedChunks.push(buffer); 20251 } 20252 this._progressiveDone = progressiveDone; 20253 const listener = args => { 20254 switch (args.type) { 20255 case "range": 20256 case "progressiveRead": 20257 this.#onReceiveData(args.begin, args.chunk); 20258 break; 20259 case "progressiveDone": 20260 this._fullReader?.progressiveDone(); 20261 this._progressiveDone = true; 20262 break; 20263 } 20264 }; 20265 pdfDataRangeTransport.transportReady(listener); 20266 } 20267 #onReceiveData(begin, chunk) { 20268 const buffer = transport_stream_getArrayBuffer(chunk); 20269 if (begin === undefined) { 20270 if (this._fullReader) { 20271 this._fullReader._enqueue(buffer); 20272 } else { 20273 this._queuedChunks.push(buffer); 20274 } 20275 } else { 20276 const rangeReader = this._rangeReaders.keys().find(r => r._begin === begin); 20277 assert(rangeReader, "#onReceiveData - no `PDFDataTransportStreamRangeReader` instance found."); 20278 rangeReader._enqueue(buffer); 20279 } 20280 } 20281 getFullReader() { 20282 const reader = super.getFullReader(); 20283 this._queuedChunks = null; 20284 return reader; 20285 } 20286 getRangeReader(begin, end) { 20287 const reader = super.getRangeReader(begin, end); 20288 if (reader) { 20289 reader.onDone = () => this._rangeReaders.delete(reader); 20290 this._source.pdfDataRangeTransport.requestDataRange(begin, end); 20291 } 20292 return reader; 20293 } 20294 cancelAllRequests(reason) { 20295 super.cancelAllRequests(reason); 20296 this._source.pdfDataRangeTransport.abort(); 20297 } 20298} 20299class PDFDataTransportStreamReader extends BasePDFStreamReader { 20300 #endRequests = endRequests.bind(this); 20301 _done = false; 20302 _queuedChunks = null; 20303 _requests = []; 20304 constructor(stream) { 20305 super(stream); 20306 const { 20307 pdfDataRangeTransport, 20308 disableRange, 20309 disableStream 20310 } = stream._source; 20311 const { 20312 length, 20313 contentDispositionFilename 20314 } = pdfDataRangeTransport; 20315 this._queuedChunks = stream._queuedChunks || []; 20316 for (const chunk of this._queuedChunks) { 20317 this._loaded += chunk.byteLength; 20318 } 20319 this._done = stream._progressiveDone; 20320 this._contentLength = length; 20321 this._isStreamingSupported = !disableStream; 20322 this._isRangeSupported = !disableRange; 20323 if (isPdfFile(contentDispositionFilename)) { 20324 this._filename = contentDispositionFilename; 20325 } 20326 this._headersCapability.resolve(); 20327 const loaded = this._loaded; 20328 Promise.resolve().then(() => { 20329 if (loaded > 0 && this._loaded === loaded) { 20330 this._callOnProgress(); 20331 } 20332 }); 20333 } 20334 _enqueue(chunk) { 20335 if (this._done) { 20336 return; 20337 } 20338 if (this._requests.length > 0) { 20339 const capability = this._requests.shift(); 20340 capability.resolve({ 20341 value: chunk, 20342 done: false 20343 }); 20344 } else { 20345 this._queuedChunks.push(chunk); 20346 } 20347 this._loaded += chunk.byteLength; 20348 this._callOnProgress(); 20349 } 20350 async read() { 20351 if (this._queuedChunks.length > 0) { 20352 const chunk = this._queuedChunks.shift(); 20353 return { 20354 value: chunk, 20355 done: false 20356 }; 20357 } 20358 if (this._done) { 20359 return { 20360 value: undefined, 20361 done: true 20362 }; 20363 } 20364 const capability = Promise.withResolvers(); 20365 this._requests.push(capability); 20366 return capability.promise; 20367 } 20368 cancel(reason) { 20369 this._done = true; 20370 this.#endRequests(); 20371 } 20372 progressiveDone() { 20373 this._done ||= true; 20374 if (this._queuedChunks.length === 0) { 20375 this.#endRequests(); 20376 } 20377 } 20378} 20379class PDFDataTransportStreamRangeReader extends BasePDFStreamRangeReader { 20380 #endRequests = endRequests.bind(this); 20381 onDone = null; 20382 _begin = -1; 20383 _done = false; 20384 _queuedChunk = null; 20385 _requests = []; 20386 constructor(stream, begin, end) { 20387 super(stream, begin, end); 20388 this._begin = begin; 20389 } 20390 _enqueue(chunk) { 20391 if (this._done) { 20392 return; 20393 } 20394 if (this._requests.length === 0) { 20395 this._queuedChunk = chunk; 20396 } else { 20397 const capability = this._requests.shift(); 20398 capability.resolve({ 20399 value: chunk, 20400 done: false 20401 }); 20402 this.#endRequests(); 20403 } 20404 this._done = true; 20405 this.onDone?.(); 20406 } 20407 async read() { 20408 if (this._queuedChunk) { 20409 const chunk = this._queuedChunk; 20410 this._queuedChunk = null; 20411 return { 20412 value: chunk, 20413 done: false 20414 }; 20415 } 20416 if (this._done) { 20417 return { 20418 value: undefined, 20419 done: true 20420 }; 20421 } 20422 const capability = Promise.withResolvers(); 20423 this._requests.push(capability); 20424 return capability.promise; 20425 } 20426 cancel(reason) { 20427 this._done = true; 20428 this.#endRequests(); 20429 this.onDone?.(); 20430 } 20431} 20432 20433;// ./src/display/network.js 20434 20435 20436 20437
vendor: 20,121 bytes, lines 20438-21207
20438 20439 20440 20441 20442 20443const OK_RESPONSE = 200; 20444const PARTIAL_CONTENT_RESPONSE = 206; 20445function network_getArrayBuffer(val) { 20446 return typeof val !== "string" ? val : stringToBytes(val).buffer; 20447} 20448class PDFNetworkStream extends BasePDFStream { 20449 #pendingRequests = new WeakMap(); 20450 _responseOrigin = null; 20451 constructor(source) { 20452 super(source, PDFNetworkStreamReader, PDFNetworkStreamRangeReader); 20453 const { 20454 httpHeaders, 20455 url 20456 } = source; 20457 this.url = url; 20458 this.isHttp = /https?:/.test(url.protocol); 20459 this.headers = createHeaders(this.isHttp, httpHeaders); 20460 } 20461 _request(args) { 20462 const xhr = new XMLHttpRequest(); 20463 const pendingRequest = { 20464 validateStatus: null, 20465 onHeadersReceived: args.onHeadersReceived, 20466 onDone: args.onDone, 20467 onError: args.onError, 20468 onProgress: args.onProgress 20469 }; 20470 this.#pendingRequests.set(xhr, pendingRequest); 20471 xhr.open("GET", this.url); 20472 xhr.withCredentials = this._source.withCredentials; 20473 for (const [key, val] of this.headers) { 20474 xhr.setRequestHeader(key, val); 20475 } 20476 if (this.isHttp && "begin" in args && "end" in args) { 20477 xhr.setRequestHeader("Range", `bytes=${args.begin}-${args.end - 1}`); 20478 pendingRequest.validateStatus = status => status === PARTIAL_CONTENT_RESPONSE || status === OK_RESPONSE; 20479 } else { 20480 pendingRequest.validateStatus = status => status === OK_RESPONSE; 20481 } 20482 xhr.responseType = "arraybuffer"; 20483 assert(args.onError, "Expected `onError` callback to be provided."); 20484 xhr.onerror = () => args.onError(xhr.status); 20485 xhr.onreadystatechange = this.#onStateChange.bind(this, xhr); 20486 xhr.onprogress = this.#onProgress.bind(this, xhr); 20487 xhr.send(null); 20488 return xhr; 20489 } 20490 #onProgress(xhr, evt) { 20491 const pendingRequest = this.#pendingRequests.get(xhr); 20492 pendingRequest?.onProgress?.(evt); 20493 } 20494 #onStateChange(xhr, evt) { 20495 const pendingRequest = this.#pendingRequests.get(xhr); 20496 if (!pendingRequest) { 20497 return; 20498 } 20499 if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { 20500 pendingRequest.onHeadersReceived(); 20501 delete pendingRequest.onHeadersReceived; 20502 } 20503 if (xhr.readyState !== 4) { 20504 return; 20505 } 20506 if (!this.#pendingRequests.has(xhr)) { 20507 return; 20508 } 20509 this.#pendingRequests.delete(xhr); 20510 if (xhr.status === 0 && this.isHttp) { 20511 pendingRequest.onError(xhr.status); 20512 return; 20513 } 20514 const xhrStatus = xhr.status || OK_RESPONSE; 20515 if (!pendingRequest.validateStatus(xhrStatus)) { 20516 pendingRequest.onError(xhr.status); 20517 return; 20518 } 20519 const chunk = network_getArrayBuffer(xhr.response); 20520 if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { 20521 const rangeHeader = xhr.getResponseHeader("Content-Range"); 20522 if (/bytes \d+-\d+\/\d+/.test(rangeHeader)) { 20523 pendingRequest.onDone(chunk); 20524 } else { 20525 warn(`Missing or invalid "Content-Range" header.`); 20526 pendingRequest.onError(0); 20527 } 20528 } else if (chunk) { 20529 pendingRequest.onDone(chunk); 20530 } else { 20531 pendingRequest.onError(xhr.status); 20532 } 20533 } 20534 _abortRequest(xhr) { 20535 if (this.#pendingRequests.has(xhr)) { 20536 this.#pendingRequests.delete(xhr); 20537 xhr.abort(); 20538 } 20539 } 20540 getRangeReader(begin, end) { 20541 const reader = super.getRangeReader(begin, end); 20542 if (reader) { 20543 reader.onClosed = () => this._rangeReaders.delete(reader); 20544 } 20545 return reader; 20546 } 20547} 20548class PDFNetworkStreamReader extends BasePDFStreamReader { 20549 #endRequests = endRequests.bind(this); 20550 _cachedChunks = []; 20551 _done = false; 20552 _requests = []; 20553 _storedError = null; 20554 constructor(stream) { 20555 super(stream); 20556 this._fullRequestXhr = stream._request({ 20557 onHeadersReceived: this.#onHeadersReceived.bind(this), 20558 onDone: this.#onDone.bind(this), 20559 onError: this.#onError.bind(this), 20560 onProgress: this.#onProgress.bind(this) 20561 }); 20562 } 20563 #onHeadersReceived() { 20564 const stream = this._stream; 20565 const { 20566 disableRange, 20567 rangeChunkSize 20568 } = stream._source; 20569 const fullRequestXhr = this._fullRequestXhr; 20570 stream._responseOrigin = getResponseOrigin(fullRequestXhr.responseURL); 20571 const rawResponseHeaders = fullRequestXhr.getAllResponseHeaders(); 20572 const responseHeaders = new Headers(rawResponseHeaders ? trimHeadersEnd(rawResponseHeaders.trimStart()).split(/[\r\n]+/).map(x => { 20573 const [key, ...val] = x.split(": "); 20574 return [key, val.join(": ")]; 20575 }) : []); 20576 const { 20577 contentLength, 20578 isRangeSupported 20579 } = validateRangeRequestCapabilities({ 20580 responseHeaders, 20581 isHttp: stream.isHttp, 20582 rangeChunkSize, 20583 disableRange 20584 }); 20585 this._contentLength = contentLength; 20586 this._isRangeSupported = isRangeSupported; 20587 this._filename = extractFilenameFromHeader(responseHeaders); 20588 if (this._isRangeSupported) { 20589 stream._abortRequest(fullRequestXhr); 20590 } 20591 this._headersCapability.resolve(); 20592 } 20593 #onDone(chunk) { 20594 if (this._requests.length > 0) { 20595 const capability = this._requests.shift(); 20596 capability.resolve({ 20597 value: chunk, 20598 done: false 20599 }); 20600 } else { 20601 this._cachedChunks.push(chunk); 20602 } 20603 this._done = true; 20604 if (this._cachedChunks.length === 0) { 20605 this.#endRequests(); 20606 } 20607 } 20608 #onError(status) { 20609 this._storedError = createResponseError(status, this._stream.url); 20610 this._headersCapability.reject(this._storedError); 20611 for (const capability of this._requests) { 20612 capability.reject(this._storedError); 20613 } 20614 this._requests.length = 0; 20615 this._cachedChunks.length = 0; 20616 } 20617 #onProgress(evt) { 20618 this.onProgress?.({ 20619 loaded: evt.loaded, 20620 total: evt.lengthComputable ? evt.total : this._contentLength 20621 }); 20622 } 20623 async read() { 20624 await this._headersCapability.promise; 20625 if (this._storedError) { 20626 throw this._storedError; 20627 } 20628 if (this._cachedChunks.length > 0) { 20629 const chunk = this._cachedChunks.shift(); 20630 return { 20631 value: chunk, 20632 done: false 20633 }; 20634 } 20635 if (this._done) { 20636 return { 20637 value: undefined, 20638 done: true 20639 }; 20640 } 20641 const capability = Promise.withResolvers(); 20642 this._requests.push(capability); 20643 return capability.promise; 20644 } 20645 cancel(reason) { 20646 this._done = true; 20647 this._headersCapability.reject(reason); 20648 this.#endRequests(); 20649 this._stream._abortRequest(this._fullRequestXhr); 20650 this._fullRequestXhr = null; 20651 } 20652} 20653class PDFNetworkStreamRangeReader extends BasePDFStreamRangeReader { 20654 #endRequests = endRequests.bind(this); 20655 onClosed = null; 20656 _done = false; 20657 _queuedChunk = null; 20658 _requests = []; 20659 _storedError = null; 20660 constructor(stream, begin, end) { 20661 super(stream, begin, end); 20662 this._requestXhr = stream._request({ 20663 begin, 20664 end, 20665 onHeadersReceived: this.#onHeadersReceived.bind(this), 20666 onDone: this.#onDone.bind(this), 20667 onError: this.#onError.bind(this), 20668 onProgress: null 20669 }); 20670 } 20671 #onHeadersReceived() { 20672 const responseOrigin = getResponseOrigin(this._requestXhr?.responseURL); 20673 try { 20674 ensureResponseOrigin(responseOrigin, this._stream._responseOrigin); 20675 } catch (ex) { 20676 this._storedError = ex; 20677 this.#onError(0); 20678 } 20679 } 20680 #onDone(chunk) { 20681 if (this._requests.length > 0) { 20682 const capability = this._requests.shift(); 20683 capability.resolve({ 20684 value: chunk, 20685 done: false 20686 }); 20687 } else { 20688 this._queuedChunk = chunk; 20689 } 20690 this._done = true; 20691 this.#endRequests(); 20692 this.onClosed?.(); 20693 } 20694 #onError(status) { 20695 this._storedError ??= createResponseError(status, this._stream.url); 20696 for (const capability of this._requests) { 20697 capability.reject(this._storedError); 20698 } 20699 this._requests.length = 0; 20700 this._queuedChunk = null; 20701 } 20702 async read() { 20703 if (this._storedError) { 20704 throw this._storedError; 20705 } 20706 if (this._queuedChunk !== null) { 20707 const chunk = this._queuedChunk; 20708 this._queuedChunk = null; 20709 return { 20710 value: chunk, 20711 done: false 20712 }; 20713 } 20714 if (this._done) { 20715 return { 20716 value: undefined, 20717 done: true 20718 }; 20719 } 20720 const capability = Promise.withResolvers(); 20721 this._requests.push(capability); 20722 return capability.promise; 20723 } 20724 cancel(reason) { 20725 this._done = true; 20726 this.#endRequests(); 20727 this._stream._abortRequest(this._requestXhr); 20728 this.onClosed?.(); 20729 } 20730} 20731 20732;// ./src/display/node_stream.js 20733 20734 20735 20736 20737function getReadableStream(url, opts = null) { 20738 const fs = process.getBuiltinModule("fs"); 20739 const { 20740 Readable 20741 } = process.getBuiltinModule("stream"); 20742 const readStream = fs.createReadStream(url, opts); 20743 return Readable.toWeb(readStream); 20744} 20745class PDFNodeStream extends BasePDFStream { 20746 constructor(source) { 20747 super(source, PDFNodeStreamReader, PDFNodeStreamRangeReader); 20748 const { 20749 url 20750 } = source; 20751 assert(url.protocol === "file:", "PDFNodeStream only supports file:// URLs."); 20752 } 20753} 20754class PDFNodeStreamReader extends BasePDFStreamReader { 20755 _reader = null; 20756 constructor(stream) { 20757 super(stream); 20758 const { 20759 disableRange, 20760 disableStream, 20761 rangeChunkSize, 20762 url 20763 } = stream._source; 20764 this._isStreamingSupported = !disableStream; 20765 const fs = process.getBuiltinModule("fs/promises"); 20766 fs.lstat(url).then(stat => { 20767 const readableStream = getReadableStream(url); 20768 this._reader = readableStream.getReader(); 20769 const { 20770 size 20771 } = stat; 20772 this._contentLength = size; 20773 this._isRangeSupported = !disableRange && size > 2 * rangeChunkSize; 20774 if (!this._isStreamingSupported && this._isRangeSupported) { 20775 this.cancel(new AbortException("Streaming is disabled.")); 20776 } 20777 this._headersCapability.resolve(); 20778 }).catch(error => { 20779 if (error.code === "ENOENT") { 20780 error = createResponseError(0, url); 20781 } 20782 this._headersCapability.reject(error); 20783 }); 20784 } 20785 async read() { 20786 await this._headersCapability.promise; 20787 const { 20788 value, 20789 done 20790 } = await this._reader.read(); 20791 if (done) { 20792 return { 20793 value, 20794 done 20795 }; 20796 } 20797 this._loaded += value.byteLength; 20798 this._callOnProgress(); 20799 return { 20800 value: getArrayBuffer(value), 20801 done: false 20802 }; 20803 } 20804 cancel(reason) { 20805 this._reader?.cancel(reason); 20806 } 20807} 20808class PDFNodeStreamRangeReader extends BasePDFStreamRangeReader { 20809 _readCapability = Promise.withResolvers(); 20810 _reader = null; 20811 constructor(stream, begin, end) { 20812 super(stream, begin, end); 20813 const { 20814 url 20815 } = stream._source; 20816 try { 20817 const readableStream = getReadableStream(url, { 20818 start: begin, 20819 end: end - 1 20820 }); 20821 this._reader = readableStream.getReader(); 20822 this._readCapability.resolve(); 20823 } catch (error) { 20824 this._readCapability.reject(error); 20825 } 20826 } 20827 async read() { 20828 await this._readCapability.promise; 20829 const { 20830 value, 20831 done 20832 } = await this._reader.read(); 20833 if (done) { 20834 return { 20835 value, 20836 done 20837 }; 20838 } 20839 return { 20840 value: getArrayBuffer(value), 20841 done: false 20842 }; 20843 } 20844 cancel(reason) { 20845 this._reader?.cancel(reason); 20846 } 20847} 20848 20849;// ./src/display/network_stream.js 20850 20851 20852 20853 20854 20855function getNetworkStream(url) { 20856 return isValidFetchUrl(url) ? PDFFetchStream : isNodeJS ? PDFNodeStream : PDFNetworkStream; 20857} 20858 20859;// ./src/display/worker_options.js 20860class GlobalWorkerOptions { 20861 static #port = null; 20862 static #src = ""; 20863 static get workerPort() { 20864 return this.#port; 20865 } 20866 static set workerPort(val) { 20867 if (!(typeof Worker !== "undefined" && val instanceof Worker) && val !== null) { 20868 throw new Error("Invalid `workerPort` type."); 20869 } 20870 this.#port = val; 20871 } 20872 static get workerSrc() { 20873 return this.#src; 20874 } 20875 static set workerSrc(val) { 20876 if (typeof val !== "string") { 20877 throw new Error("Invalid `workerSrc` type."); 20878 } 20879 this.#src = val; 20880 } 20881} 20882 20883;// ./src/display/metadata.js 20884class Metadata { 20885 #map; 20886 #data; 20887 constructor({ 20888 parsedData, 20889 rawData 20890 }) { 20891 this.#map = parsedData; 20892 this.#data = rawData; 20893 } 20894 getRaw() { 20895 return this.#data; 20896 } 20897 get(name) { 20898 return this.#map.get(name) ?? null; 20899 } 20900 [Symbol.iterator]() { 20901 return this.#map.entries(); 20902 } 20903} 20904 20905;// ./src/display/optional_content_config.js 20906 20907 20908 20909 20910const INTERNAL = Symbol("INTERNAL"); 20911class OptionalContentGroup { 20912 #isDisplay = false; 20913 #isPrint = false; 20914 #userSet = false; 20915 #visible = true; 20916 constructor(renderingIntent, { 20917 name, 20918 intent, 20919 usage, 20920 rbGroups 20921 }) { 20922 this.#isDisplay = !!(renderingIntent & RenderingIntentFlag.DISPLAY); 20923 this.#isPrint = !!(renderingIntent & RenderingIntentFlag.PRINT); 20924 this.name = name; 20925 this.intent = intent; 20926 this.usage = usage; 20927 this.rbGroups = rbGroups; 20928 } 20929 get visible() { 20930 if (this.#userSet) { 20931 return this.#visible; 20932 } 20933 if (!this.#visible) { 20934 return false; 20935 } 20936 const { 20937 print, 20938 view 20939 } = this.usage; 20940 if (this.#isDisplay) { 20941 return view?.viewState !== "OFF"; 20942 } else if (this.#isPrint) { 20943 return print?.printState !== "OFF"; 20944 } 20945 return true; 20946 } 20947 _setVisible(internal, visible, userSet = false) { 20948 if (internal !== INTERNAL) { 20949 unreachable("Internal method `_setVisible` called."); 20950 } 20951 this.#userSet = userSet; 20952 this.#visible = visible; 20953 } 20954 get serializable() { 20955 return { 20956 userSet: this.#userSet, 20957 visible: this.#visible 20958 }; 20959 } 20960} 20961class OptionalContentConfig { 20962 #cachedGetHash = null; 20963 #groups = new Map(); 20964 #initialHash = null; 20965 #order = null; 20966 #rawData; 20967 creator = null; 20968 name = null; 20969 constructor(data, renderingIntent = RenderingIntentFlag.DISPLAY, groupState = null) { 20970 this.#rawData = data; 20971 this.renderingIntent = renderingIntent; 20972 if (data === null) { 20973 return; 20974 } 20975 this.name = data.name; 20976 this.creator = data.creator; 20977 this.#order = data.order; 20978 for (const group of data.groups) { 20979 this.#groups.set(group.id, new OptionalContentGroup(renderingIntent, group)); 20980 } 20981 if (groupState) { 20982 if (groupState.size !== this.#groups.size) { 20983 unreachable("Incorrect serialized groupState."); 20984 } 20985 for (const [id, group] of groupState) { 20986 this.#groups.get(id)._setVisible(INTERNAL, group.visible, group.userSet); 20987 } 20988 } else { 20989 if (data.baseState === "OFF") { 20990 for (const group of this.#groups.values()) { 20991 group._setVisible(INTERNAL, false); 20992 } 20993 } 20994 for (const on of data.on) { 20995 this.#groups.get(on)._setVisible(INTERNAL, true); 20996 } 20997 for (const off of data.off) { 20998 this.#groups.get(off)._setVisible(INTERNAL, false); 20999 } 21000 } 21001 this.#initialHash = this.getHash(); 21002 } 21003 #evaluateVisibilityExpression(array) { 21004 const length = array.length; 21005 if (length < 2) { 21006 return true; 21007 } 21008 const operator = array[0]; 21009 for (let i = 1; i < length; i++) { 21010 const element = array[i]; 21011 let state; 21012 if (Array.isArray(element)) { 21013 state = this.#evaluateVisibilityExpression(element); 21014 } else if (this.#groups.has(element)) { 21015 state = this.#groups.get(element).visible; 21016 } else { 21017 warn(`Optional content group not found: ${element}`); 21018 return true; 21019 } 21020 switch (operator) { 21021 case "And": 21022 if (!state) { 21023 return false; 21024 } 21025 break; 21026 case "Or": 21027 if (state) { 21028 return true; 21029 } 21030 break; 21031 case "Not": 21032 return !state; 21033 default: 21034 return true; 21035 } 21036 } 21037 return operator === "And"; 21038 } 21039 isVisible(group) { 21040 if (this.#groups.size === 0) { 21041 return true; 21042 } 21043 if (!group) { 21044 info("Optional content group not defined."); 21045 return true; 21046 } 21047 if (group.type === "OCG") { 21048 if (!this.#groups.has(group.id)) { 21049 warn(`Optional content group not found: ${group.id}`); 21050 return true; 21051 } 21052 return this.#groups.get(group.id).visible; 21053 } else if (group.type === "OCMD") { 21054 if (group.expression) { 21055 return this.#evaluateVisibilityExpression(group.expression); 21056 } 21057 if (!group.policy || group.policy === "AnyOn") { 21058 for (const id of group.ids) { 21059 if (!this.#groups.has(id)) { 21060 warn(`Optional content group not found: ${id}`); 21061 return true; 21062 } 21063 if (this.#groups.get(id).visible) { 21064 return true; 21065 } 21066 } 21067 return false; 21068 } else if (group.policy === "AllOn") { 21069 for (const id of group.ids) { 21070 if (!this.#groups.has(id)) { 21071 warn(`Optional content group not found: ${id}`); 21072 return true; 21073 } 21074 if (!this.#groups.get(id).visible) { 21075 return false; 21076 } 21077 } 21078 return true; 21079 } else if (group.policy === "AnyOff") { 21080 for (const id of group.ids) { 21081 if (!this.#groups.has(id)) { 21082 warn(`Optional content group not found: ${id}`); 21083 return true; 21084 } 21085 if (!this.#groups.get(id).visible) { 21086 return true; 21087 } 21088 } 21089 return false; 21090 } else if (group.policy === "AllOff") { 21091 for (const id of group.ids) { 21092 if (!this.#groups.has(id)) { 21093 warn(`Optional content group not found: ${id}`); 21094 return true; 21095 } 21096 if (this.#groups.get(id).visible) { 21097 return false; 21098 } 21099 } 21100 return true; 21101 } 21102 warn(`Unknown optional content policy ${group.policy}.`); 21103 return true; 21104 } 21105 warn(`Unknown group type ${group.type}.`); 21106 return true; 21107 } 21108 setVisibility(id, visible = true, preserveRB = true) { 21109 const group = this.#groups.get(id); 21110 if (!group) { 21111 warn(`Optional content group not found: ${id}`); 21112 return; 21113 } 21114 if (preserveRB && visible && group.rbGroups.length) { 21115 for (const rbGroup of group.rbGroups) { 21116 for (const otherId of rbGroup) { 21117 if (otherId !== id) { 21118 this.#groups.get(otherId)?._setVisible(INTERNAL, false, true); 21119 } 21120 } 21121 } 21122 } 21123 group._setVisible(INTERNAL, !!visible, true); 21124 this.#cachedGetHash = null; 21125 } 21126 setOCGState({ 21127 state, 21128 preserveRB 21129 }) { 21130 let operator; 21131 for (const elem of state) { 21132 switch (elem) { 21133 case "ON": 21134 case "OFF": 21135 case "Toggle": 21136 operator = elem; 21137 continue; 21138 } 21139 const group = this.#groups.get(elem); 21140 if (!group) { 21141 continue; 21142 } 21143 switch (operator) { 21144 case "ON": 21145 this.setVisibility(elem, true, preserveRB); 21146 break; 21147 case "OFF": 21148 this.setVisibility(elem, false, preserveRB); 21149 break; 21150 case "Toggle": 21151 this.setVisibility(elem, !group.visible, preserveRB); 21152 break; 21153 } 21154 } 21155 this.#cachedGetHash = null; 21156 } 21157 get hasInitialVisibility() { 21158 return this.#initialHash === null || this.getHash() === this.#initialHash; 21159 } 21160 getOrder() { 21161 if (!this.#groups.size) { 21162 return null; 21163 } 21164 if (this.#order) { 21165 return this.#order.slice(); 21166 } 21167 return [...this.#groups.keys()]; 21168 } 21169 getGroup(id) { 21170 return this.#groups.get(id) || null; 21171 } 21172 getHash() { 21173 if (this.#cachedGetHash !== null) { 21174 return this.#cachedGetHash; 21175 } 21176 const hash = new MurmurHash3_64(); 21177 for (const [id, group] of this.#groups) { 21178 hash.update(`${id}:${group.visible}`); 21179 } 21180 return this.#cachedGetHash = hash.hexdigest(); 21181 } 21182 [Symbol.iterator]() { 21183 return this.#groups.entries(); 21184 } 21185 get serializable() { 21186 const groupState = new Map(); 21187 for (const [id, group] of this.#groups) { 21188 groupState.set(id, group.serializable); 21189 } 21190 return { 21191 data: this.#rawData, 21192 renderingIntent: this.renderingIntent, 21193 groupState 21194 }; 21195 } 21196 static fromSerializable({ 21197 data, 21198 renderingIntent, 21199 groupState 21200 }) { 21201 return new OptionalContentConfig(data, renderingIntent, groupState); 21202 } 21203} 21204 21205;// ./src/display/pages_mapper.js 21206 21207
vendor: 10,185 bytes, lines 21208-21550
21208 21209 21210 21211 21212 21213 21214 21215 21216 21217 21218 21219 21220 21221 21222class PagesMapper { 21223 #pageNumberToId = null; 21224 #prevPageNumbers = null; 21225 #pagesNumber = 0; 21226 #clipboard = null; 21227 #savedData = null; 21228 get pagesNumber() { 21229 return this.#pagesNumber; 21230 } 21231 set pagesNumber(n) { 21232 if (this.#pagesNumber === n) { 21233 return; 21234 } 21235 this.#pagesNumber = n; 21236 this.#pageNumberToId = null; 21237 this.#prevPageNumbers = null; 21238 } 21239 #ensureInit() { 21240 if (this.#pageNumberToId) { 21241 return; 21242 } 21243 const n = this.#pagesNumber; 21244 const pageNumberToId = this.#pageNumberToId = new Uint32Array(n); 21245 for (let i = 0; i < n; i++) { 21246 pageNumberToId[i] = i + 1; 21247 } 21248 this.#prevPageNumbers = new Int32Array(pageNumberToId); 21249 } 21250 #buildIdToPageNumber() { 21251 const idToPageNumber = new Map(); 21252 const pageNumberToId = this.#pageNumberToId; 21253 for (let i = 0, ii = this.#pagesNumber; i < ii; i++) { 21254 const id = pageNumberToId[i]; 21255 const pageNumbers = idToPageNumber.get(id); 21256 if (pageNumbers) { 21257 pageNumbers.push(i + 1); 21258 } else { 21259 idToPageNumber.set(id, [i + 1]); 21260 } 21261 } 21262 return idToPageNumber; 21263 } 21264 movePages(selectedPages, pagesToMove, index) { 21265 this.#ensureInit(); 21266 const pageNumberToId = this.#pageNumberToId; 21267 const movedCount = pagesToMove.length; 21268 const mappedPagesToMove = new Uint32Array(movedCount); 21269 let removedBeforeTarget = 0; 21270 for (let i = 0; i < movedCount; i++) { 21271 const pageIndex = pagesToMove[i] - 1; 21272 mappedPagesToMove[i] = pageNumberToId[pageIndex]; 21273 if (pageIndex < index) { 21274 removedBeforeTarget++; 21275 } 21276 } 21277 const pagesNumber = this.#pagesNumber; 21278 const remainingLen = pagesNumber - movedCount; 21279 const prevPageNumbers = new Int32Array(pagesNumber); 21280 const adjustedTarget = MathClamp(index - removedBeforeTarget, 0, remainingLen); 21281 for (let i = 0, r = 0; i < pagesNumber; i++) { 21282 if (!selectedPages.has(i + 1)) { 21283 pageNumberToId[r] = pageNumberToId[i]; 21284 prevPageNumbers[r++] = i + 1; 21285 } 21286 } 21287 pageNumberToId.copyWithin(adjustedTarget + movedCount, adjustedTarget, remainingLen); 21288 pageNumberToId.set(mappedPagesToMove, adjustedTarget); 21289 prevPageNumbers.copyWithin(adjustedTarget + movedCount, adjustedTarget, remainingLen); 21290 prevPageNumbers.set(pagesToMove, adjustedTarget); 21291 this.#prevPageNumbers = prevPageNumbers; 21292 if (pageNumberToId.every((id, i) => id === i + 1)) { 21293 this.#pageNumberToId = null; 21294 } 21295 } 21296 deletePages(pagesToDelete) { 21297 this.#ensureInit(); 21298 const pageNumberToId = this.#pageNumberToId; 21299 const prevIdToPageNumber = this.#buildIdToPageNumber(); 21300 this.#savedData = { 21301 pageNumberToId: pageNumberToId.slice(), 21302 pagesNumber: this.#pagesNumber, 21303 prevPageNumbers: this.#prevPageNumbers.slice() 21304 }; 21305 const newN = this.#pagesNumber - pagesToDelete.length; 21306 this.#pagesNumber = newN; 21307 const newPageNumberToId = this.#pageNumberToId = new Uint32Array(newN); 21308 this.#prevPageNumbers = new Int32Array(newN); 21309 let sourceIndex = 0; 21310 let destIndex = 0; 21311 for (const pageNumber of pagesToDelete) { 21312 const pageIndex = pageNumber - 1; 21313 if (pageIndex !== sourceIndex) { 21314 newPageNumberToId.set(pageNumberToId.subarray(sourceIndex, pageIndex), destIndex); 21315 destIndex += pageIndex - sourceIndex; 21316 } 21317 sourceIndex = pageIndex + 1; 21318 } 21319 if (sourceIndex < pageNumberToId.length) { 21320 newPageNumberToId.set(pageNumberToId.subarray(sourceIndex), destIndex); 21321 } 21322 this.#updatePrevPageNumbers(prevIdToPageNumber, new Set(pagesToDelete)); 21323 } 21324 cancelDelete() { 21325 if (this.#savedData) { 21326 this.#pageNumberToId = this.#savedData.pageNumberToId; 21327 this.#pagesNumber = this.#savedData.pagesNumber; 21328 this.#prevPageNumbers = this.#savedData.prevPageNumbers; 21329 this.#savedData = null; 21330 } 21331 } 21332 cleanSavedData() { 21333 this.#savedData = null; 21334 } 21335 copyPages(pagesToCopy) { 21336 this.#ensureInit(); 21337 this.#clipboard = { 21338 pageNumbers: pagesToCopy, 21339 pageIds: pagesToCopy.map(n => this.#pageNumberToId[n - 1]) 21340 }; 21341 } 21342 cancelCopy() { 21343 this.#clipboard = null; 21344 } 21345 pastePages(index) { 21346 this.#ensureInit(); 21347 const pageNumberToId = this.#pageNumberToId; 21348 const prevIdToPageNumber = this.#buildIdToPageNumber(); 21349 const { 21350 pageNumbers: copiedPageNumbers, 21351 pageIds: copiedPageIds 21352 } = this.#clipboard; 21353 const newN = this.#pagesNumber + copiedPageNumbers.length; 21354 this.#pagesNumber = newN; 21355 const newPageNumberToId = this.#pageNumberToId = new Uint32Array(newN); 21356 this.#prevPageNumbers = new Int32Array(newN); 21357 newPageNumberToId.set(pageNumberToId.subarray(0, index), 0); 21358 newPageNumberToId.set(copiedPageIds, index); 21359 newPageNumberToId.set(pageNumberToId.subarray(index), index + copiedPageNumbers.length); 21360 this.#updatePrevPageNumbers(prevIdToPageNumber, null, index, copiedPageNumbers); 21361 this.#clipboard = null; 21362 } 21363 #updatePrevPageNumbers(prevIdToPageNumber, deletedPageNumbers = null, pasteIndex = -1, copiedPageNumbers = null) { 21364 const prevPageNumbers = this.#prevPageNumbers; 21365 const newPageNumberToId = this.#pageNumberToId; 21366 const pasteEnd = pasteIndex + (copiedPageNumbers?.length ?? 0); 21367 const idsIndices = new Map(); 21368 for (let i = 0, ii = this.#pagesNumber; i < ii; i++) { 21369 if (i >= pasteIndex && i < pasteEnd) { 21370 prevPageNumbers[i] = -copiedPageNumbers[i - pasteIndex]; 21371 continue; 21372 } 21373 const id = newPageNumberToId[i]; 21374 const oldPositions = prevIdToPageNumber.get(id); 21375 let j = idsIndices.get(id) || 0; 21376 if (deletedPageNumbers && oldPositions) { 21377 while (j < oldPositions.length && deletedPageNumbers.has(oldPositions[j])) { 21378 j++; 21379 } 21380 } 21381 prevPageNumbers[i] = oldPositions?.[j]; 21382 idsIndices.set(id, j + 1); 21383 } 21384 } 21385 hasBeenAltered() { 21386 return this.#pageNumberToId !== null; 21387 } 21388 #buildCopyLevels(extractedPageNumbers = null) { 21389 if (!this.#pageNumberToId) { 21390 return null; 21391 } 21392 const copyLevels = new Int32Array(this.#pagesNumber).fill(-1); 21393 const counts = new Map(); 21394 if (extractedPageNumbers) { 21395 for (const pageNumber of extractedPageNumbers) { 21396 const id = this.getPageId(pageNumber); 21397 const level = counts.get(id) ?? 0; 21398 counts.set(id, level + 1); 21399 copyLevels[pageNumber - 1] = level; 21400 } 21401 } else { 21402 for (let i = 0, ii = this.#pagesNumber; i < ii; i++) { 21403 const id = this.#pageNumberToId[i]; 21404 const level = counts.get(id) ?? 0; 21405 counts.set(id, level + 1); 21406 copyLevels[i] = level; 21407 } 21408 } 21409 return copyLevels; 21410 } 21411 getPageMappingForSaving(idToPageNumber = null, copyLevels = this.#buildCopyLevels()) { 21412 idToPageNumber ??= this.#buildIdToPageNumber(); 21413 let nCopy = 0; 21414 for (const pageNumbers of idToPageNumber.values()) { 21415 nCopy = Math.max(nCopy, pageNumbers.length); 21416 } 21417 const extractParams = new Array(nCopy); 21418 for (let i = 0; i < nCopy; i++) { 21419 extractParams[i] = { 21420 document: null, 21421 pageIndices: [], 21422 includePages: [] 21423 }; 21424 } 21425 for (const [id, pageNumbers] of idToPageNumber) { 21426 for (let i = 0, ii = pageNumbers.length; i < ii; i++) { 21427 extractParams[i].includePages.push([id - 1, pageNumbers[i] - 1]); 21428 } 21429 } 21430 for (const { 21431 includePages, 21432 pageIndices 21433 } of extractParams) { 21434 includePages.sort((a, b) => a[0] - b[0]); 21435 for (let i = 0, ii = includePages.length; i < ii; i++) { 21436 pageIndices.push(includePages[i][1]); 21437 includePages[i] = includePages[i][0]; 21438 } 21439 } 21440 return { 21441 pageInfos: extractParams, 21442 copyLevels 21443 }; 21444 } 21445 extractPages(extractedPageNumbers) { 21446 extractedPageNumbers = Array.from(extractedPageNumbers).sort((a, b) => a - b); 21447 const usedIds = new Map(); 21448 for (let i = 0, ii = extractedPageNumbers.length; i < ii; i++) { 21449 const id = this.getPageId(extractedPageNumbers[i]); 21450 const usedPageNumbers = usedIds.getOrInsertComputed(id, makeArr); 21451 usedPageNumbers.push(i + 1); 21452 } 21453 return this.getPageMappingForSaving(usedIds, this.#buildCopyLevels(extractedPageNumbers)); 21454 } 21455 getPrevPageNumber(pageNumber) { 21456 return this.#prevPageNumbers?.[pageNumber - 1] ?? 0; 21457 } 21458 getPageNumber(id) { 21459 if (!this.#pageNumberToId) { 21460 return id; 21461 } 21462 const pageNumberToId = this.#pageNumberToId; 21463 for (let i = 0, ii = this.#pagesNumber; i < ii; i++) { 21464 if (pageNumberToId[i] === id) { 21465 return i + 1; 21466 } 21467 } 21468 return 0; 21469 } 21470 getPageId(pageNumber) { 21471 return this.#pageNumberToId?.[pageNumber - 1] ?? pageNumber; 21472 } 21473 getMapping() { 21474 return this.#pageNumberToId?.subarray(0, this.pagesNumber); 21475 } 21476} 21477 21478;// ./src/display/pdf_objects.js 21479 21480 21481const INITIAL_DATA = Symbol("INITIAL_DATA"); 21482const dataObj = () => ({ 21483 ...Promise.withResolvers(), 21484 data: INITIAL_DATA 21485}); 21486class PDFObjects { 21487 #objs = new Map(); 21488 get(objId, callback = null) { 21489 if (callback) { 21490 const obj = this.#objs.getOrInsertComputed(objId, dataObj); 21491 obj.promise.then(() => callback(obj.data)); 21492 return null; 21493 } 21494 const obj = this.#objs.get(objId); 21495 if (!obj || obj.data === INITIAL_DATA) { 21496 throw new Error(`Requesting object that isn't resolved yet ${objId}.`); 21497 } 21498 return obj.data; 21499 } 21500 has(objId) { 21501 const obj = this.#objs.get(objId); 21502 return !!obj && obj.data !== INITIAL_DATA; 21503 } 21504 delete(objId) { 21505 const obj = this.#objs.get(objId); 21506 if (!obj || obj.data === INITIAL_DATA) { 21507 return false; 21508 } 21509 this.#objs.delete(objId); 21510 return true; 21511 } 21512 resolve(objId, data = null) { 21513 const obj = this.#objs.getOrInsertComputed(objId, dataObj); 21514 if (obj.data !== INITIAL_DATA) { 21515 throw new Error(`Object already resolved ${objId}.`); 21516 } 21517 obj.data = data; 21518 obj.resolve(); 21519 } 21520 clear() { 21521 for (const { 21522 data 21523 } of this.#objs.values()) { 21524 data?.bitmap?.close(); 21525 } 21526 this.#objs.clear(); 21527 } 21528 *[Symbol.iterator]() { 21529 for (const [objId, { 21530 data 21531 }] of this.#objs) { 21532 if (data !== INITIAL_DATA) { 21533 yield [objId, data]; 21534 } 21535 } 21536 } 21537} 21538 21539;// ./src/display/text_layer.js 21540 21541 21542 21543 21544 21545 21546 21547 21548 21549 21550
vendor: 68,261 bytes, lines 21551-23754
21551 21552 21553 21554const MAX_TEXT_DIVS_TO_RENDER = 100000; 21555const DEFAULT_FONT_SIZE = 30; 21556class TextLayer { 21557 #capability = Promise.withResolvers(); 21558 #container = null; 21559 #disableProcessItems = false; 21560 #fontInspectorEnabled = !!globalThis.FontInspector?.enabled; 21561 #imagesHandler = null; 21562 #lang = null; 21563 #layoutTextParams = null; 21564 #pageHeight = 0; 21565 #pageWidth = 0; 21566 #reader = null; 21567 #rootContainer = null; 21568 #rotation = 0; 21569 #scale = 0; 21570 #styleCache = Object.create(null); 21571 #textContentItemsStr = []; 21572 #textContentSource = null; 21573 #textDivs = []; 21574 #textDivProperties = new WeakMap(); 21575 #transform = null; 21576 static #ascentCache = new Map(); 21577 static #canvasContexts = new Map(); 21578 static #canvasCtxFonts = new WeakMap(); 21579 static #minFontSize = null; 21580 static #pendingTextLayers = new Set(); 21581 constructor({ 21582 textContentSource, 21583 images, 21584 container, 21585 viewport 21586 }) { 21587 if (textContentSource instanceof ReadableStream) { 21588 this.#textContentSource = textContentSource; 21589 } else if (typeof textContentSource === "object") { 21590 this.#textContentSource = new ReadableStream({ 21591 start(controller) { 21592 controller.enqueue(textContentSource); 21593 controller.close(); 21594 } 21595 }); 21596 } else { 21597 throw new Error('No "textContentSource" parameter specified.'); 21598 } 21599 this.#container = this.#rootContainer = container; 21600 this.#imagesHandler = images; 21601 this.#scale = viewport.scale * OutputScale.pixelRatio; 21602 this.#rotation = viewport.rotation; 21603 this.#layoutTextParams = { 21604 div: null, 21605 properties: null, 21606 ctx: null 21607 }; 21608 const { 21609 pageWidth, 21610 pageHeight, 21611 pageX, 21612 pageY 21613 } = viewport.rawDims; 21614 this.#transform = [1, 0, 0, -1, -pageX, pageY + pageHeight]; 21615 this.#pageWidth = pageWidth; 21616 this.#pageHeight = pageHeight; 21617 TextLayer.#ensureMinFontSizeComputed(); 21618 container.style.setProperty("--min-font-size", TextLayer.#minFontSize); 21619 setLayerDimensions(container, viewport); 21620 this.#capability.promise.finally(() => { 21621 TextLayer.#pendingTextLayers.delete(this); 21622 this.#layoutTextParams = null; 21623 this.#styleCache = null; 21624 }).catch(() => {}); 21625 } 21626 static get fontFamilyMap() { 21627 const { 21628 isWindows, 21629 isFirefox 21630 } = FeatureTest.platform; 21631 return shadow(this, "fontFamilyMap", new Map([["sans-serif", `${isWindows && isFirefox ? "Calibri, " : ""}sans-serif`], ["monospace", `${isWindows && isFirefox ? "Lucida Console, " : ""}monospace`]])); 21632 } 21633 render() { 21634 if (this.#imagesHandler) { 21635 this.#container.append(this.#imagesHandler.render()); 21636 } 21637 const pump = () => { 21638 this.#reader.read().then(({ 21639 value, 21640 done 21641 }) => { 21642 if (done) { 21643 this.#capability.resolve(); 21644 return; 21645 } 21646 this.#lang ??= value.lang; 21647 Object.assign(this.#styleCache, value.styles); 21648 this.#processItems(value.items); 21649 pump(); 21650 }, this.#capability.reject); 21651 }; 21652 this.#reader = this.#textContentSource.getReader(); 21653 TextLayer.#pendingTextLayers.add(this); 21654 pump(); 21655 return this.#capability.promise; 21656 } 21657 update({ 21658 viewport, 21659 onBefore = null 21660 }) { 21661 const scale = viewport.scale * OutputScale.pixelRatio; 21662 const rotation = viewport.rotation; 21663 if (rotation !== this.#rotation) { 21664 onBefore?.(); 21665 this.#rotation = rotation; 21666 setLayerDimensions(this.#rootContainer, { 21667 rotation 21668 }); 21669 } 21670 if (scale !== this.#scale) { 21671 onBefore?.(); 21672 this.#scale = scale; 21673 const params = { 21674 div: null, 21675 properties: null, 21676 ctx: TextLayer.#getCtx(this.#lang) 21677 }; 21678 for (const div of this.#textDivs) { 21679 params.properties = this.#textDivProperties.get(div); 21680 params.div = div; 21681 this.#layout(params); 21682 } 21683 } 21684 } 21685 cancel() { 21686 const abortEx = new AbortException("TextLayer task cancelled."); 21687 this.#reader?.cancel(abortEx).catch(() => {}); 21688 this.#reader = null; 21689 this.#capability.reject(abortEx); 21690 } 21691 get textDivs() { 21692 return this.#textDivs; 21693 } 21694 get textContentItemsStr() { 21695 return this.#textContentItemsStr; 21696 } 21697 #processItems(items) { 21698 if (this.#disableProcessItems) { 21699 return; 21700 } 21701 this.#layoutTextParams.ctx ??= TextLayer.#getCtx(this.#lang); 21702 const textDivs = this.#textDivs, 21703 textContentItemsStr = this.#textContentItemsStr; 21704 for (const item of items) { 21705 if (textDivs.length > MAX_TEXT_DIVS_TO_RENDER) { 21706 warn("Ignoring additional textDivs for performance reasons."); 21707 this.#disableProcessItems = true; 21708 return; 21709 } 21710 if (item.str === undefined) { 21711 if (item.type === "beginMarkedContentProps" || item.type === "beginMarkedContent") { 21712 const parent = this.#container; 21713 this.#container = document.createElement("span"); 21714 this.#container.classList.add("markedContent"); 21715 if (item.id) { 21716 this.#container.setAttribute("id", item.id); 21717 } 21718 if (item.tag === "Artifact") { 21719 this.#container.ariaHidden = true; 21720 } 21721 parent.append(this.#container); 21722 } else if (item.type === "endMarkedContent") { 21723 this.#container = this.#container.parentNode; 21724 } 21725 continue; 21726 } 21727 textContentItemsStr.push(item.str); 21728 this.#appendText(item); 21729 } 21730 } 21731 #appendText(geom) { 21732 const textDiv = document.createElement("span"); 21733 const textDivProperties = { 21734 angle: 0, 21735 canvasWidth: 0, 21736 hasText: geom.str !== "", 21737 hasEOL: geom.hasEOL, 21738 fontSize: 0 21739 }; 21740 this.#textDivs.push(textDiv); 21741 const tx = Util.transform(this.#transform, geom.transform); 21742 let angle = Math.atan2(tx[1], tx[0]); 21743 const style = this.#styleCache[geom.fontName]; 21744 if (style.vertical) { 21745 angle += Math.PI / 2; 21746 } 21747 let fontFamily = this.#fontInspectorEnabled && style.fontSubstitution || style.fontFamily; 21748 fontFamily = TextLayer.fontFamilyMap.get(fontFamily) || fontFamily; 21749 const fontHeight = Math.hypot(tx[2], tx[3]); 21750 const fontAscent = fontHeight * TextLayer.#getAscent(fontFamily, style, this.#lang); 21751 let left, top; 21752 if (angle === 0) { 21753 left = tx[4]; 21754 top = tx[5] - fontAscent; 21755 } else { 21756 left = tx[4] + fontAscent * Math.sin(angle); 21757 top = tx[5] - fontAscent * Math.cos(angle); 21758 } 21759 const divStyle = textDiv.style; 21760 divStyle.left = `${(100 * left / this.#pageWidth).toFixed(2)}%`; 21761 divStyle.top = `${(100 * top / this.#pageHeight).toFixed(2)}%`; 21762 divStyle.setProperty("--font-height", `${fontHeight.toFixed(2)}px`); 21763 divStyle.fontFamily = fontFamily; 21764 textDivProperties.fontSize = fontHeight; 21765 textDiv.setAttribute("role", "presentation"); 21766 textDiv.textContent = geom.str; 21767 textDiv.dir = geom.dir; 21768 if (this.#fontInspectorEnabled) { 21769 textDiv.dataset.fontName = style.fontSubstitutionLoadedName || geom.fontName; 21770 } 21771 if (angle !== 0) { 21772 textDivProperties.angle = angle * (180 / Math.PI); 21773 } 21774 let shouldScaleText = false; 21775 if (geom.str.length > 1) { 21776 shouldScaleText = true; 21777 } else if (geom.str !== " " && geom.transform[0] !== geom.transform[3]) { 21778 const absScaleX = Math.abs(geom.transform[0]), 21779 absScaleY = Math.abs(geom.transform[3]); 21780 if (absScaleX !== absScaleY && Math.max(absScaleX, absScaleY) / Math.min(absScaleX, absScaleY) > 1.5) { 21781 shouldScaleText = true; 21782 } 21783 } 21784 if (shouldScaleText) { 21785 textDivProperties.canvasWidth = style.vertical ? geom.height : geom.width; 21786 } 21787 this.#textDivProperties.set(textDiv, textDivProperties); 21788 this.#layoutTextParams.div = textDiv; 21789 this.#layoutTextParams.properties = textDivProperties; 21790 this.#layout(this.#layoutTextParams); 21791 if (textDivProperties.hasText) { 21792 this.#container.append(textDiv); 21793 } 21794 if (textDivProperties.hasEOL) { 21795 const br = document.createElement("br"); 21796 br.setAttribute("role", "presentation"); 21797 this.#container.append(br); 21798 } 21799 } 21800 #layout(params) { 21801 const { 21802 div, 21803 properties, 21804 ctx 21805 } = params; 21806 const { 21807 style 21808 } = div; 21809 if (properties.canvasWidth !== 0 && properties.hasText) { 21810 const { 21811 fontFamily 21812 } = style; 21813 const { 21814 canvasWidth, 21815 fontSize 21816 } = properties; 21817 TextLayer.#ensureCtxFont(ctx, fontSize * this.#scale, fontFamily); 21818 const { 21819 width 21820 } = ctx.measureText(div.textContent); 21821 if (width > 0) { 21822 style.setProperty("--scale-x", canvasWidth * this.#scale / width); 21823 } 21824 } 21825 if (properties.angle !== 0) { 21826 style.setProperty("--rotate", `${properties.angle}deg`); 21827 } 21828 } 21829 static cleanup() { 21830 if (this.#pendingTextLayers.size > 0) { 21831 return; 21832 } 21833 this.#ascentCache.clear(); 21834 for (const { 21835 canvas 21836 } of this.#canvasContexts.values()) { 21837 canvas.remove(); 21838 } 21839 this.#canvasContexts.clear(); 21840 } 21841 static #getCtx(lang = null) { 21842 let ctx = this.#canvasContexts.get(lang ||= ""); 21843 if (!ctx) { 21844 const canvas = document.createElement("canvas"); 21845 canvas.style.cssText = "position:absolute;top:0;left:0;width:0;height:0;display:none;" + "letter-spacing:normal;word-spacing:normal"; 21846 canvas.lang = lang; 21847 document.body.append(canvas); 21848 ctx = canvas.getContext("2d", { 21849 alpha: false, 21850 willReadFrequently: true 21851 }); 21852 this.#canvasContexts.set(lang, ctx); 21853 this.#canvasCtxFonts.set(ctx, { 21854 size: 0, 21855 family: "" 21856 }); 21857 } 21858 return ctx; 21859 } 21860 static #ensureCtxFont(ctx, size, family) { 21861 const cached = this.#canvasCtxFonts.get(ctx); 21862 if (size === cached.size && family === cached.family) { 21863 return; 21864 } 21865 ctx.font = `${size}px ${family}`; 21866 cached.size = size; 21867 cached.family = family; 21868 } 21869 static #ensureMinFontSizeComputed() { 21870 if (this.#minFontSize !== null) { 21871 return; 21872 } 21873 const div = document.createElement("div"); 21874 div.style.opacity = 0; 21875 div.style.lineHeight = 1; 21876 div.style.fontSize = "1px"; 21877 div.style.position = "absolute"; 21878 div.textContent = "X"; 21879 document.body.append(div); 21880 this.#minFontSize = div.getBoundingClientRect().height; 21881 div.remove(); 21882 } 21883 static #getAscent(fontFamily, style, lang) { 21884 const cachedAscent = this.#ascentCache.get(fontFamily); 21885 if (cachedAscent) { 21886 return cachedAscent; 21887 } 21888 const ctx = this.#getCtx(lang); 21889 ctx.canvas.width = ctx.canvas.height = DEFAULT_FONT_SIZE; 21890 this.#ensureCtxFont(ctx, DEFAULT_FONT_SIZE, fontFamily); 21891 const metrics = ctx.measureText(""); 21892 const ascent = metrics.fontBoundingBoxAscent; 21893 const descent = Math.abs(metrics.fontBoundingBoxDescent); 21894 ctx.canvas.width = ctx.canvas.height = 0; 21895 let ratio = 0.8; 21896 if (ascent) { 21897 ratio = ascent / (ascent + descent); 21898 } else { 21899 if (FeatureTest.platform.isFirefox) { 21900 warn("Enable the `dom.textMetrics.fontBoundingBox.enabled` preference " + "in `about:config` to improve TextLayer rendering."); 21901 } 21902 if (style.ascent) { 21903 ratio = style.ascent; 21904 } else if (style.descent) { 21905 ratio = 1 + style.descent; 21906 } 21907 } 21908 this.#ascentCache.set(fontFamily, ratio); 21909 return ratio; 21910 } 21911} 21912 21913;// ./src/display/api.js 21914 21915 21916 21917 21918 21919 21920 21921 21922 21923 21924 21925 21926 21927 21928 21929 21930 21931 21932 21933 21934 21935 21936 21937 21938 21939 21940 21941 21942 21943 21944 21945 21946 21947 21948 21949 21950 21951 21952 21953 21954 21955 21956 21957 21958 21959 21960 21961const RENDERING_CANCELLED_TIMEOUT = 100; 21962function getDocument(src = {}) { 21963 const task = new PDFDocumentLoadingTask(); 21964 const { 21965 docId 21966 } = task; 21967 const url = src.url ? getUrlProp(src.url) : null; 21968 const data = src.data ? getDataProp(src.data) : null; 21969 const httpHeaders = src.httpHeaders || null; 21970 const withCredentials = src.withCredentials === true; 21971 const password = src.password ?? null; 21972 const rangeTransport = src.range instanceof PDFDataRangeTransport ? src.range : null; 21973 const rangeChunkSize = Number.isInteger(src.rangeChunkSize) && src.rangeChunkSize > 0 ? src.rangeChunkSize : 2 ** 16; 21974 let worker = src.worker instanceof PDFWorker ? src.worker : null; 21975 const verbosity = src.verbosity; 21976 const docBaseUrl = typeof src.docBaseUrl === "string" && !isDataScheme(src.docBaseUrl) ? src.docBaseUrl : null; 21977 const cMapUrl = getFactoryUrlProp(src.cMapUrl); 21978 const cMapPacked = src.cMapPacked !== false; 21979 const iccUrl = getFactoryUrlProp(src.iccUrl); 21980 const standardFontDataUrl = getFactoryUrlProp(src.standardFontDataUrl); 21981 const wasmUrl = getFactoryUrlProp(src.wasmUrl); 21982 const ignoreErrors = src.stopAtErrors !== true; 21983 const maxImageSize = Number.isInteger(src.maxImageSize) && src.maxImageSize > -1 ? src.maxImageSize : -1; 21984 const isOffscreenCanvasSupported = typeof src.isOffscreenCanvasSupported === "boolean" ? src.isOffscreenCanvasSupported : !isNodeJS; 21985 const isImageDecoderSupported = typeof src.isImageDecoderSupported === "boolean" ? src.isImageDecoderSupported : !isNodeJS; 21986 const canvasMaxAreaInBytes = Number.isInteger(src.canvasMaxAreaInBytes) ? src.canvasMaxAreaInBytes : -1; 21987 const disableFontFace = typeof src.disableFontFace === "boolean" ? src.disableFontFace : isNodeJS; 21988 const fontExtraProperties = src.fontExtraProperties === true; 21989 const enableXfa = src.enableXfa === true; 21990 const ownerDocument = src.ownerDocument || globalThis.document; 21991 const disableRange = src.disableRange === true; 21992 const disableStream = src.disableStream === true; 21993 const disableAutoFetch = src.disableAutoFetch === true; 21994 const pdfBug = src.pdfBug === true; 21995 const CanvasFactory = src.CanvasFactory || (isNodeJS ? NodeCanvasFactory : DOMCanvasFactory); 21996 const FilterFactory = src.FilterFactory || (isNodeJS ? NodeFilterFactory : DOMFilterFactory); 21997 const BinaryDataFactory = src.BinaryDataFactory || (isNodeJS ? NodeBinaryDataFactory : DOMBinaryDataFactory); 21998 const enableHWA = src.enableHWA === true; 21999 const enableWebGPU = src.enableWebGPU === true; 22000 const gpuPromise = enableWebGPU ? initGPU() : Promise.resolve(false); 22001 const useWasm = src.useWasm !== false; 22002 const pagesMapper = src.pagesMapper || new PagesMapper(); 22003 const useSystemFonts = typeof src.useSystemFonts === "boolean" ? src.useSystemFonts : !isNodeJS && !disableFontFace; 22004 const useWorkerFetch = typeof src.useWorkerFetch === "boolean" ? src.useWorkerFetch : !!(BinaryDataFactory === DOMBinaryDataFactory && cMapUrl && cMapPacked && standardFontDataUrl && wasmUrl && isValidFetchUrl(cMapUrl, document.baseURI) && isValidFetchUrl(standardFontDataUrl, document.baseURI) && isValidFetchUrl(wasmUrl, document.baseURI)); 22005 const styleElement = null; 22006 setVerbosityLevel(verbosity); 22007 const transportFactory = { 22008 canvasFactory: new CanvasFactory({ 22009 ownerDocument, 22010 enableHWA 22011 }), 22012 filterFactory: new FilterFactory({ 22013 docId, 22014 ownerDocument 22015 }), 22016 binaryDataFactory: useWorkerFetch ? null : new BinaryDataFactory({ 22017 cMapUrl, 22018 standardFontDataUrl, 22019 wasmUrl 22020 }) 22021 }; 22022 if (!worker) { 22023 worker = PDFWorker.create({ 22024 verbosity, 22025 port: GlobalWorkerOptions.workerPort 22026 }); 22027 task._worker = worker; 22028 } 22029 const docParams = { 22030 docId, 22031 apiVersion: "6.3.289", 22032 data, 22033 password, 22034 disableAutoFetch, 22035 rangeChunkSize, 22036 docBaseUrl, 22037 enableXfa, 22038 evaluatorOptions: { 22039 maxImageSize, 22040 disableFontFace, 22041 ignoreErrors, 22042 isOffscreenCanvasSupported, 22043 isImageDecoderSupported, 22044 canvasMaxAreaInBytes, 22045 fontExtraProperties, 22046 useSystemFonts, 22047 useWasm, 22048 useWorkerFetch, 22049 cMapUrl, 22050 cMapPacked, 22051 iccUrl, 22052 standardFontDataUrl, 22053 wasmUrl, 22054 hasGPU: false 22055 } 22056 }; 22057 const transportParams = { 22058 ownerDocument, 22059 pdfBug, 22060 styleElement, 22061 enableHWA, 22062 loadingParams: { 22063 disableAutoFetch, 22064 enableXfa 22065 } 22066 }; 22067 Promise.all([worker.promise, gpuPromise]).then(function ([, hasGPU]) { 22068 if (worker.destroyed) { 22069 throw new Error("Worker was destroyed"); 22070 } 22071 docParams.evaluatorOptions.hasGPU = hasGPU; 22072 const workerIdPromise = worker.messageHandler.sendWithPromise("GetDocRequest", docParams, data ? [data.buffer] : null); 22073 let networkStream; 22074 if (data) {} else if (rangeTransport) { 22075 networkStream = new PDFDataTransportStream({ 22076 pdfDataRangeTransport: rangeTransport, 22077 disableRange, 22078 disableStream 22079 }); 22080 } else if (url) { 22081 const NetworkStream = getNetworkStream(url); 22082 networkStream = new NetworkStream({ 22083 url, 22084 httpHeaders, 22085 withCredentials, 22086 rangeChunkSize, 22087 disableRange, 22088 disableStream 22089 }); 22090 } else { 22091 throw new Error("getDocument - expected either `data`, `range`, or `url` parameter."); 22092 } 22093 return workerIdPromise.then(workerId => { 22094 if (worker.destroyed) { 22095 throw new Error("Worker was destroyed"); 22096 } 22097 const messageHandler = new MessageHandler(docId, workerId, worker.port); 22098 const transport = new WorkerTransport(messageHandler, task, networkStream, transportParams, transportFactory, pagesMapper); 22099 task._transport = transport; 22100 if (task.destroyed) { 22101 throw new Error("Loading aborted"); 22102 } 22103 messageHandler.send("Ready", null); 22104 }); 22105 }).catch(task._capability.reject).finally(task._setupCapability.resolve); 22106 return task; 22107} 22108class PDFDocumentLoadingTask { 22109 static #docId = 0; 22110 _capability = Promise.withResolvers(); 22111 _setupCapability = Promise.withResolvers(); 22112 _transport = null; 22113 _worker = null; 22114 docId = `d${PDFDocumentLoadingTask.#docId++}`; 22115 destroyed = false; 22116 onPassword = null; 22117 onProgress = null; 22118 get promise() { 22119 return this._capability.promise; 22120 } 22121 async destroy() { 22122 this.destroyed = true; 22123 this._capability.promise.catch(() => {}); 22124 try { 22125 if (this._worker?.port) { 22126 this._worker._pendingDestroy = true; 22127 } 22128 await this._setupCapability.promise; 22129 await this._transport?.destroy(); 22130 } catch (ex) { 22131 if (this._worker?.port) { 22132 delete this._worker._pendingDestroy; 22133 } 22134 throw ex; 22135 } 22136 this._transport = null; 22137 this._worker?.destroy(); 22138 this._worker = null; 22139 } 22140 async getData() { 22141 return this._transport.getData(); 22142 } 22143} 22144class PDFDataRangeTransport { 22145 #capability = Promise.withResolvers(); 22146 #listener = null; 22147 constructor(length, initialData, progressiveDone = false, contentDispositionFilename = null) { 22148 this.length = length; 22149 this.initialData = initialData; 22150 this.progressiveDone = progressiveDone; 22151 this.contentDispositionFilename = contentDispositionFilename; 22152 } 22153 onDataRange(begin, chunk) { 22154 this.#listener({ 22155 type: "range", 22156 begin, 22157 chunk 22158 }); 22159 } 22160 onDataProgressiveRead(chunk) { 22161 this.#capability.promise.then(() => { 22162 this.#listener({ 22163 type: "progressiveRead", 22164 chunk 22165 }); 22166 }); 22167 } 22168 onDataProgressiveDone() { 22169 this.#capability.promise.then(() => { 22170 this.#listener({ 22171 type: "progressiveDone" 22172 }); 22173 }); 22174 } 22175 transportReady(listener) { 22176 this.#listener = listener; 22177 this.#capability.resolve(); 22178 } 22179 requestDataRange(begin, end) { 22180 unreachable("Abstract method PDFDataRangeTransport.requestDataRange"); 22181 } 22182 abort() {} 22183} 22184class PDFDocumentProxy { 22185 constructor(pdfInfo, transport) { 22186 this._pdfInfo = pdfInfo; 22187 this._transport = transport; 22188 } 22189 get pagesMapper() { 22190 return this._transport.pagesMapper; 22191 } 22192 get annotationStorage() { 22193 return this._transport.annotationStorage; 22194 } 22195 get canvasFactory() { 22196 return this._transport.canvasFactory; 22197 } 22198 get filterFactory() { 22199 return this._transport.filterFactory; 22200 } 22201 get numPages() { 22202 return this._pdfInfo.numPages; 22203 } 22204 get fingerprints() { 22205 return this._pdfInfo.fingerprints; 22206 } 22207 get isPureXfa() { 22208 return shadow(this, "isPureXfa", !!this._transport._htmlForXfa); 22209 } 22210 get allXfaHtml() { 22211 return this._transport._htmlForXfa; 22212 } 22213 getPage(pageNumber) { 22214 return this._transport.getPage(pageNumber); 22215 } 22216 getPageIndex(ref) { 22217 return this._transport.getPageIndex(ref); 22218 } 22219 getDestinations() { 22220 return this._transport.getDestinations(); 22221 } 22222 getDestination(id) { 22223 return this._transport.getDestination(id); 22224 } 22225 getPageLabels() { 22226 return this._transport.getPageLabels(); 22227 } 22228 getPageLayout() { 22229 return this._transport.getPageLayout(); 22230 } 22231 getPageMode() { 22232 return this._transport.getPageMode(); 22233 } 22234 getViewerPreferences() { 22235 return this._transport.getViewerPreferences(); 22236 } 22237 getOpenAction() { 22238 return this._transport.getOpenAction(); 22239 } 22240 getAttachments() { 22241 return this._transport.getAttachments(); 22242 } 22243 getAttachmentContent(id) { 22244 return this._transport.getAttachmentContent(id); 22245 } 22246 getAnnotationsByType(types, pageIndexesToSkip) { 22247 return this._transport.getAnnotationsByType(types, pageIndexesToSkip); 22248 } 22249 getJSActions() { 22250 return this._transport.getDocJSActions(); 22251 } 22252 getOutline() { 22253 return this._transport.getOutline(); 22254 } 22255 getOptionalContentConfig({ 22256 intent = "display" 22257 } = {}) { 22258 const { 22259 renderingIntent 22260 } = this._transport.getRenderingIntent(intent); 22261 return this._transport.getOptionalContentConfig(renderingIntent); 22262 } 22263 getPermissions() { 22264 return this._transport.getPermissions(); 22265 } 22266 getMetadata() { 22267 return this._transport.getMetadata(); 22268 } 22269 getMarkInfo() { 22270 return this._transport.getMarkInfo(); 22271 } 22272 getData() { 22273 return this._transport.getData(); 22274 } 22275 saveDocument() { 22276 return this._transport.saveDocument(); 22277 } 22278 extractPages(pageInfos, copyLevels = null) { 22279 return this._transport.extractPages(pageInfos, copyLevels); 22280 } 22281 getDownloadInfo() { 22282 return this._transport.downloadInfoCapability.promise; 22283 } 22284 cleanup(keepLoadedFonts = false) { 22285 return this._transport.startCleanup(keepLoadedFonts || this.isPureXfa); 22286 } 22287 cachedPageNumber(ref) { 22288 return this._transport.cachedPageNumber(ref); 22289 } 22290 get loadingParams() { 22291 return this._transport.loadingParams; 22292 } 22293 get loadingTask() { 22294 return this._transport.loadingTask; 22295 } 22296 getFieldObjects() { 22297 return this._transport.getFieldObjects(); 22298 } 22299 getSignatures() { 22300 return this._transport.getSignatures(); 22301 } 22302 getSignatureData(id) { 22303 return this._transport.getSignatureData(id); 22304 } 22305 hasJSActions() { 22306 return this._transport.hasJSActions(); 22307 } 22308 getCalculationOrderIds() { 22309 return this._transport.getCalculationOrderIds(); 22310 } 22311} 22312class PDFPageProxy { 22313 #pendingCleanup = false; 22314 #pagesMapper = null; 22315 constructor(pageIndex, pageInfo, transport, pagesMapper, pdfBug = false) { 22316 this._pageIndex = pageIndex; 22317 this._pageInfo = pageInfo; 22318 this._transport = transport; 22319 this._stats = pdfBug ? new StatTimer() : null; 22320 this._pdfBug = pdfBug; 22321 this.commonObjs = transport.commonObjs; 22322 this.objs = new PDFObjects(); 22323 this._intentStates = new Map(); 22324 this.destroyed = false; 22325 this.recordedBBoxes = null; 22326 this.#pagesMapper = pagesMapper; 22327 this.imageCoordinates = null; 22328 } 22329 clone(id) { 22330 const clone = new PDFPageProxy(id, this._pageInfo, this._transport, this.#pagesMapper, this._pdfBug); 22331 clone.clonedFromIndex = this.clonedFromIndex ?? this._pageIndex; 22332 this._transport.updatePage(clone); 22333 return clone; 22334 } 22335 get pageNumber() { 22336 return this._pageIndex + 1; 22337 } 22338 set pageNumber(value) { 22339 this._pageIndex = value - 1; 22340 this._transport.updatePage(this); 22341 } 22342 get rotate() { 22343 return this._pageInfo.rotate; 22344 } 22345 get ref() { 22346 return this._pageInfo.ref; 22347 } 22348 get userUnit() { 22349 return this._pageInfo.userUnit; 22350 } 22351 get view() { 22352 return this._pageInfo.view; 22353 } 22354 getViewport({ 22355 scale, 22356 rotation = this.rotate, 22357 offsetX = 0, 22358 offsetY = 0, 22359 dontFlip = false 22360 } = {}) { 22361 return new PageViewport({ 22362 viewBox: this.view, 22363 userUnit: this.userUnit, 22364 scale, 22365 rotation, 22366 offsetX, 22367 offsetY, 22368 dontFlip 22369 }); 22370 } 22371 getAnnotations({ 22372 intent = "display" 22373 } = {}) { 22374 const { 22375 renderingIntent 22376 } = this._transport.getRenderingIntent(intent); 22377 return this._transport.getAnnotations(this._pageIndex, renderingIntent); 22378 } 22379 getJSActions() { 22380 return this._transport.getPageJSActions(this._pageIndex); 22381 } 22382 get filterFactory() { 22383 return this._transport.filterFactory; 22384 } 22385 get isPureXfa() { 22386 return shadow(this, "isPureXfa", !!this._transport._htmlForXfa); 22387 } 22388 async getXfa() { 22389 return this._transport._htmlForXfa?.children[this._pageIndex] || null; 22390 } 22391 render({ 22392 canvasContext, 22393 canvas = canvasContext.canvas, 22394 viewport, 22395 intent = "display", 22396 annotationMode = AnnotationMode.ENABLE, 22397 transform = null, 22398 background = null, 22399 optionalContentConfigPromise = null, 22400 annotationCanvasMap = null, 22401 pageColors = null, 22402 printAnnotationStorage = null, 22403 isEditing = false, 22404 recordImages = false, 22405 recordOperations = false, 22406 operationsFilter = null 22407 }) { 22408 this._stats?.time("Overall"); 22409 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, isEditing); 22410 const { 22411 renderingIntent, 22412 cacheKey 22413 } = intentArgs; 22414 this.#pendingCleanup = false; 22415 optionalContentConfigPromise ||= this._transport.getOptionalContentConfig(renderingIntent); 22416 const intentState = this._intentStates.getOrInsertComputed(cacheKey, makeObj); 22417 if (intentState.streamReaderCancelTimeout) { 22418 clearTimeout(intentState.streamReaderCancelTimeout); 22419 intentState.streamReaderCancelTimeout = null; 22420 } 22421 const intentPrint = !!(renderingIntent & RenderingIntentFlag.PRINT); 22422 if (!intentState.displayReadyCapability) { 22423 intentState.displayReadyCapability = Promise.withResolvers(); 22424 intentState.operatorList = { 22425 fnArray: [], 22426 argsArray: [], 22427 lastChunk: false, 22428 separateAnnots: null 22429 }; 22430 this._stats?.time("Page Request"); 22431 this._pumpOperatorList(intentArgs); 22432 } 22433 const recordForDebugger = !!(this._pdfBug && globalThis.StepperManager?.enabled); 22434 const shouldRecordOperations = !!canvas && !this.recordedBBoxes && (recordOperations || recordForDebugger); 22435 const shouldRecordImages = !!canvas && !this.imageCoordinates && recordImages; 22436 const complete = error => { 22437 intentState.renderTasks.delete(internalRenderTask); 22438 if (shouldRecordOperations) { 22439 const recordedBBoxes = internalRenderTask.gfx?.dependencyTracker.take(); 22440 if (recordedBBoxes) { 22441 internalRenderTask.stepper?.setOperatorBBoxes(recordedBBoxes, internalRenderTask.gfx.dependencyTracker.takeDebugMetadata()); 22442 if (recordOperations) { 22443 this.recordedBBoxes = recordedBBoxes; 22444 } 22445 } 22446 } 22447 if (shouldRecordImages && !error) { 22448 this.imageCoordinates = internalRenderTask.gfx?.imagesTracker.take(); 22449 } 22450 if (intentPrint) { 22451 this.#pendingCleanup = true; 22452 } 22453 this.#tryCleanup(); 22454 if (error) { 22455 internalRenderTask.capability.reject(error); 22456 this._abortOperatorList({ 22457 intentState, 22458 reason: error instanceof Error ? error : new Error(error) 22459 }); 22460 } else { 22461 internalRenderTask.capability.resolve(); 22462 } 22463 if (this._stats) { 22464 this._stats.timeEnd("Rendering"); 22465 this._stats.timeEnd("Overall"); 22466 if (globalThis.Stats?.enabled) { 22467 globalThis.Stats.add(this.pageNumber, this._stats); 22468 } 22469 } 22470 }; 22471 let dependencyTracker = null; 22472 let bboxTracker = null; 22473 if (shouldRecordOperations || shouldRecordImages) { 22474 bboxTracker = new CanvasBBoxTracker(canvas, intentState.operatorList.length); 22475 } 22476 if (shouldRecordOperations) { 22477 dependencyTracker = new CanvasDependencyTracker(bboxTracker, recordForDebugger); 22478 } 22479 const internalRenderTask = new InternalRenderTask({ 22480 callback: complete, 22481 params: { 22482 canvas, 22483 canvasContext, 22484 dependencyTracker: dependencyTracker ?? bboxTracker, 22485 imagesTracker: shouldRecordImages ? new CanvasImagesTracker(canvas) : null, 22486 viewport, 22487 transform, 22488 background 22489 }, 22490 objs: this.objs, 22491 commonObjs: this.commonObjs, 22492 annotationCanvasMap, 22493 operatorList: intentState.operatorList, 22494 pageIndex: this._pageIndex, 22495 canvasFactory: this._transport.canvasFactory, 22496 filterFactory: this._transport.filterFactory, 22497 useRequestAnimationFrame: !intentPrint, 22498 pdfBug: this._pdfBug, 22499 pageColors, 22500 enableHWA: this._transport.enableHWA, 22501 operationsFilter 22502 }); 22503 (intentState.renderTasks ||= new Set()).add(internalRenderTask); 22504 const renderTask = internalRenderTask.task; 22505 Promise.all([intentState.displayReadyCapability.promise, optionalContentConfigPromise]).then(([transparency, optionalContentConfig]) => { 22506 if (this.destroyed) { 22507 complete(); 22508 return; 22509 } 22510 this._stats?.time("Rendering"); 22511 if (!(optionalContentConfig.renderingIntent & renderingIntent)) { 22512 throw new Error("Must use the same `intent`-argument when calling the `PDFPageProxy.render` " + "and `PDFDocumentProxy.getOptionalContentConfig` methods."); 22513 } 22514 internalRenderTask.initializeGraphics({ 22515 transparency, 22516 optionalContentConfig 22517 }); 22518 internalRenderTask.operatorListChanged(); 22519 }).catch(complete); 22520 return renderTask; 22521 } 22522 getOperatorList({ 22523 intent = "display", 22524 annotationMode = AnnotationMode.ENABLE, 22525 printAnnotationStorage = null, 22526 isEditing = false 22527 } = {}) { 22528 function operatorListChanged() { 22529 if (intentState.operatorList.lastChunk) { 22530 intentState.opListReadCapability.resolve(intentState.operatorList); 22531 intentState.renderTasks.delete(opListTask); 22532 } 22533 } 22534 const intentArgs = this._transport.getRenderingIntent(intent, annotationMode, printAnnotationStorage, isEditing, true); 22535 const intentState = this._intentStates.getOrInsertComputed(intentArgs.cacheKey, makeObj); 22536 let opListTask; 22537 if (!intentState.opListReadCapability) { 22538 opListTask = Object.create(null); 22539 opListTask.operatorListChanged = operatorListChanged; 22540 intentState.opListReadCapability = Promise.withResolvers(); 22541 (intentState.renderTasks ||= new Set()).add(opListTask); 22542 intentState.operatorList = { 22543 fnArray: [], 22544 argsArray: [], 22545 lastChunk: false, 22546 separateAnnots: null 22547 }; 22548 this._stats?.time("Page Request"); 22549 this._pumpOperatorList(intentArgs); 22550 } 22551 return intentState.opListReadCapability.promise; 22552 } 22553 streamTextContent({ 22554 includeMarkedContent = false, 22555 disableNormalization = false 22556 } = {}) { 22557 const TEXT_CONTENT_CHUNK_SIZE = 100; 22558 return this._transport.messageHandler.sendWithStream("GetTextContent", { 22559 pageId: this.#pagesMapper.getPageId(this._pageIndex + 1) - 1, 22560 pageIndex: this._pageIndex, 22561 includeMarkedContent: includeMarkedContent === true, 22562 disableNormalization: disableNormalization === true 22563 }, { 22564 highWaterMark: TEXT_CONTENT_CHUNK_SIZE, 22565 size(textContent) { 22566 return textContent.items.length; 22567 } 22568 }); 22569 } 22570 async getTextContent(params = {}) { 22571 if (this._transport._htmlForXfa) { 22572 return this.getXfa().then(xfa => XfaText.textContent(xfa)); 22573 } 22574 const readableStream = this.streamTextContent(params); 22575 const textContent = { 22576 items: [], 22577 styles: Object.create(null), 22578 lang: null 22579 }; 22580 for await (const value of readableStream) { 22581 textContent.lang ??= value.lang; 22582 Object.assign(textContent.styles, value.styles); 22583 textContent.items.push(...value.items); 22584 } 22585 return textContent; 22586 } 22587 getStructTree() { 22588 return this._transport.getStructTree(this._pageIndex); 22589 } 22590 _destroy() { 22591 this.destroyed = true; 22592 const waitOn = []; 22593 for (const intentState of this._intentStates.values()) { 22594 this._abortOperatorList({ 22595 intentState, 22596 reason: new Error("Page was destroyed."), 22597 force: true 22598 }); 22599 if (intentState.opListReadCapability) { 22600 continue; 22601 } 22602 for (const internalRenderTask of intentState.renderTasks) { 22603 waitOn.push(internalRenderTask.completed); 22604 internalRenderTask.cancel(); 22605 } 22606 } 22607 this.objs.clear(); 22608 this.#pendingCleanup = false; 22609 return Promise.all(waitOn); 22610 } 22611 cleanup(resetStats = false) { 22612 this.#pendingCleanup = true; 22613 const success = this.#tryCleanup(); 22614 if (resetStats && success) { 22615 this._stats &&= new StatTimer(); 22616 } 22617 return success; 22618 } 22619 #tryCleanup() { 22620 if (!this.#pendingCleanup || this.destroyed) { 22621 return false; 22622 } 22623 for (const { 22624 renderTasks, 22625 operatorList 22626 } of this._intentStates.values()) { 22627 if (renderTasks.size > 0 || !operatorList.lastChunk) { 22628 return false; 22629 } 22630 } 22631 this._intentStates.clear(); 22632 this.objs.clear(); 22633 this.#pendingCleanup = false; 22634 return true; 22635 } 22636 _startRenderPage(transparency, cacheKey) { 22637 const intentState = this._intentStates.get(cacheKey); 22638 if (!intentState) { 22639 return; 22640 } 22641 this._stats?.timeEnd("Page Request"); 22642 intentState.displayReadyCapability?.resolve(transparency); 22643 } 22644 _renderPageChunk(operatorListChunk, intentState) { 22645 for (let i = 0, ii = operatorListChunk.length; i < ii; i++) { 22646 intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); 22647 intentState.operatorList.argsArray.push(operatorListChunk.argsArray[i]); 22648 } 22649 intentState.operatorList.lastChunk = operatorListChunk.lastChunk; 22650 intentState.operatorList.separateAnnots = operatorListChunk.separateAnnots; 22651 for (const internalRenderTask of intentState.renderTasks) { 22652 internalRenderTask.operatorListChanged(); 22653 } 22654 if (operatorListChunk.lastChunk) { 22655 this.#tryCleanup(); 22656 } 22657 } 22658 _pumpOperatorList({ 22659 renderingIntent, 22660 cacheKey, 22661 annotationStorageSerializable, 22662 modifiedIds 22663 }) { 22664 const { 22665 map, 22666 transfer 22667 } = annotationStorageSerializable; 22668 const readableStream = this._transport.messageHandler.sendWithStream("GetOperatorList", { 22669 pageId: this.#pagesMapper.getPageId(this._pageIndex + 1) - 1, 22670 pageIndex: this._pageIndex, 22671 intent: renderingIntent, 22672 cacheKey, 22673 annotationStorage: map, 22674 modifiedIds 22675 }, undefined, transfer); 22676 const reader = readableStream.getReader(); 22677 const intentState = this._intentStates.get(cacheKey); 22678 intentState.streamReader = reader; 22679 const pump = () => { 22680 reader.read().then(({ 22681 value, 22682 done 22683 }) => { 22684 if (done) { 22685 intentState.streamReader = null; 22686 return; 22687 } 22688 if (this._transport.destroyed) { 22689 return; 22690 } 22691 this._renderPageChunk(value, intentState); 22692 pump(); 22693 }, reason => { 22694 intentState.streamReader = null; 22695 if (this._transport.destroyed) { 22696 return; 22697 } 22698 if (intentState.operatorList) { 22699 intentState.operatorList.lastChunk = true; 22700 for (const internalRenderTask of intentState.renderTasks) { 22701 internalRenderTask.operatorListChanged(); 22702 } 22703 this.#tryCleanup(); 22704 } 22705 if (intentState.displayReadyCapability) { 22706 intentState.displayReadyCapability.reject(reason); 22707 } else if (intentState.opListReadCapability) { 22708 intentState.opListReadCapability.reject(reason); 22709 } else { 22710 throw reason; 22711 } 22712 }); 22713 }; 22714 pump(); 22715 } 22716 _abortOperatorList({ 22717 intentState, 22718 reason, 22719 force = false 22720 }) { 22721 if (!intentState.streamReader) { 22722 return; 22723 } 22724 if (intentState.streamReaderCancelTimeout) { 22725 clearTimeout(intentState.streamReaderCancelTimeout); 22726 intentState.streamReaderCancelTimeout = null; 22727 } 22728 if (!force) { 22729 if (intentState.renderTasks.size > 0) { 22730 return; 22731 } 22732 if (reason instanceof RenderingCancelledException) { 22733 let delay = RENDERING_CANCELLED_TIMEOUT; 22734 if (reason.extraDelay > 0 && reason.extraDelay < 1000) { 22735 delay += reason.extraDelay; 22736 } 22737 intentState.streamReaderCancelTimeout = setTimeout(() => { 22738 intentState.streamReaderCancelTimeout = null; 22739 this._abortOperatorList({ 22740 intentState, 22741 reason, 22742 force: true 22743 }); 22744 }, delay); 22745 return; 22746 } 22747 } 22748 intentState.streamReader.cancel(new AbortException(reason.message)).catch(() => {}); 22749 intentState.streamReader = null; 22750 if (this._transport.destroyed) { 22751 return; 22752 } 22753 for (const [curCacheKey, curIntentState] of this._intentStates) { 22754 if (curIntentState === intentState) { 22755 this._intentStates.delete(curCacheKey); 22756 break; 22757 } 22758 } 22759 this.cleanup(); 22760 } 22761 get stats() { 22762 return this._stats; 22763 } 22764} 22765class PDFWorker { 22766 #capability = Promise.withResolvers(); 22767 #messageHandler = null; 22768 #port = null; 22769 #webWorker = null; 22770 static #fakeWorkerId = 0; 22771 static #isWorkerDisabled = false; 22772 static #workerPorts = new WeakMap(); 22773 static { 22774 if (isNodeJS) { 22775 this.#isWorkerDisabled = true; 22776 GlobalWorkerOptions.workerSrc ||= "./pdf.worker.mjs"; 22777 } 22778 this._isSameOrigin = (baseUrl, otherUrl) => { 22779 const base = URL.parse(baseUrl); 22780 if (!base?.origin || base.origin === "null") { 22781 return false; 22782 } 22783 const other = new URL(otherUrl, base); 22784 return base.origin === other.origin; 22785 }; 22786 this._createCDNWrapper = url => { 22787 const wrapper = `await import("${url}");`; 22788 return URL.createObjectURL(new Blob([wrapper], { 22789 type: "text/javascript" 22790 })); 22791 }; 22792 } 22793 constructor({ 22794 name = null, 22795 port = null, 22796 verbosity = getVerbosityLevel() 22797 } = {}) { 22798 this.name = name; 22799 this.destroyed = false; 22800 this.verbosity = verbosity; 22801 if (port) { 22802 if (PDFWorker.#workerPorts.has(port)) { 22803 throw new Error("Cannot use more than one PDFWorker per port."); 22804 } 22805 PDFWorker.#workerPorts.set(port, this); 22806 this.#initializeFromPort(port); 22807 } else { 22808 this.#initialize(); 22809 } 22810 } 22811 get promise() { 22812 return this.#capability.promise; 22813 } 22814 #resolve() { 22815 this.#capability.resolve(); 22816 this.#messageHandler.send("configure", { 22817 verbosity: this.verbosity 22818 }); 22819 } 22820 get port() { 22821 return this.#port; 22822 } 22823 get messageHandler() { 22824 return this.#messageHandler; 22825 } 22826 #initializeFromPort(port) { 22827 this.#port = port; 22828 this.#messageHandler = new MessageHandler("main", "worker", port); 22829 this.#messageHandler.on("ready", () => {}); 22830 this.#resolve(); 22831 } 22832 #initialize() { 22833 if (PDFWorker.#isWorkerDisabled || PDFWorker.#mainThreadWorkerMessageHandler) { 22834 this.#setupFakeWorker(); 22835 return; 22836 } 22837 let { 22838 workerSrc 22839 } = PDFWorker; 22840 try { 22841 if (!PDFWorker._isSameOrigin(window.location, workerSrc)) { 22842 workerSrc = PDFWorker._createCDNWrapper(new URL(workerSrc, window.location).href); 22843 } 22844 const worker = new Worker(workerSrc, { 22845 type: "module" 22846 }); 22847 const messageHandler = new MessageHandler("main", "worker", worker); 22848 const terminateEarly = () => { 22849 ac.abort(); 22850 messageHandler.destroy(); 22851 worker.terminate(); 22852 if (this.destroyed) { 22853 this.#capability.reject(new Error("Worker was destroyed")); 22854 } else { 22855 this.#setupFakeWorker(); 22856 } 22857 }; 22858 const ac = new AbortController(); 22859 worker.addEventListener("error", () => { 22860 if (!this.#webWorker) { 22861 terminateEarly(); 22862 } 22863 }, { 22864 signal: ac.signal 22865 }); 22866 messageHandler.on("test", data => { 22867 ac.abort(); 22868 if (this.destroyed || !data) { 22869 terminateEarly(); 22870 return; 22871 } 22872 this.#messageHandler = messageHandler; 22873 this.#port = worker; 22874 this.#webWorker = worker; 22875 this.#resolve(); 22876 }); 22877 messageHandler.on("ready", data => { 22878 ac.abort(); 22879 if (this.destroyed) { 22880 terminateEarly(); 22881 return; 22882 } 22883 try { 22884 sendTest(); 22885 } catch { 22886 this.#setupFakeWorker(); 22887 } 22888 }); 22889 const sendTest = () => { 22890 const testObj = new Uint8Array(); 22891 messageHandler.send("test", testObj, [testObj.buffer]); 22892 }; 22893 sendTest(); 22894 return; 22895 } catch { 22896 info("The worker has been disabled."); 22897 } 22898 this.#setupFakeWorker(); 22899 } 22900 #setupFakeWorker() { 22901 if (!PDFWorker.#isWorkerDisabled) { 22902 warn("Setting up fake worker."); 22903 PDFWorker.#isWorkerDisabled = true; 22904 } 22905 PDFWorker._setupFakeWorkerGlobal.then(WorkerMessageHandler => { 22906 if (this.destroyed) { 22907 this.#capability.reject(new Error("Worker was destroyed")); 22908 return; 22909 } 22910 const port = new LoopbackPort(); 22911 this.#port = port; 22912 const id = `fake${PDFWorker.#fakeWorkerId++}`; 22913 const workerHandler = new MessageHandler(id + "_worker", id, port); 22914 WorkerMessageHandler.setup(workerHandler, port); 22915 this.#messageHandler = new MessageHandler(id, id + "_worker", port); 22916 this.#resolve(); 22917 }).catch(reason => { 22918 this.#capability.reject(new Error(`Setting up fake worker failed: "${reason.message}".`)); 22919 }); 22920 } 22921 destroy() { 22922 this.destroyed = true; 22923 this.#webWorker?.terminate(); 22924 this.#webWorker = null; 22925 PDFWorker.#workerPorts.delete(this.#port); 22926 this.#port = null; 22927 this.#messageHandler?.destroy(); 22928 this.#messageHandler = null; 22929 } 22930 static create(params) { 22931 const cachedPort = this.#workerPorts.get(params?.port); 22932 if (cachedPort) { 22933 if (cachedPort._pendingDestroy) { 22934 throw new Error("PDFWorker.create - the worker is being destroyed.\n" + "Please remember to await `PDFDocumentLoadingTask.destroy()`-calls."); 22935 } 22936 return cachedPort; 22937 } 22938 return new PDFWorker(params); 22939 } 22940 static get workerSrc() { 22941 if (GlobalWorkerOptions.workerSrc) { 22942 return GlobalWorkerOptions.workerSrc; 22943 } 22944 throw new Error('No "GlobalWorkerOptions.workerSrc" specified.'); 22945 } 22946 static get #mainThreadWorkerMessageHandler() { 22947 try { 22948 return globalThis.pdfjsWorker?.WorkerMessageHandler || null; 22949 } catch { 22950 return null; 22951 } 22952 } 22953 static get _setupFakeWorkerGlobal() { 22954 const loader = async () => { 22955 if (this.#mainThreadWorkerMessageHandler) { 22956 return this.#mainThreadWorkerMessageHandler; 22957 } 22958 const worker = await import( 22959 /*webpackIgnore: true*/ 22960 /*@vite-ignore*/ 22961 this.workerSrc); 22962 return worker.WorkerMessageHandler; 22963 }; 22964 return shadow(this, "_setupFakeWorkerGlobal", loader()); 22965 } 22966} 22967class WorkerTransport { 22968 downloadInfoCapability = Promise.withResolvers(); 22969 #fullReader = null; 22970 #methodPromises = new Map(); 22971 #networkStream = null; 22972 #pageCache = new Map(); 22973 #pagePromises = new Map(); 22974 #pageRefCache = new Map(); 22975 #passwordCapability = null; 22976 constructor(messageHandler, loadingTask, networkStream, params, factory, pagesMapper) { 22977 this.messageHandler = messageHandler; 22978 this.loadingTask = loadingTask; 22979 this.#networkStream = networkStream; 22980 this.commonObjs = new PDFObjects(); 22981 this.fontLoader = new FontLoader({ 22982 ownerDocument: params.ownerDocument, 22983 styleElement: params.styleElement 22984 }); 22985 this.enableHWA = params.enableHWA; 22986 this.loadingParams = params.loadingParams; 22987 this._params = params; 22988 this.canvasFactory = factory.canvasFactory; 22989 this.filterFactory = factory.filterFactory; 22990 this.binaryDataFactory = factory.binaryDataFactory; 22991 this.pagesMapper = pagesMapper; 22992 this.destroyed = false; 22993 this.destroyCapability = null; 22994 this.setupMessageHandler(); 22995 } 22996 updatePage(page) { 22997 const { 22998 _pageIndex 22999 } = page; 23000 this.#pageCache.set(_pageIndex, page); 23001 this.#pagePromises.set(_pageIndex, Promise.resolve(page)); 23002 } 23003 #cacheSimpleMethod(name, data = null) { 23004 return this.#methodPromises.getOrInsertComputed(name, () => this.messageHandler.sendWithPromise(name, data)); 23005 } 23006 #onProgress({ 23007 loaded, 23008 total 23009 }) { 23010 this.loadingTask.onProgress?.({ 23011 loaded, 23012 total, 23013 percent: total ? MathClamp(Math.round(loaded / total * 100), 0, 100) : NaN 23014 }); 23015 } 23016 get annotationStorage() { 23017 return shadow(this, "annotationStorage", new AnnotationStorage()); 23018 } 23019 getRenderingIntent(intent, annotationMode = AnnotationMode.ENABLE, printAnnotationStorage = null, isEditing = false, isOpList = false) { 23020 let renderingIntent = RenderingIntentFlag.DISPLAY; 23021 let annotationStorageSerializable = SerializableEmpty; 23022 switch (intent) { 23023 case "any": 23024 renderingIntent = RenderingIntentFlag.ANY; 23025 break; 23026 case "display": 23027 break; 23028 case "print": 23029 renderingIntent = RenderingIntentFlag.PRINT; 23030 break; 23031 default: 23032 warn(`getRenderingIntent - invalid intent: ${intent}`); 23033 } 23034 const annotationStorage = renderingIntent & RenderingIntentFlag.PRINT && printAnnotationStorage instanceof PrintAnnotationStorage ? printAnnotationStorage : this.annotationStorage; 23035 switch (annotationMode) { 23036 case AnnotationMode.DISABLE: 23037 renderingIntent += RenderingIntentFlag.ANNOTATIONS_DISABLE; 23038 break; 23039 case AnnotationMode.ENABLE: 23040 break; 23041 case AnnotationMode.ENABLE_FORMS: 23042 renderingIntent += RenderingIntentFlag.ANNOTATIONS_FORMS; 23043 break; 23044 case AnnotationMode.ENABLE_STORAGE: 23045 renderingIntent += RenderingIntentFlag.ANNOTATIONS_STORAGE; 23046 annotationStorageSerializable = annotationStorage.serializable; 23047 break; 23048 default: 23049 warn(`getRenderingIntent - invalid annotationMode: ${annotationMode}`); 23050 } 23051 if (isEditing) { 23052 renderingIntent += RenderingIntentFlag.IS_EDITING; 23053 } 23054 if (isOpList) { 23055 renderingIntent += RenderingIntentFlag.OPLIST; 23056 } 23057 const { 23058 ids: modifiedIds, 23059 hash: modifiedIdsHash 23060 } = annotationStorage.modifiedIds; 23061 const cacheKeyBuf = [renderingIntent, annotationStorageSerializable.hash, modifiedIdsHash]; 23062 return { 23063 renderingIntent, 23064 cacheKey: cacheKeyBuf.join("_"), 23065 annotationStorageSerializable, 23066 modifiedIds 23067 }; 23068 } 23069 destroy() { 23070 if (this.destroyCapability) { 23071 return this.destroyCapability.promise; 23072 } 23073 this.destroyed = true; 23074 this.destroyCapability = Promise.withResolvers(); 23075 this.#passwordCapability?.reject(new Error("Worker was destroyed during onPassword callback")); 23076 const waitOn = []; 23077 for (const page of this.#pageCache.values()) { 23078 waitOn.push(page._destroy()); 23079 } 23080 this.#pageCache.clear(); 23081 this.#pagePromises.clear(); 23082 this.#pageRefCache.clear(); 23083 if (Object.hasOwn(this, "annotationStorage")) { 23084 this.annotationStorage.resetModified(); 23085 } 23086 const terminated = this.messageHandler.sendWithPromise("Terminate", null); 23087 waitOn.push(terminated); 23088 Promise.all(waitOn).then(() => { 23089 this.commonObjs.clear(); 23090 this.fontLoader.clear(); 23091 this.#methodPromises.clear(); 23092 this.filterFactory.destroy(); 23093 TextLayer.cleanup(); 23094 this.#networkStream?.cancelAllRequests(new AbortException("Worker was terminated.")); 23095 this.messageHandler?.destroy(); 23096 this.messageHandler = null; 23097 this.destroyCapability.resolve(); 23098 }, this.destroyCapability.reject); 23099 return this.destroyCapability.promise; 23100 } 23101 setupMessageHandler() { 23102 const { 23103 messageHandler, 23104 loadingTask 23105 } = this; 23106 messageHandler.on("GetReader", (data, sink) => { 23107 assert(this.#networkStream, "GetReader - no `BasePDFStream` instance available."); 23108 this.#fullReader = this.#networkStream.getFullReader(); 23109 this.#fullReader.onProgress = evt => this.#onProgress(evt); 23110 sink.onPull = () => { 23111 this.#fullReader.read().then(function ({ 23112 value, 23113 done 23114 }) { 23115 if (done) { 23116 sink.close(); 23117 return; 23118 } 23119 assert(value instanceof ArrayBuffer, "GetReader - expected an ArrayBuffer."); 23120 sink.enqueue(new Uint8Array(value), 1, [value]); 23121 }).catch(reason => { 23122 sink.error(reason); 23123 }); 23124 }; 23125 sink.onCancel = reason => { 23126 this.#fullReader.cancel(reason); 23127 sink.ready.catch(readyReason => { 23128 if (this.destroyed) { 23129 return; 23130 } 23131 throw readyReason; 23132 }); 23133 }; 23134 }); 23135 messageHandler.on("ReaderHeadersReady", async data => { 23136 await this.#fullReader.headersReady; 23137 const { 23138 isStreamingSupported, 23139 isRangeSupported, 23140 contentLength 23141 } = this.#fullReader; 23142 if (isStreamingSupported && isRangeSupported) { 23143 this.#fullReader.onProgress = null; 23144 } 23145 return { 23146 isStreamingSupported, 23147 isRangeSupported, 23148 contentLength 23149 }; 23150 }); 23151 messageHandler.on("GetRangeReader", (data, sink) => { 23152 assert(this.#networkStream, "GetRangeReader - no `BasePDFStream` instance available."); 23153 const rangeReader = this.#networkStream.getRangeReader(data.begin, data.end); 23154 if (!rangeReader) { 23155 sink.close(); 23156 return; 23157 } 23158 sink.onPull = () => { 23159 rangeReader.read().then(function ({ 23160 value, 23161 done 23162 }) { 23163 if (done) { 23164 sink.close(); 23165 return; 23166 } 23167 assert(value instanceof ArrayBuffer, "GetRangeReader - expected an ArrayBuffer."); 23168 sink.enqueue(new Uint8Array(value), 1, [value]); 23169 }).catch(reason => { 23170 sink.error(reason); 23171 }); 23172 }; 23173 sink.onCancel = reason => { 23174 rangeReader.cancel(reason); 23175 sink.ready.catch(readyReason => { 23176 if (this.destroyed) { 23177 return; 23178 } 23179 throw readyReason; 23180 }); 23181 }; 23182 }); 23183 messageHandler.on("GetDoc", ({ 23184 pdfInfo 23185 }) => { 23186 this.pagesMapper.pagesNumber = pdfInfo.numPages; 23187 this._numPages = pdfInfo.numPages; 23188 this._htmlForXfa = pdfInfo.htmlForXfa; 23189 delete pdfInfo.htmlForXfa; 23190 loadingTask._capability.resolve(new PDFDocumentProxy(pdfInfo, this)); 23191 }); 23192 messageHandler.on("DocException", ex => { 23193 loadingTask._capability.reject(wrapReason(ex)); 23194 }); 23195 messageHandler.on("PasswordRequest", ex => { 23196 this.#passwordCapability = Promise.withResolvers(); 23197 try { 23198 if (!loadingTask.onPassword) { 23199 throw wrapReason(ex); 23200 } 23201 const updatePassword = password => { 23202 if (password instanceof Error) { 23203 this.#passwordCapability.reject(password); 23204 } else { 23205 this.#passwordCapability.resolve({ 23206 password 23207 }); 23208 } 23209 }; 23210 loadingTask.onPassword(updatePassword, ex.code); 23211 } catch (err) { 23212 this.#passwordCapability.reject(err); 23213 } 23214 return this.#passwordCapability.promise; 23215 }); 23216 messageHandler.on("DataLoaded", data => { 23217 this.#onProgress({ 23218 loaded: data.length, 23219 total: data.length 23220 }); 23221 this.downloadInfoCapability.resolve(data); 23222 }); 23223 messageHandler.on("StartRenderPage", data => { 23224 if (this.destroyed) { 23225 return; 23226 } 23227 const page = this.#pageCache.get(data.pageIndex); 23228 page._startRenderPage(data.transparency, data.cacheKey); 23229 }); 23230 messageHandler.on("commonobj", ([id, type, exportedData]) => { 23231 if (this.destroyed) { 23232 return null; 23233 } 23234 if (this.commonObjs.has(id)) { 23235 return null; 23236 } 23237 switch (type) { 23238 case "Font": 23239 if ("error" in exportedData) { 23240 const exportedError = exportedData.error; 23241 warn(`Error during font loading: ${exportedError}`); 23242 this.commonObjs.resolve(id, exportedError); 23243 break; 23244 } 23245 const fontData = new FontInfo(exportedData); 23246 const inspectFont = this._params.pdfBug && globalThis.FontInspector?.enabled ? (font, url) => globalThis.FontInspector.fontAdded(font, url) : null; 23247 const font = new FontFaceObject(fontData, inspectFont, exportedData.charProcOperatorList, exportedData.extra); 23248 this.fontLoader.bind(font).catch(() => messageHandler.sendWithPromise("FontFallback", { 23249 id 23250 })).finally(() => { 23251 if (!font.fontExtraProperties) { 23252 font.clearData(); 23253 } 23254 this.commonObjs.resolve(id, font); 23255 }); 23256 break; 23257 case "CopyLocalImage": 23258 const { 23259 imageRef 23260 } = exportedData; 23261 assert(imageRef, "The imageRef must be defined."); 23262 for (const pageProxy of this.#pageCache.values()) { 23263 for (const [, data] of pageProxy.objs) { 23264 if (data?.ref !== imageRef) { 23265 continue; 23266 } 23267 if (!data.dataLen) { 23268 return null; 23269 } 23270 const copy = structuredClone(data); 23271 this.commonObjs.resolve(id, copy); 23272 return data.dataLen; 23273 } 23274 } 23275 break; 23276 case "FontPath": 23277 this.commonObjs.resolve(id, new FontPathInfo(exportedData)); 23278 break; 23279 case "Image": 23280 this.commonObjs.resolve(id, exportedData); 23281 break; 23282 case "Pattern": 23283 const pattern = new PatternInfo(exportedData); 23284 this.commonObjs.resolve(id, pattern.getIR()); 23285 break; 23286 default: 23287 throw new Error(`Got unknown common object type ${type}`); 23288 } 23289 return null; 23290 }); 23291 messageHandler.on("obj", ([id, pageIndex, type, imageData]) => { 23292 if (this.destroyed) { 23293 return; 23294 } 23295 const pageProxy = this.#pageCache.get(pageIndex); 23296 if (pageProxy.objs.has(id)) { 23297 return; 23298 } 23299 if (pageProxy._intentStates.size === 0) { 23300 imageData?.bitmap?.close(); 23301 return; 23302 } 23303 switch (type) { 23304 case "Image": 23305 case "Pattern": 23306 pageProxy.objs.resolve(id, imageData); 23307 break; 23308 default: 23309 throw new Error(`Got unknown object type ${type}`); 23310 } 23311 }); 23312 messageHandler.on("DocProgress", data => { 23313 if (this.destroyed) { 23314 return; 23315 } 23316 this.#onProgress(data); 23317 }); 23318 messageHandler.on("FetchBinaryData", async data => { 23319 if (this.destroyed) { 23320 throw new Error("Worker was destroyed."); 23321 } 23322 if (!this.binaryDataFactory) { 23323 throw new Error("`BinaryDataFactory` not initialized, see the `useWorkerFetch` parameter."); 23324 } 23325 return this.binaryDataFactory.fetch(data); 23326 }); 23327 } 23328 getData() { 23329 return this.messageHandler.sendWithPromise("GetData", null); 23330 } 23331 saveDocument() { 23332 if (this.annotationStorage.size <= 0) { 23333 warn("saveDocument called while `annotationStorage` is empty, " + "please use the getData-method instead."); 23334 } 23335 const { 23336 map, 23337 transfer 23338 } = this.annotationStorage.serializable; 23339 return this.messageHandler.sendWithPromise("SaveDocument", { 23340 isPureXfa: !!this._htmlForXfa, 23341 numPages: this._numPages, 23342 annotationStorage: map, 23343 filename: this.#fullReader?.filename ?? null 23344 }, transfer).finally(() => { 23345 this.annotationStorage.resetModified(); 23346 }); 23347 } 23348 extractPages(pageInfos, copyLevels = null) { 23349 const params = { 23350 pageInfos 23351 }; 23352 let transfer; 23353 const ImageBitmapCtor = globalThis.ImageBitmap; 23354 if (typeof ImageBitmapCtor === "function") { 23355 const infos = Array.isArray(pageInfos) ? pageInfos : [pageInfos]; 23356 for (const pageInfo of infos) { 23357 if (pageInfo?.image instanceof ImageBitmapCtor) { 23358 (transfer ||= []).push(pageInfo.image); 23359 } 23360 } 23361 } 23362 if (this.annotationStorage.size > 0) { 23363 const serialized = this.annotationStorage.serializable; 23364 let { 23365 map 23366 } = serialized; 23367 if (serialized.transfer?.length) { 23368 if (transfer) { 23369 transfer.push(...serialized.transfer); 23370 } else { 23371 transfer = serialized.transfer; 23372 } 23373 } 23374 const mapping = this.pagesMapper.getMapping(); 23375 if (mapping) { 23376 const remapped = new Map(); 23377 for (const [k, v] of map) { 23378 if (v?.pageIndex !== undefined && v.pageIndex >= 0 && v.pageIndex < mapping.length) { 23379 const copyLevel = copyLevels?.[v.pageIndex] ?? 0; 23380 const sourceIdx = mapping[v.pageIndex] - 1; 23381 if (sourceIdx !== v.pageIndex || copyLevel !== 0) { 23382 remapped.set(k, { 23383 ...v, 23384 pageIndex: sourceIdx, 23385 copyLevel 23386 }); 23387 continue; 23388 } 23389 } 23390 remapped.set(k, v); 23391 } 23392 map = remapped; 23393 } 23394 params.annotationStorage = map; 23395 } 23396 return this.messageHandler.sendWithPromise("ExtractPages", params, transfer).finally(() => { 23397 this.annotationStorage.resetModified(); 23398 }); 23399 } 23400 getPage(pageNumber) { 23401 if (!Number.isInteger(pageNumber) || pageNumber <= 0 || pageNumber > this.pagesMapper.pagesNumber) { 23402 return Promise.reject(new Error("Invalid page request.")); 23403 } 23404 const pageIndex = pageNumber - 1; 23405 const newPageIndex = this.pagesMapper.getPageId(pageNumber) - 1; 23406 const cachedPromise = this.#pagePromises.get(pageIndex); 23407 if (cachedPromise) { 23408 return cachedPromise; 23409 } 23410 const promise = this.messageHandler.sendWithPromise("GetPage", { 23411 pageIndex: newPageIndex 23412 }).then(pageInfo => { 23413 if (this.destroyed) { 23414 throw new Error("Transport destroyed"); 23415 } 23416 if (pageInfo.refStr) { 23417 this.#pageRefCache.set(pageInfo.refStr, newPageIndex); 23418 } 23419 const page = new PDFPageProxy(pageIndex, pageInfo, this, this.pagesMapper, this._params.pdfBug); 23420 this.#pageCache.set(pageIndex, page); 23421 return page; 23422 }); 23423 this.#pagePromises.set(pageIndex, promise); 23424 return promise; 23425 } 23426 async getPageIndex(ref) { 23427 if (!isRefProxy(ref)) { 23428 throw new Error("Invalid pageIndex request."); 23429 } 23430 const index = await this.messageHandler.sendWithPromise("GetPageIndex", { 23431 num: ref.num, 23432 gen: ref.gen 23433 }); 23434 const pageNumber = this.pagesMapper.getPageNumber(index + 1); 23435 if (pageNumber === 0) { 23436 throw new Error("GetPageIndex: page has been removed."); 23437 } 23438 return pageNumber - 1; 23439 } 23440 getAnnotations(pageIndex, intent) { 23441 return this.messageHandler.sendWithPromise("GetAnnotations", { 23442 pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1, 23443 intent 23444 }); 23445 } 23446 getFieldObjects() { 23447 return this.#cacheSimpleMethod("GetFieldObjects"); 23448 } 23449 getSignatures() { 23450 return this.#cacheSimpleMethod("GetSignatures"); 23451 } 23452 getSignatureData(id) { 23453 return this.messageHandler.sendWithPromise("GetSignatureData", id); 23454 } 23455 hasJSActions() { 23456 return this.#cacheSimpleMethod("HasJSActions"); 23457 } 23458 getCalculationOrderIds() { 23459 return this.messageHandler.sendWithPromise("GetCalculationOrderIds", null); 23460 } 23461 getDestinations() { 23462 return this.messageHandler.sendWithPromise("GetDestinations", null); 23463 } 23464 getDestination(id) { 23465 if (typeof id !== "string") { 23466 return Promise.reject(new Error("Invalid destination request.")); 23467 } 23468 return this.messageHandler.sendWithPromise("GetDestination", { 23469 id 23470 }); 23471 } 23472 getPageLabels() { 23473 return this.messageHandler.sendWithPromise("GetPageLabels", null); 23474 } 23475 getPageLayout() { 23476 return this.messageHandler.sendWithPromise("GetPageLayout", null); 23477 } 23478 getPageMode() { 23479 return this.messageHandler.sendWithPromise("GetPageMode", null); 23480 } 23481 getViewerPreferences() { 23482 return this.messageHandler.sendWithPromise("GetViewerPreferences", null); 23483 } 23484 getOpenAction() { 23485 return this.messageHandler.sendWithPromise("GetOpenAction", null); 23486 } 23487 getAttachments() { 23488 return this.messageHandler.sendWithPromise("GetAttachments", null); 23489 } 23490 getAttachmentContent(id) { 23491 return this.messageHandler.sendWithPromise("GetAttachmentContent", id); 23492 } 23493 getAnnotationsByType(types, pageIndexesToSkip) { 23494 return this.messageHandler.sendWithPromise("GetAnnotationsByType", { 23495 types, 23496 pageIndexesToSkip 23497 }); 23498 } 23499 getDocJSActions() { 23500 return this.#cacheSimpleMethod("GetDocJSActions"); 23501 } 23502 getPageJSActions(pageIndex) { 23503 return this.messageHandler.sendWithPromise("GetPageJSActions", { 23504 pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1 23505 }); 23506 } 23507 getStructTree(pageIndex) { 23508 return this.messageHandler.sendWithPromise("GetStructTree", { 23509 pageIndex: this.pagesMapper.getPageId(pageIndex + 1) - 1 23510 }); 23511 } 23512 getOutline() { 23513 return this.messageHandler.sendWithPromise("GetOutline", null); 23514 } 23515 getOptionalContentConfig(renderingIntent) { 23516 return this.#cacheSimpleMethod("GetOptionalContentConfig").then(data => new OptionalContentConfig(data, renderingIntent)); 23517 } 23518 getPermissions() { 23519 return this.messageHandler.sendWithPromise("GetPermissions", null); 23520 } 23521 getMetadata() { 23522 const name = "GetMetadata"; 23523 return this.#methodPromises.getOrInsertComputed(name, () => this.messageHandler.sendWithPromise(name, null).then(results => ({ 23524 info: results[0], 23525 metadata: results[1] ? new Metadata(results[1]) : null, 23526 contentDispositionFilename: this.#fullReader?.filename ?? null, 23527 contentLength: this.#fullReader?.contentLength ?? null, 23528 hasStructTree: results[2] 23529 }))); 23530 } 23531 getMarkInfo() { 23532 return this.messageHandler.sendWithPromise("GetMarkInfo", null); 23533 } 23534 async startCleanup(keepLoadedFonts = false) { 23535 if (this.destroyed) { 23536 return; 23537 } 23538 await this.messageHandler.sendWithPromise("Cleanup", null); 23539 for (const page of this.#pageCache.values()) { 23540 const cleanupSuccessful = page.cleanup(); 23541 if (!cleanupSuccessful) { 23542 throw new Error(`startCleanup: Page ${page.pageNumber} is currently rendering.`); 23543 } 23544 } 23545 this.commonObjs.clear(); 23546 if (!keepLoadedFonts) { 23547 this.fontLoader.clear(); 23548 } 23549 this.#methodPromises.clear(); 23550 this.filterFactory.destroy(true); 23551 TextLayer.cleanup(); 23552 } 23553 cachedPageNumber(ref) { 23554 if (!isRefProxy(ref)) { 23555 return null; 23556 } 23557 const refStr = ref.gen === 0 ? `${ref.num}R` : `${ref.num}R${ref.gen}`; 23558 const pageIndex = this.#pageRefCache.get(refStr); 23559 if (pageIndex >= 0) { 23560 const pageNumber = this.pagesMapper.getPageNumber(pageIndex + 1); 23561 if (pageNumber !== 0) { 23562 return pageNumber; 23563 } 23564 } 23565 return null; 23566 } 23567} 23568class RenderTask { 23569 _internalRenderTask = null; 23570 onContinue = null; 23571 onError = null; 23572 constructor(internalRenderTask) { 23573 this._internalRenderTask = internalRenderTask; 23574 } 23575 get promise() { 23576 return this._internalRenderTask.capability.promise; 23577 } 23578 cancel(extraDelay = 0) { 23579 this._internalRenderTask.cancel(null, extraDelay); 23580 } 23581 get separateAnnots() { 23582 const { 23583 separateAnnots 23584 } = this._internalRenderTask.operatorList; 23585 if (!separateAnnots) { 23586 return false; 23587 } 23588 const { 23589 annotationCanvasMap 23590 } = this._internalRenderTask; 23591 return separateAnnots.form || separateAnnots.canvas && annotationCanvasMap?.size > 0; 23592 } 23593 get imageCoordinates() { 23594 return this._internalRenderTask.imageCoordinates || null; 23595 } 23596} 23597class InternalRenderTask { 23598 #rAF = null; 23599 static #canvasInUse = new WeakSet(); 23600 constructor({ 23601 callback, 23602 params, 23603 objs, 23604 commonObjs, 23605 annotationCanvasMap, 23606 operatorList, 23607 pageIndex, 23608 canvasFactory, 23609 filterFactory, 23610 useRequestAnimationFrame = false, 23611 pdfBug = false, 23612 pageColors = null, 23613 enableHWA = false, 23614 operationsFilter = null 23615 }) { 23616 this.callback = callback; 23617 this.params = params; 23618 this.objs = objs; 23619 this.commonObjs = commonObjs; 23620 this.annotationCanvasMap = annotationCanvasMap; 23621 this.operatorListIdx = null; 23622 this.operatorList = operatorList; 23623 this._pageIndex = pageIndex; 23624 this.canvasFactory = canvasFactory; 23625 this.filterFactory = filterFactory; 23626 this._pdfBug = pdfBug; 23627 this.pageColors = pageColors; 23628 this.running = false; 23629 this.graphicsReadyCallback = null; 23630 this.graphicsReady = false; 23631 this._useRequestAnimationFrame = useRequestAnimationFrame === true && typeof window !== "undefined"; 23632 this.cancelled = false; 23633 this.capability = Promise.withResolvers(); 23634 this.task = new RenderTask(this); 23635 this._cancelBound = this.cancel.bind(this); 23636 this._continueBound = this._continue.bind(this); 23637 this._scheduleNextBound = this._scheduleNext.bind(this); 23638 this._nextBound = this._next.bind(this); 23639 this._canvas = params.canvas; 23640 this._canvasContext = params.canvas ? null : params.canvasContext; 23641 this._enableHWA = enableHWA; 23642 this._dependencyTracker = params.dependencyTracker; 23643 this._imagesTracker = params.imagesTracker; 23644 this._operationsFilter = operationsFilter; 23645 } 23646 get completed() { 23647 return this.capability.promise.catch(function () {}); 23648 } 23649 initializeGraphics({ 23650 transparency = false, 23651 optionalContentConfig 23652 }) { 23653 if (this.cancelled) { 23654 return; 23655 } 23656 if (this._canvas) { 23657 if (InternalRenderTask.#canvasInUse.has(this._canvas)) { 23658 throw new Error("Cannot use the same canvas during multiple render() operations. " + "Use different canvas or ensure previous operations were " + "cancelled or completed."); 23659 } 23660 InternalRenderTask.#canvasInUse.add(this._canvas); 23661 } 23662 if (this._pdfBug && globalThis.StepperManager?.enabled) { 23663 this.stepper = globalThis.StepperManager.create(this._pageIndex); 23664 this.stepper.init(this.operatorList); 23665 this.stepper.nextBreakPoint = this.stepper.getNextBreakPoint(); 23666 } 23667 const { 23668 viewport, 23669 transform, 23670 background, 23671 dependencyTracker, 23672 imagesTracker 23673 } = this.params; 23674 const canvasContext = this._canvasContext || this._canvas.getContext("2d", { 23675 alpha: false, 23676 willReadFrequently: !this._enableHWA 23677 }); 23678 this.gfx = new CanvasGraphics(canvasContext, this.commonObjs, this.objs, this.canvasFactory, this.filterFactory, { 23679 optionalContentConfig 23680 }, this.annotationCanvasMap, this.pageColors, dependencyTracker, imagesTracker); 23681 this.gfx.beginDrawing({ 23682 transform, 23683 viewport, 23684 transparency, 23685 background 23686 }); 23687 this.operatorListIdx = 0; 23688 this.graphicsReady = true; 23689 this.graphicsReadyCallback?.(); 23690 } 23691 cancel(error = null, extraDelay = 0) { 23692 this.running = false; 23693 this.cancelled = true; 23694 this.gfx?.endDrawing(); 23695 if (this.#rAF) { 23696 window.cancelAnimationFrame(this.#rAF); 23697 this.#rAF = null; 23698 } 23699 InternalRenderTask.#canvasInUse.delete(this._canvas); 23700 error ||= new RenderingCancelledException(`Rendering cancelled, page ${this._pageIndex + 1}`, extraDelay); 23701 this.callback(error); 23702 this.task.onError?.(error); 23703 } 23704 operatorListChanged() { 23705 if (!this.graphicsReady) { 23706 this.graphicsReadyCallback ||= this._continueBound; 23707 return; 23708 } 23709 this.gfx.dependencyTracker?.growOperationsCount(this.operatorList.fnArray.length); 23710 this.stepper?.updateOperatorList(this.operatorList); 23711 if (this.running) { 23712 return; 23713 } 23714 this._continue(); 23715 } 23716 _continue() { 23717 this.running = true; 23718 if (this.cancelled) { 23719 return; 23720 } 23721 if (this.task.onContinue) { 23722 this.task.onContinue(this._scheduleNextBound); 23723 } else { 23724 this._scheduleNext(); 23725 } 23726 } 23727 _scheduleNext() { 23728 if (this._useRequestAnimationFrame) { 23729 this.#rAF = window.requestAnimationFrame(() => { 23730 this.#rAF = null; 23731 this._nextBound().catch(this._cancelBound); 23732 }); 23733 } else { 23734 Promise.resolve().then(this._nextBound).catch(this._cancelBound); 23735 } 23736 } 23737 async _next() { 23738 if (this.cancelled) { 23739 return; 23740 } 23741 this.operatorListIdx = this.gfx.executeOperatorList(this.operatorList, this.operatorListIdx, this._continueBound, this.stepper, this._operationsFilter); 23742 if (this.operatorListIdx === this.operatorList.argsArray.length) { 23743 this.running = false; 23744 if (this.operatorList.lastChunk) { 23745 this.gfx.endDrawing(); 23746 InternalRenderTask.#canvasInUse.delete(this._canvas); 23747 this.callback(); 23748 } 23749 } 23750 } 23751} 23752const version = "6.3.289"; 23753const build = "1c8020a7d"; 23754
vendor: 12,807 bytes, lines 23755-24194
23755// EXTERNAL MODULE: ./node_modules/core-js/modules/es.math.sum-precise.js 23756var es_math_sum_precise = __webpack_require__(3068); 23757;// ./src/display/editor/color_picker.js 23758 23759 23760 23761class ColorPicker { 23762 #button = null; 23763 #buttonSwatch = null; 23764 #defaultColor; 23765 #dropdown = null; 23766 #dropdownWasFromKeyboard = false; 23767 #isMainColorPicker = false; 23768 #editor = null; 23769 #eventBus; 23770 #openDropdownAC = null; 23771 #uiManager = null; 23772 static #l10nColor = null; 23773 static get _keyboardManager() { 23774 return shadow(this, "_keyboardManager", new KeyboardManager([[["Escape"], ColorPicker.prototype._hideDropdownFromKeyboard], [["Space"], ColorPicker.prototype._colorSelectFromKeyboard], [["ArrowDown", "ArrowRight"], ColorPicker.prototype._moveToNext], [["ArrowUp", "ArrowLeft"], ColorPicker.prototype._moveToPrevious], [["Home"], ColorPicker.prototype._moveToBeginning], [["End"], ColorPicker.prototype._moveToEnd]])); 23775 } 23776 constructor({ 23777 editor = null, 23778 uiManager = null 23779 }) { 23780 if (editor) { 23781 this.#isMainColorPicker = false; 23782 this.#editor = editor; 23783 } else { 23784 this.#isMainColorPicker = true; 23785 } 23786 this.#uiManager = editor?._uiManager || uiManager; 23787 this.#eventBus = this.#uiManager._eventBus; 23788 this.#defaultColor = editor?.color?.toUpperCase() || this.#uiManager?.highlightColors.values().next().value || "#FFFF98"; 23789 ColorPicker.#l10nColor ||= Object.freeze({ 23790 blue: "pdfjs-editor-colorpicker-blue", 23791 green: "pdfjs-editor-colorpicker-green", 23792 pink: "pdfjs-editor-colorpicker-pink", 23793 red: "pdfjs-editor-colorpicker-red", 23794 yellow: "pdfjs-editor-colorpicker-yellow" 23795 }); 23796 } 23797 renderButton() { 23798 const button = this.#button = document.createElement("button"); 23799 button.className = "colorPicker"; 23800 button.tabIndex = "0"; 23801 button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button"); 23802 button.ariaHasPopup = "true"; 23803 if (this.#editor) { 23804 button.ariaControls = `${this.#editor.id}_colorpicker_dropdown`; 23805 } 23806 const signal = this.#uiManager._signal; 23807 button.addEventListener("click", this.#openDropdown.bind(this), { 23808 signal 23809 }); 23810 button.addEventListener("keydown", this.#keyDown.bind(this), { 23811 signal 23812 }); 23813 const swatch = this.#buttonSwatch = document.createElement("span"); 23814 swatch.className = "swatch"; 23815 swatch.ariaHidden = "true"; 23816 swatch.style.backgroundColor = this.#defaultColor; 23817 button.append(swatch); 23818 return button; 23819 } 23820 renderMainDropdown() { 23821 const dropdown = this.#dropdown = this.#getDropdownRoot(); 23822 dropdown.ariaOrientation = "horizontal"; 23823 dropdown.ariaLabelledBy = "highlightColorPickerLabel"; 23824 return dropdown; 23825 } 23826 #getDropdownRoot() { 23827 const div = document.createElement("div"); 23828 const signal = this.#uiManager._signal; 23829 div.addEventListener("contextmenu", noContextMenu, { 23830 signal 23831 }); 23832 div.className = "dropdown"; 23833 div.role = "listbox"; 23834 div.ariaMultiSelectable = "false"; 23835 div.ariaOrientation = "vertical"; 23836 div.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-dropdown"); 23837 if (this.#editor) { 23838 div.id = `${this.#editor.id}_colorpicker_dropdown`; 23839 } 23840 for (const [name, color] of this.#uiManager.highlightColors) { 23841 const button = document.createElement("button"); 23842 button.tabIndex = "0"; 23843 button.role = "option"; 23844 button.setAttribute("data-color", color); 23845 button.title = name; 23846 button.setAttribute("data-l10n-id", ColorPicker.#l10nColor[name]); 23847 const swatch = document.createElement("span"); 23848 button.append(swatch); 23849 swatch.className = "swatch"; 23850 swatch.style.backgroundColor = color; 23851 button.ariaSelected = color === this.#defaultColor; 23852 button.addEventListener("click", this.#colorSelect.bind(this, color), { 23853 signal 23854 }); 23855 div.append(button); 23856 } 23857 div.addEventListener("keydown", this.#keyDown.bind(this), { 23858 signal 23859 }); 23860 return div; 23861 } 23862 #colorSelect(color, event) { 23863 event.stopPropagation(); 23864 this.#eventBus.dispatch("switchannotationeditorparams", { 23865 source: this, 23866 type: AnnotationEditorParamsType.HIGHLIGHT_COLOR, 23867 value: color 23868 }); 23869 this.update(color); 23870 } 23871 _colorSelectFromKeyboard(event) { 23872 if (event.target === this.#button) { 23873 this.#openDropdown(event); 23874 return; 23875 } 23876 const color = event.target.getAttribute("data-color"); 23877 if (!color) { 23878 return; 23879 } 23880 this.#colorSelect(color, event); 23881 } 23882 _moveToNext(event) { 23883 if (!this.#isDropdownVisible) { 23884 this.#openDropdown(event); 23885 return; 23886 } 23887 if (event.target === this.#button) { 23888 this.#dropdown.firstElementChild?.focus(); 23889 return; 23890 } 23891 event.target.nextSibling?.focus(); 23892 } 23893 _moveToPrevious(event) { 23894 if (event.target === this.#dropdown?.firstElementChild || event.target === this.#button) { 23895 if (this.#isDropdownVisible) { 23896 this._hideDropdownFromKeyboard(); 23897 } 23898 return; 23899 } 23900 if (!this.#isDropdownVisible) { 23901 this.#openDropdown(event); 23902 } 23903 event.target.previousSibling?.focus(); 23904 } 23905 _moveToBeginning(event) { 23906 if (!this.#isDropdownVisible) { 23907 this.#openDropdown(event); 23908 return; 23909 } 23910 this.#dropdown.firstElementChild?.focus(); 23911 } 23912 _moveToEnd(event) { 23913 if (!this.#isDropdownVisible) { 23914 this.#openDropdown(event); 23915 return; 23916 } 23917 this.#dropdown.lastElementChild?.focus(); 23918 } 23919 #keyDown(event) { 23920 ColorPicker._keyboardManager.exec(this, event); 23921 } 23922 #openDropdown(event) { 23923 if (this.#isDropdownVisible) { 23924 this.hideDropdown(); 23925 return; 23926 } 23927 this.#dropdownWasFromKeyboard = event.detail === 0; 23928 if (!this.#openDropdownAC) { 23929 this.#openDropdownAC = new AbortController(); 23930 window.addEventListener("pointerdown", this.#pointerDown.bind(this), { 23931 signal: this.#uiManager.combinedSignal(this.#openDropdownAC) 23932 }); 23933 } 23934 this.#button.ariaExpanded = "true"; 23935 if (this.#dropdown) { 23936 this.#dropdown.classList.remove("hidden"); 23937 return; 23938 } 23939 const root = this.#dropdown = this.#getDropdownRoot(); 23940 this.#button.append(root); 23941 } 23942 #pointerDown(event) { 23943 if (this.#dropdown?.contains(event.target)) { 23944 return; 23945 } 23946 this.hideDropdown(); 23947 } 23948 hideDropdown() { 23949 this.#dropdown?.classList.add("hidden"); 23950 this.#button.ariaExpanded = "false"; 23951 this.#openDropdownAC?.abort(); 23952 this.#openDropdownAC = null; 23953 } 23954 get #isDropdownVisible() { 23955 return this.#dropdown && !this.#dropdown.classList.contains("hidden"); 23956 } 23957 _hideDropdownFromKeyboard() { 23958 if (this.#isMainColorPicker) { 23959 return; 23960 } 23961 if (!this.#isDropdownVisible) { 23962 this.#editor?.unselect(); 23963 return; 23964 } 23965 this.hideDropdown(); 23966 this.#button.focus({ 23967 preventScroll: true, 23968 focusVisible: this.#dropdownWasFromKeyboard 23969 }); 23970 } 23971 update(color) { 23972 if (this.#buttonSwatch) { 23973 this.#buttonSwatch.style.backgroundColor = color; 23974 } 23975 if (!this.#dropdown) { 23976 return; 23977 } 23978 const i = this.#uiManager.highlightColors.values(); 23979 for (const child of this.#dropdown.children) { 23980 child.ariaSelected = i.next().value === color.toUpperCase(); 23981 } 23982 } 23983 destroy() { 23984 this.#button?.remove(); 23985 this.#button = null; 23986 this.#buttonSwatch = null; 23987 this.#dropdown?.remove(); 23988 this.#dropdown = null; 23989 } 23990} 23991class BasicColorPicker { 23992 #input = null; 23993 #hasAlpha = false; 23994 #editor = null; 23995 #uiManager = null; 23996 static #l10nColor = null; 23997 constructor(editor) { 23998 this.#editor = editor; 23999 this.#uiManager = editor._uiManager; 24000 BasicColorPicker.#l10nColor ||= Object.freeze({ 24001 freetext: "pdfjs-editor-color-picker-free-text-input", 24002 ink: "pdfjs-editor-color-picker-ink-input" 24003 }); 24004 } 24005 renderButton() { 24006 if (this.#input) { 24007 return this.#input; 24008 } 24009 const { 24010 editorType, 24011 colorType, 24012 colorAndOpacityType, 24013 opacityType, 24014 color, 24015 opacity 24016 } = this.#editor; 24017 const hasAlpha = this.#hasAlpha = FeatureTest.isAlphaColorInputSupported && opacityType !== undefined; 24018 const input = this.#input = document.createElement("input"); 24019 input.type = "color"; 24020 if (hasAlpha) { 24021 input.setAttribute("alpha", ""); 24022 const alphaHex = Util.hexNums[Math.round((opacity ?? 1) * 255)]; 24023 input.value = (color || "#000000") + alphaHex; 24024 } else { 24025 input.value = color || "#000000"; 24026 } 24027 input.className = "basicColorPicker"; 24028 input.tabIndex = 0; 24029 input.setAttribute("data-l10n-id", BasicColorPicker.#l10nColor[editorType]); 24030 input.addEventListener("input", () => { 24031 if (hasAlpha) { 24032 const rgba = getRGBA(input.value); 24033 if (!rgba) { 24034 return; 24035 } 24036 const [r, g, b, op] = rgba; 24037 const hex = Util.makeHexColor(r, g, b); 24038 if (colorAndOpacityType !== undefined) { 24039 this.#uiManager.updateParams(colorAndOpacityType, { 24040 color: hex, 24041 opacity: op 24042 }); 24043 } else { 24044 this.#uiManager.updateParams(colorType, hex); 24045 this.#uiManager.updateParams(opacityType, op); 24046 } 24047 } else { 24048 this.#uiManager.updateParams(colorType, input.value); 24049 } 24050 }, { 24051 signal: this.#uiManager._signal 24052 }); 24053 return input; 24054 } 24055 update(value) { 24056 if (!this.#input) { 24057 return; 24058 } 24059 if (this.#hasAlpha) { 24060 const alphaHex = Util.hexNums[Math.round(this.#editor.opacity * 255)]; 24061 this.#input.value = value + alphaHex; 24062 } else { 24063 this.#input.value = value; 24064 } 24065 } 24066 updateOpacity(value) { 24067 if (!this.#input || !this.#hasAlpha) { 24068 return; 24069 } 24070 const alphaHex = Util.hexNums[Math.round(value * 255)]; 24071 this.#input.value = this.#editor.color + alphaHex; 24072 } 24073 destroy() { 24074 this.#input?.remove(); 24075 this.#input = null; 24076 } 24077 hideDropdown() {} 24078} 24079 24080// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.flat-map.js 24081var es_iterator_flat_map = __webpack_require__(531); 24082;// ./src/shared/scripting_utils.js 24083 24084 24085 24086function makeColorComp(n) { 24087 return Math.floor(MathClamp(n, 0, 1) * 255).toString(16).padStart(2, "0"); 24088} 24089function scaleAndClamp(x) { 24090 return MathClamp(x, 0, 1) * 255; 24091} 24092class ColorConverters { 24093 static CMYK_G([c, y, m, k]) { 24094 return ["G", 1 - Math.min(1, 0.3 * c + 0.59 * m + 0.11 * y + k)]; 24095 } 24096 static G_CMYK([g]) { 24097 return ["CMYK", 0, 0, 0, 1 - g]; 24098 } 24099 static G_RGB([g]) { 24100 return ["RGB", g, g, g]; 24101 } 24102 static G_rgb([g]) { 24103 g = scaleAndClamp(g); 24104 return [g, g, g]; 24105 } 24106 static G_HTML([g]) { 24107 const G = makeColorComp(g); 24108 return `#${G}${G}${G}`; 24109 } 24110 static RGB_G([r, g, b]) { 24111 return ["G", 0.3 * r + 0.59 * g + 0.11 * b]; 24112 } 24113 static RGB_rgb(color) { 24114 return color.map(scaleAndClamp); 24115 } 24116 static RGB_HTML(color) { 24117 return `#${color.map(makeColorComp).join("")}`; 24118 } 24119 static T_HTML() { 24120 return "#00000000"; 24121 } 24122 static T_rgb() { 24123 return [null]; 24124 } 24125 static CMYK_RGB([c, y, m, k]) { 24126 return ["RGB", 1 - Math.min(1, c + k), 1 - Math.min(1, m + k), 1 - Math.min(1, y + k)]; 24127 } 24128 static CMYK_rgb([c, y, m, k]) { 24129 return [scaleAndClamp(1 - Math.min(1, c + k)), scaleAndClamp(1 - Math.min(1, m + k)), scaleAndClamp(1 - Math.min(1, y + k))]; 24130 } 24131 static CMYK_HTML(components) { 24132 const rgb = this.CMYK_RGB(components).slice(1); 24133 return this.RGB_HTML(rgb); 24134 } 24135 static RGB_CMYK([r, g, b]) { 24136 const c = 1 - r; 24137 const m = 1 - g; 24138 const y = 1 - b; 24139 const k = Math.min(c, m, y); 24140 return ["CMYK", c, m, y, k]; 24141 } 24142} 24143const DateFormats = (/* unused pure expression or super */ null && (["m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm", "d-mmm-yy", "dd-mmm-yy", "yy-mm-dd", "mmm-yy", "mmmm-yy", "mmm d, yyyy", "mmmm d, yyyy", "m/d/yy h:MM tt", "m/d/yy HH:MM"])); 24144const TimeFormats = (/* unused pure expression or super */ null && (["HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"])); 24145 24146;// ./src/display/svg_factory.js 24147 24148class BaseSVGFactory { 24149 create(width, height, skipDimensions = false) { 24150 if (width <= 0 || height <= 0) { 24151 throw new Error("Invalid SVG dimensions"); 24152 } 24153 const svg = this._createSVG("svg:svg"); 24154 svg.setAttribute("version", "1.1"); 24155 if (!skipDimensions) { 24156 svg.setAttribute("width", `${width}px`); 24157 svg.setAttribute("height", `${height}px`); 24158 } 24159 svg.setAttribute("preserveAspectRatio", "none"); 24160 svg.setAttribute("viewBox", `0 0 ${width} ${height}`); 24161 return svg; 24162 } 24163 createElement(type) { 24164 if (typeof type !== "string") { 24165 throw new Error("Invalid SVG element type"); 24166 } 24167 return this._createSVG(type); 24168 } 24169 _createSVG(type) { 24170 unreachable("Abstract method `_createSVG` called."); 24171 } 24172} 24173class DOMSVGFactory extends BaseSVGFactory { 24174 _createSVG(type) { 24175 return document.createElementNS(SVG_NS, type); 24176 } 24177} 24178 24179;// ./src/display/annotation_layer.js 24180 24181 24182 24183 24184 24185 24186 24187 24188 24189 24190 24191 24192 24193 24194
vendor: 129,342 bytes, lines 24195-28445
24195 24196 24197 24198 24199 24200 24201const annotation_layer_DEFAULT_FONT_SIZE = 9; 24202const GetElementsByNameSet = new WeakSet(); 24203const TIMEZONE_OFFSET = new Date().getTimezoneOffset() * 60 * 1000; 24204class AnnotationElementFactory { 24205 static create(parameters) { 24206 const subtype = parameters.data.annotationType; 24207 switch (subtype) { 24208 case AnnotationType.LINK: 24209 return new LinkAnnotationElement(parameters); 24210 case AnnotationType.TEXT: 24211 return new TextAnnotationElement(parameters); 24212 case AnnotationType.WIDGET: 24213 const fieldType = parameters.data.fieldType; 24214 switch (fieldType) { 24215 case "Tx": 24216 return new TextWidgetAnnotationElement(parameters); 24217 case "Btn": 24218 if (parameters.data.radioButton) { 24219 return new RadioButtonWidgetAnnotationElement(parameters); 24220 } else if (parameters.data.checkBox) { 24221 return new CheckboxWidgetAnnotationElement(parameters); 24222 } 24223 return new PushButtonWidgetAnnotationElement(parameters); 24224 case "Ch": 24225 return new ChoiceWidgetAnnotationElement(parameters); 24226 case "Sig": 24227 return new SignatureWidgetAnnotationElement(parameters); 24228 } 24229 return new WidgetAnnotationElement(parameters); 24230 case AnnotationType.POPUP: 24231 return new PopupAnnotationElement(parameters); 24232 case AnnotationType.FREETEXT: 24233 return new FreeTextAnnotationElement(parameters); 24234 case AnnotationType.LINE: 24235 return new LineAnnotationElement(parameters); 24236 case AnnotationType.SQUARE: 24237 return new SquareAnnotationElement(parameters); 24238 case AnnotationType.CIRCLE: 24239 return new CircleAnnotationElement(parameters); 24240 case AnnotationType.POLYLINE: 24241 return new PolylineAnnotationElement(parameters); 24242 case AnnotationType.CARET: 24243 return new CaretAnnotationElement(parameters); 24244 case AnnotationType.INK: 24245 return new InkAnnotationElement(parameters); 24246 case AnnotationType.POLYGON: 24247 return new PolygonAnnotationElement(parameters); 24248 case AnnotationType.HIGHLIGHT: 24249 return new HighlightAnnotationElement(parameters); 24250 case AnnotationType.UNDERLINE: 24251 return new UnderlineAnnotationElement(parameters); 24252 case AnnotationType.SQUIGGLY: 24253 return new SquigglyAnnotationElement(parameters); 24254 case AnnotationType.STRIKEOUT: 24255 return new StrikeOutAnnotationElement(parameters); 24256 case AnnotationType.STAMP: 24257 return new StampAnnotationElement(parameters); 24258 case AnnotationType.FILEATTACHMENT: 24259 return new FileAttachmentAnnotationElement(parameters); 24260 case AnnotationType.RICHMEDIA: 24261 case AnnotationType.SCREEN: 24262 case AnnotationType.SOUND: 24263 return new MediaAnnotationElement(parameters); 24264 default: 24265 return new AnnotationElement(parameters); 24266 } 24267 } 24268} 24269class AnnotationElement { 24270 #updates = null; 24271 #hasBorder = false; 24272 #popupElement = null; 24273 constructor(parameters, { 24274 isRenderable = false, 24275 ignoreBorder = false, 24276 createQuadrilaterals = false 24277 } = {}) { 24278 this.isRenderable = isRenderable; 24279 this.data = parameters.data; 24280 this.layer = parameters.layer; 24281 this.linkService = parameters.linkService; 24282 this.downloadManager = parameters.downloadManager; 24283 this.imageResourcesPath = parameters.imageResourcesPath; 24284 this.renderForms = parameters.renderForms; 24285 this.svgFactory = parameters.svgFactory; 24286 this.annotationStorage = parameters.annotationStorage; 24287 this.enableComment = parameters.enableComment; 24288 this.enableScripting = parameters.enableScripting; 24289 this.hasJSActions = parameters.hasJSActions; 24290 this._fieldObjects = parameters.fieldObjects; 24291 this.parent = parameters.parent; 24292 this.hasOwnCommentButton = false; 24293 if (isRenderable) { 24294 this.contentElement = this.container = this._createContainer(ignoreBorder); 24295 } 24296 if (createQuadrilaterals) { 24297 this._createQuadrilaterals(); 24298 } 24299 } 24300 static _hasPopupData({ 24301 contentsObj, 24302 richText 24303 }) { 24304 return !!(contentsObj?.str || richText?.str); 24305 } 24306 get _isEditable() { 24307 return this.data.isEditable; 24308 } 24309 get hasPopupData() { 24310 return AnnotationElement._hasPopupData(this.data) || this.enableComment && !!this.commentText; 24311 } 24312 get commentData() { 24313 const { 24314 data 24315 } = this; 24316 const editor = this.annotationStorage?.getEditor(data.id); 24317 if (editor) { 24318 return editor.getData(); 24319 } 24320 return data; 24321 } 24322 get hasCommentButton() { 24323 return this.enableComment && this.hasPopupElement; 24324 } 24325 get commentButtonPosition() { 24326 const editor = this.annotationStorage?.getEditor(this.data.id); 24327 if (editor) { 24328 return editor.commentButtonPositionInPage; 24329 } 24330 const { 24331 quadPoints, 24332 inkLists, 24333 rect 24334 } = this.data; 24335 let maxX = -Infinity; 24336 let maxY = -Infinity; 24337 if (quadPoints?.length >= 8) { 24338 for (let i = 0; i < quadPoints.length; i += 8) { 24339 if (quadPoints[i + 1] > maxY) { 24340 maxY = quadPoints[i + 1]; 24341 maxX = quadPoints[i + 2]; 24342 } else if (quadPoints[i + 1] === maxY) { 24343 maxX = Math.max(maxX, quadPoints[i + 2]); 24344 } 24345 } 24346 return [maxX, maxY]; 24347 } 24348 if (inkLists?.length >= 1) { 24349 for (const inkList of inkLists) { 24350 for (let i = 0, ii = inkList.length; i < ii; i += 2) { 24351 if (inkList[i + 1] > maxY) { 24352 maxY = inkList[i + 1]; 24353 maxX = inkList[i]; 24354 } else if (inkList[i + 1] === maxY) { 24355 maxX = Math.max(maxX, inkList[i]); 24356 } 24357 } 24358 } 24359 if (maxX !== Infinity) { 24360 return [maxX, maxY]; 24361 } 24362 } 24363 if (rect) { 24364 return [rect[2], rect[3]]; 24365 } 24366 return null; 24367 } 24368 _normalizePoint(point) { 24369 const { 24370 page: { 24371 view 24372 }, 24373 viewport: { 24374 rawDims: { 24375 pageWidth, 24376 pageHeight, 24377 pageX, 24378 pageY 24379 } 24380 } 24381 } = this.parent; 24382 point[1] = view[3] - point[1] + view[1]; 24383 point[0] = 100 * (point[0] - pageX) / pageWidth; 24384 point[1] = 100 * (point[1] - pageY) / pageHeight; 24385 return point; 24386 } 24387 get commentText() { 24388 const { 24389 data 24390 } = this; 24391 return this.annotationStorage.getRawValue(`${AnnotationEditorPrefix}${data.id}`)?.popup?.contents || data.contentsObj?.str || ""; 24392 } 24393 set commentText(text) { 24394 const { 24395 data 24396 } = this; 24397 const popup = { 24398 deleted: !text, 24399 contents: text || "" 24400 }; 24401 if (!this.annotationStorage.updateEditor(data.id, { 24402 popup 24403 })) { 24404 this.annotationStorage.setValue(`${AnnotationEditorPrefix}${data.id}`, { 24405 id: data.id, 24406 annotationType: data.annotationType, 24407 page: this.parent.page, 24408 popup, 24409 popupRef: data.popupRef, 24410 modificationDate: new Date() 24411 }); 24412 } 24413 if (!text) { 24414 this.removePopup(); 24415 } 24416 } 24417 removePopup() { 24418 (this.#popupElement?.popup || this.popup)?.remove(); 24419 this.#popupElement = this.popup = null; 24420 } 24421 updateEdited(params) { 24422 if (!this.container) { 24423 return; 24424 } 24425 if (params.rect) { 24426 this.#updates ||= { 24427 rect: this.data.rect.slice(0) 24428 }; 24429 } 24430 const { 24431 rect, 24432 popup: newPopup 24433 } = params; 24434 if (rect) { 24435 this.#setRectEdited(rect); 24436 } 24437 let popup = this.#popupElement?.popup || this.popup; 24438 if (!popup && newPopup?.text) { 24439 this._createPopup(newPopup); 24440 popup = this.#popupElement.popup; 24441 } 24442 if (!popup) { 24443 return; 24444 } 24445 popup.updateEdited(params); 24446 if (newPopup?.deleted) { 24447 popup.remove(); 24448 this.#popupElement = null; 24449 this.popup = null; 24450 } 24451 } 24452 resetEdited() { 24453 if (!this.#updates) { 24454 return; 24455 } 24456 this.#setRectEdited(this.#updates.rect); 24457 this.#popupElement?.popup.resetEdited(); 24458 this.#updates = null; 24459 } 24460 #setRectEdited(rect) { 24461 const { 24462 container: { 24463 style 24464 }, 24465 data: { 24466 rect: currentRect, 24467 rotation 24468 }, 24469 parent: { 24470 viewport: { 24471 rawDims: { 24472 pageWidth, 24473 pageHeight, 24474 pageX, 24475 pageY 24476 } 24477 } 24478 } 24479 } = this; 24480 currentRect?.splice(0, 4, ...rect); 24481 style.left = `${100 * (rect[0] - pageX) / pageWidth}%`; 24482 style.top = `${100 * (pageHeight - rect[3] + pageY) / pageHeight}%`; 24483 if (rotation === 0) { 24484 style.width = `${100 * (rect[2] - rect[0]) / pageWidth}%`; 24485 style.height = `${100 * (rect[3] - rect[1]) / pageHeight}%`; 24486 } else { 24487 this.setRotation(rotation); 24488 } 24489 } 24490 _createContainer(ignoreBorder) { 24491 const { 24492 data, 24493 parent: { 24494 page, 24495 viewport 24496 } 24497 } = this; 24498 const container = document.createElement("section"); 24499 container.setAttribute("data-annotation-id", data.id); 24500 if (!(this instanceof WidgetAnnotationElement) && !(this instanceof LinkAnnotationElement) && !(this instanceof MediaAnnotationElement)) { 24501 container.tabIndex = 0; 24502 } 24503 const { 24504 style 24505 } = container; 24506 style.zIndex = this.parent.zIndex; 24507 this.parent.zIndex += 2; 24508 if (data.alternativeText) { 24509 container.title = data.alternativeText; 24510 } 24511 if (data.noRotate) { 24512 container.classList.add("norotate"); 24513 } 24514 if (!data.rect || this instanceof PopupAnnotationElement) { 24515 const { 24516 rotation 24517 } = data; 24518 if (!data.hasOwnCanvas && rotation !== 0) { 24519 this.setRotation(rotation, container); 24520 } 24521 return container; 24522 } 24523 const { 24524 width, 24525 height 24526 } = this; 24527 if (!ignoreBorder && data.borderStyle.width > 0) { 24528 style.borderWidth = `${data.borderStyle.width}px`; 24529 const horizontalRadius = data.borderStyle.horizontalCornerRadius; 24530 const verticalRadius = data.borderStyle.verticalCornerRadius; 24531 if (horizontalRadius > 0 || verticalRadius > 0) { 24532 const radius = `calc(${horizontalRadius}px * var(--total-scale-factor)) / calc(${verticalRadius}px * var(--total-scale-factor))`; 24533 style.borderRadius = radius; 24534 } 24535 switch (data.borderStyle.style) { 24536 case AnnotationBorderStyleType.SOLID: 24537 style.borderStyle = "solid"; 24538 break; 24539 case AnnotationBorderStyleType.DASHED: 24540 style.borderStyle = "dashed"; 24541 break; 24542 case AnnotationBorderStyleType.BEVELED: 24543 warn("Unimplemented border style: beveled"); 24544 break; 24545 case AnnotationBorderStyleType.INSET: 24546 warn("Unimplemented border style: inset"); 24547 break; 24548 case AnnotationBorderStyleType.UNDERLINE: 24549 style.borderBottomStyle = "solid"; 24550 break; 24551 default: 24552 break; 24553 } 24554 const borderColor = data.borderColor || null; 24555 if (borderColor) { 24556 this.#hasBorder = true; 24557 style.borderColor = Util.makeHexColor(...borderColor); 24558 } else { 24559 style.borderWidth = 0; 24560 } 24561 } 24562 const rect = Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]); 24563 const { 24564 pageWidth, 24565 pageHeight, 24566 pageX, 24567 pageY 24568 } = viewport.rawDims; 24569 style.left = `${100 * (rect[0] - pageX) / pageWidth}%`; 24570 style.top = `${100 * (rect[1] - pageY) / pageHeight}%`; 24571 const { 24572 rotation 24573 } = data; 24574 if (data.hasOwnCanvas || rotation === 0) { 24575 style.width = `${100 * width / pageWidth}%`; 24576 style.height = `${100 * height / pageHeight}%`; 24577 } else { 24578 this.setRotation(rotation, container); 24579 } 24580 return container; 24581 } 24582 setRotation(angle, container = this.container) { 24583 if (!this.data.rect) { 24584 return; 24585 } 24586 const { 24587 pageWidth, 24588 pageHeight 24589 } = this.parent.viewport.rawDims; 24590 let { 24591 width, 24592 height 24593 } = this; 24594 if (angle % 180 !== 0) { 24595 [width, height] = [height, width]; 24596 } 24597 container.style.width = `${100 * width / pageWidth}%`; 24598 container.style.height = `${100 * height / pageHeight}%`; 24599 container.setAttribute("data-main-rotation", (360 - angle) % 360); 24600 } 24601 get _commonActions() { 24602 const setColor = (jsName, styleName, event) => { 24603 const color = event.detail[jsName]; 24604 const colorType = color[0]; 24605 const colorArray = color.slice(1); 24606 event.target.style[styleName] = ColorConverters[`${colorType}_HTML`](colorArray); 24607 this.annotationStorage.setValue(this.data.id, { 24608 [styleName]: ColorConverters[`${colorType}_rgb`](colorArray) 24609 }); 24610 }; 24611 return shadow(this, "_commonActions", { 24612 display: event => { 24613 const { 24614 display 24615 } = event.detail; 24616 const hidden = display % 2 === 1; 24617 this.container.style.visibility = hidden ? "hidden" : "visible"; 24618 this.annotationStorage.setValue(this.data.id, { 24619 noView: hidden, 24620 noPrint: display === 1 || display === 2 24621 }); 24622 }, 24623 print: event => { 24624 this.annotationStorage.setValue(this.data.id, { 24625 noPrint: !event.detail.print 24626 }); 24627 }, 24628 hidden: event => { 24629 const { 24630 hidden 24631 } = event.detail; 24632 this.container.style.visibility = hidden ? "hidden" : "visible"; 24633 this.annotationStorage.setValue(this.data.id, { 24634 noPrint: hidden, 24635 noView: hidden 24636 }); 24637 }, 24638 focus: event => { 24639 setTimeout(() => event.target.focus({ 24640 preventScroll: false 24641 }), 0); 24642 }, 24643 userName: event => { 24644 event.target.title = event.detail.userName; 24645 }, 24646 readonly: event => { 24647 event.target.disabled = event.detail.readonly; 24648 }, 24649 required: event => { 24650 this._setRequired(event.target, event.detail.required); 24651 }, 24652 bgColor: event => { 24653 setColor("bgColor", "backgroundColor", event); 24654 }, 24655 fillColor: event => { 24656 setColor("fillColor", "backgroundColor", event); 24657 }, 24658 fgColor: event => { 24659 setColor("fgColor", "color", event); 24660 }, 24661 textColor: event => { 24662 setColor("textColor", "color", event); 24663 }, 24664 borderColor: event => { 24665 setColor("borderColor", "borderColor", event); 24666 }, 24667 strokeColor: event => { 24668 setColor("strokeColor", "borderColor", event); 24669 }, 24670 rotation: event => { 24671 const angle = event.detail.rotation; 24672 this.setRotation(angle); 24673 this.annotationStorage.setValue(this.data.id, { 24674 rotation: angle 24675 }); 24676 } 24677 }); 24678 } 24679 _dispatchEventFromSandbox(actions, jsEvent) { 24680 const commonActions = this._commonActions; 24681 for (const name of Object.keys(jsEvent.detail)) { 24682 const action = actions[name] || commonActions[name]; 24683 action?.(jsEvent); 24684 } 24685 } 24686 _setDefaultPropertiesFromJS(element) { 24687 if (!this.enableScripting) { 24688 return; 24689 } 24690 const storedData = this.annotationStorage.getRawValue(this.data.id); 24691 if (!storedData) { 24692 return; 24693 } 24694 const commonActions = this._commonActions; 24695 for (const [actionName, detail] of Object.entries(storedData)) { 24696 const action = commonActions[actionName]; 24697 if (action) { 24698 const eventProxy = { 24699 detail: { 24700 [actionName]: detail 24701 }, 24702 target: element 24703 }; 24704 action(eventProxy); 24705 delete storedData[actionName]; 24706 } 24707 } 24708 } 24709 _createQuadrilaterals() { 24710 if (!this.container) { 24711 return; 24712 } 24713 const { 24714 quadPoints 24715 } = this.data; 24716 if (!quadPoints) { 24717 return; 24718 } 24719 const [rectBlX, rectBlY, rectTrX, rectTrY] = this.data.rect.map(Math.fround); 24720 if (quadPoints.length === 8) { 24721 const [trX, trY, blX, blY] = quadPoints.subarray(2, 6); 24722 if (rectTrX === trX && rectTrY === trY && rectBlX === blX && rectBlY === blY) { 24723 return; 24724 } 24725 } 24726 const { 24727 style 24728 } = this.container; 24729 let svgBuffer; 24730 if (this.#hasBorder) { 24731 const { 24732 borderColor, 24733 borderWidth 24734 } = style; 24735 style.borderWidth = 0; 24736 svgBuffer = ["url('data:image/svg+xml;utf8,", `<svg xmlns="${SVG_NS}" preserveAspectRatio="none" viewBox="0 0 1 1">`, `<g fill="transparent" stroke="${borderColor}" stroke-width="${borderWidth}">`]; 24737 this.container.classList.add("hasBorder"); 24738 } 24739 const width = rectTrX - rectBlX; 24740 const height = rectTrY - rectBlY; 24741 const { 24742 svgFactory 24743 } = this; 24744 const svg = svgFactory.createElement("svg"); 24745 svg.classList.add("quadrilateralsContainer"); 24746 svg.setAttribute("width", 0); 24747 svg.setAttribute("height", 0); 24748 svg.role = "none"; 24749 const defs = svgFactory.createElement("defs"); 24750 svg.append(defs); 24751 const clipPath = svgFactory.createElement("clipPath"); 24752 const id = `clippath_${this.data.id}`; 24753 clipPath.setAttribute("id", id); 24754 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 24755 defs.append(clipPath); 24756 for (let i = 2, ii = quadPoints.length; i < ii; i += 8) { 24757 const trX = quadPoints[i]; 24758 const trY = quadPoints[i + 1]; 24759 const blX = quadPoints[i + 2]; 24760 const blY = quadPoints[i + 3]; 24761 const rect = svgFactory.createElement("rect"); 24762 const x = (blX - rectBlX) / width; 24763 const y = (rectTrY - trY) / height; 24764 const rectWidth = (trX - blX) / width; 24765 const rectHeight = (trY - blY) / height; 24766 rect.setAttribute("x", x); 24767 rect.setAttribute("y", y); 24768 rect.setAttribute("width", rectWidth); 24769 rect.setAttribute("height", rectHeight); 24770 clipPath.append(rect); 24771 svgBuffer?.push(`<rect vector-effect="non-scaling-stroke" x="${x}" y="${y}" width="${rectWidth}" height="${rectHeight}"/>`); 24772 } 24773 if (this.#hasBorder) { 24774 svgBuffer.push(`</g></svg>')`); 24775 style.backgroundImage = svgBuffer.join(""); 24776 } 24777 this.container.append(svg); 24778 this.container.style.clipPath = `url(#${id})`; 24779 } 24780 _createPopup(popupData = null) { 24781 const { 24782 data 24783 } = this; 24784 let contentsObj, modificationDate; 24785 if (popupData) { 24786 contentsObj = { 24787 str: popupData.text 24788 }; 24789 modificationDate = popupData.date; 24790 } else { 24791 contentsObj = data.contentsObj; 24792 modificationDate = data.modificationDate; 24793 } 24794 this.#popupElement = new PopupAnnotationElement({ 24795 data: { 24796 color: data.color, 24797 titleObj: data.titleObj, 24798 modificationDate, 24799 contentsObj, 24800 richText: data.richText, 24801 parentRect: data.rect, 24802 borderStyle: 0, 24803 id: `popup_${data.id}`, 24804 rotation: data.rotation, 24805 noRotate: true 24806 }, 24807 linkService: this.linkService, 24808 parent: this.parent, 24809 elements: [this] 24810 }); 24811 } 24812 get hasPopupElement() { 24813 return !!(this.#popupElement || this.popup || this.data.popupRef); 24814 } 24815 get extraPopupElement() { 24816 return this.#popupElement; 24817 } 24818 render() { 24819 unreachable("Abstract method `AnnotationElement.render` called"); 24820 } 24821 _getElementsByName(name, skipId = null) { 24822 const fields = []; 24823 if (this._fieldObjects) { 24824 const fieldObj = this._fieldObjects.get(name) || []; 24825 for (const { 24826 page, 24827 id, 24828 exportValues 24829 } of fieldObj) { 24830 if (page === -1) { 24831 continue; 24832 } 24833 if (id === skipId) { 24834 continue; 24835 } 24836 const exportValue = typeof exportValues === "string" ? exportValues : null; 24837 const domElement = document.querySelector(`[data-element-id="${id}"]`); 24838 if (domElement && !GetElementsByNameSet.has(domElement)) { 24839 warn(`_getElementsByName - element not allowed: ${id}`); 24840 continue; 24841 } 24842 fields.push({ 24843 id, 24844 exportValue, 24845 domElement 24846 }); 24847 } 24848 return fields; 24849 } 24850 for (const domElement of document.getElementsByName(name)) { 24851 const { 24852 exportValue 24853 } = domElement; 24854 const id = domElement.getAttribute("data-element-id"); 24855 if (id === skipId) { 24856 continue; 24857 } 24858 if (!GetElementsByNameSet.has(domElement)) { 24859 continue; 24860 } 24861 fields.push({ 24862 id, 24863 exportValue, 24864 domElement 24865 }); 24866 } 24867 return fields; 24868 } 24869 show() { 24870 if (this.container) { 24871 this.container.hidden = false; 24872 } 24873 this.popup?.maybeShow(); 24874 } 24875 hide() { 24876 if (this.container) { 24877 this.container.hidden = true; 24878 } 24879 this.popup?.forceHide(); 24880 } 24881 getElementsToTriggerPopup() { 24882 return this.container; 24883 } 24884 addHighlightArea() { 24885 const triggers = this.getElementsToTriggerPopup(); 24886 if (Array.isArray(triggers)) { 24887 for (const element of triggers) { 24888 element.classList.add("highlightArea"); 24889 } 24890 } else { 24891 triggers.classList.add("highlightArea"); 24892 } 24893 } 24894 _editOnDoubleClick() { 24895 if (!this._isEditable) { 24896 return; 24897 } 24898 const { 24899 annotationEditorType: mode, 24900 data: { 24901 id: editId 24902 } 24903 } = this; 24904 this.container.addEventListener("dblclick", () => { 24905 this.linkService.eventBus?.dispatch("switchannotationeditormode", { 24906 source: this, 24907 mode, 24908 editId, 24909 mustEnterInEditMode: true 24910 }); 24911 }); 24912 } 24913 updateOC(optionalContentConfig) { 24914 if (!this.data.oc || !optionalContentConfig) { 24915 return; 24916 } 24917 const isVisible = optionalContentConfig.isVisible(this.data.oc); 24918 if (isVisible) { 24919 this.show(); 24920 } else { 24921 this.hide(); 24922 } 24923 } 24924 get width() { 24925 return this.data.rect[2] - this.data.rect[0]; 24926 } 24927 get height() { 24928 return this.data.rect[3] - this.data.rect[1]; 24929 } 24930 _setBackgroundColor(element) { 24931 const color = this.data.backgroundColor || null; 24932 element.style.backgroundColor = color === null ? "transparent" : Util.makeHexColor(...color); 24933 } 24934} 24935class EditorAnnotationElement extends AnnotationElement { 24936 constructor(parameters) { 24937 super(parameters, { 24938 isRenderable: true, 24939 ignoreBorder: true 24940 }); 24941 this.editor = parameters.editor; 24942 } 24943 render() { 24944 this.container.className = "editorAnnotation"; 24945 return this.container; 24946 } 24947 createOrUpdatePopup() { 24948 const { 24949 editor 24950 } = this; 24951 if (!editor.hasComment) { 24952 return; 24953 } 24954 this._createPopup(editor.comment); 24955 } 24956 get hasCommentButton() { 24957 return this.enableComment && this.editor.hasComment; 24958 } 24959 get commentButtonPosition() { 24960 return this.editor.commentButtonPositionInPage; 24961 } 24962 get commentText() { 24963 return this.editor.comment.text; 24964 } 24965 set commentText(text) { 24966 this.editor.comment = text; 24967 if (!text) { 24968 this.removePopup(); 24969 } 24970 } 24971 get commentData() { 24972 return this.editor.getData(); 24973 } 24974 remove() { 24975 this.parent.removeAnnotation(this.data.id); 24976 this.container.remove(); 24977 this.container = null; 24978 this.removePopup(); 24979 } 24980} 24981class LinkAnnotationElement extends AnnotationElement { 24982 constructor(parameters, options = null) { 24983 super(parameters, { 24984 isRenderable: true, 24985 ignoreBorder: !!options?.ignoreBorder, 24986 createQuadrilaterals: true 24987 }); 24988 this.isTooltipOnly = parameters.data.isTooltipOnly; 24989 } 24990 render() { 24991 const { 24992 data, 24993 linkService 24994 } = this; 24995 const link = document.createElement("a"); 24996 link.setAttribute("data-element-id", data.id); 24997 let isBound = false; 24998 if (data.url) { 24999 linkService.addLinkAttributes(link, data.url, data.newWindow); 25000 isBound = true; 25001 } else if (data.action) { 25002 this._bindNamedAction(link, data.action, data.overlaidText); 25003 isBound = true; 25004 } else if (data.attachment) { 25005 this.#bindAttachment(link, data.attachmentId, data.attachment, data.overlaidText, data.attachmentDest); 25006 isBound = true; 25007 } else if (data.setOCGState) { 25008 this.#bindSetOCGState(link, data.setOCGState, data.overlaidText); 25009 isBound = true; 25010 } else if (data.dest) { 25011 this._bindLink(link, data.dest, data.overlaidText); 25012 isBound = true; 25013 } else { 25014 if (data.actions && (data.actions.has("Action") || data.actions.has("Mouse Up") || data.actions.has("Mouse Down")) && this.enableScripting && this.hasJSActions) { 25015 this._bindJSAction(link, data); 25016 isBound = true; 25017 } 25018 if (data.resetForm) { 25019 this._bindResetFormAction(link, data.resetForm); 25020 isBound = true; 25021 } else if (this.isTooltipOnly && !isBound) { 25022 this._bindLink(link, ""); 25023 isBound = true; 25024 } 25025 } 25026 this.container.classList.add("linkAnnotation"); 25027 if (isBound) { 25028 this.contentElement = link; 25029 this.container.append(link); 25030 } 25031 return this.container; 25032 } 25033 #setInternalLink() { 25034 this.container.setAttribute("data-internal-link", ""); 25035 } 25036 _bindLink(link, destination, overlaidText = "") { 25037 link.href = this.linkService.getDestinationHash(destination); 25038 link.onclick = () => { 25039 if (destination) { 25040 this.linkService.goToDestination(destination); 25041 } 25042 return false; 25043 }; 25044 if (destination || destination === "") { 25045 this.#setInternalLink(); 25046 } 25047 if (overlaidText) { 25048 link.title = overlaidText; 25049 } 25050 } 25051 _bindNamedAction(link, action, overlaidText = "") { 25052 link.href = this.linkService.getAnchorUrl(""); 25053 link.onclick = () => { 25054 this.linkService.executeNamedAction(action); 25055 return false; 25056 }; 25057 if (overlaidText) { 25058 link.title = overlaidText; 25059 } 25060 this.#setInternalLink(); 25061 } 25062 #bindAttachment(link, attachmentId, attachment, overlaidText = "", dest = null) { 25063 link.href = this.linkService.getAnchorUrl(""); 25064 if (attachment.description) { 25065 link.title = attachment.description; 25066 } else if (overlaidText) { 25067 link.title = overlaidText; 25068 } 25069 const openAttachment = async () => { 25070 const content = await this.linkService.getAttachmentContent(attachmentId); 25071 if (content) { 25072 this.downloadManager?.openOrDownloadData(content, attachment.filename, dest); 25073 } 25074 }; 25075 link.onclick = () => { 25076 openAttachment(); 25077 return false; 25078 }; 25079 this.#setInternalLink(); 25080 } 25081 #bindSetOCGState(link, action, overlaidText = "") { 25082 link.href = this.linkService.getAnchorUrl(""); 25083 link.onclick = () => { 25084 this.linkService.executeSetOCGState(action); 25085 return false; 25086 }; 25087 if (overlaidText) { 25088 link.title = overlaidText; 25089 } 25090 this.#setInternalLink(); 25091 } 25092 _bindJSAction(link, { 25093 actions, 25094 id, 25095 overlaidText 25096 }) { 25097 link.href = this.linkService.getAnchorUrl(""); 25098 const map = new Map([["Action", "onclick"], ["Mouse Up", "onmouseup"], ["Mouse Down", "onmousedown"]]); 25099 for (const name of actions.keys()) { 25100 const jsName = map.get(name); 25101 if (!jsName) { 25102 continue; 25103 } 25104 link[jsName] = () => { 25105 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25106 source: this, 25107 detail: { 25108 id, 25109 name 25110 } 25111 }); 25112 return false; 25113 }; 25114 } 25115 if (overlaidText) { 25116 link.title = overlaidText; 25117 } 25118 link.onclick ||= () => false; 25119 this.#setInternalLink(); 25120 } 25121 _bindResetFormAction(link, resetForm) { 25122 const otherClickAction = link.onclick; 25123 if (!otherClickAction) { 25124 link.href = this.linkService.getAnchorUrl(""); 25125 } 25126 this.#setInternalLink(); 25127 if (!this._fieldObjects) { 25128 warn(`_bindResetFormAction - "resetForm" action not supported, ` + "ensure that the `fieldObjects` parameter is provided."); 25129 if (!otherClickAction) { 25130 link.onclick = () => false; 25131 } 25132 return; 25133 } 25134 link.onclick = () => { 25135 otherClickAction?.(); 25136 const { 25137 fields: resetFormFields, 25138 refs: resetFormRefs, 25139 include 25140 } = resetForm; 25141 const allFields = []; 25142 if (resetFormFields.length !== 0 || resetFormRefs.length !== 0) { 25143 const fieldIds = new Set(resetFormRefs); 25144 for (const fieldName of resetFormFields) { 25145 const fields = this._fieldObjects.get(fieldName) || []; 25146 for (const { 25147 id 25148 } of fields) { 25149 fieldIds.add(id); 25150 } 25151 } 25152 for (const fields of this._fieldObjects.values()) { 25153 for (const field of fields) { 25154 if (fieldIds.has(field.id) === include) { 25155 allFields.push(field); 25156 } 25157 } 25158 } 25159 } else { 25160 for (const fields of this._fieldObjects.values()) { 25161 allFields.push(...fields); 25162 } 25163 } 25164 const storage = this.annotationStorage; 25165 const allIds = []; 25166 for (const field of allFields) { 25167 const { 25168 id 25169 } = field; 25170 allIds.push(id); 25171 switch (field.type) { 25172 case "text": 25173 { 25174 const value = field.defaultValue || ""; 25175 storage.setValue(id, { 25176 value 25177 }); 25178 break; 25179 } 25180 case "checkbox": 25181 case "radiobutton": 25182 { 25183 const value = field.defaultValue === field.exportValues; 25184 storage.setValue(id, { 25185 value 25186 }); 25187 break; 25188 } 25189 case "combobox": 25190 case "listbox": 25191 { 25192 const value = field.defaultValue || ""; 25193 storage.setValue(id, { 25194 value 25195 }); 25196 break; 25197 } 25198 default: 25199 continue; 25200 } 25201 const domElement = document.querySelector(`[data-element-id="${id}"]`); 25202 if (!domElement) { 25203 continue; 25204 } else if (!GetElementsByNameSet.has(domElement)) { 25205 warn(`_bindResetFormAction - element not allowed: ${id}`); 25206 continue; 25207 } 25208 domElement.dispatchEvent(new Event("resetform")); 25209 } 25210 if (this.enableScripting) { 25211 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25212 source: this, 25213 detail: { 25214 id: "app", 25215 ids: allIds, 25216 name: "ResetForm" 25217 } 25218 }); 25219 } 25220 return false; 25221 }; 25222 } 25223} 25224class TextAnnotationElement extends AnnotationElement { 25225 constructor(parameters) { 25226 super(parameters, { 25227 isRenderable: true 25228 }); 25229 } 25230 render() { 25231 this.container.classList.add("textAnnotation"); 25232 const image = document.createElement("img"); 25233 image.src = this.imageResourcesPath + "annotation-" + this.data.name.toLowerCase() + ".svg"; 25234 image.setAttribute("data-l10n-id", "pdfjs-text-annotation-type"); 25235 image.setAttribute("data-l10n-args", JSON.stringify({ 25236 type: this.data.name 25237 })); 25238 if (!this.data.popupRef && this.hasPopupData) { 25239 this.hasOwnCommentButton = true; 25240 this._createPopup(); 25241 } 25242 this.container.append(image); 25243 return this.container; 25244 } 25245} 25246class WidgetAnnotationElement extends AnnotationElement { 25247 render() { 25248 return this.container; 25249 } 25250 _getKeyModifier(event) { 25251 return FeatureTest.platform.isMac ? event.metaKey : event.ctrlKey; 25252 } 25253 _setEventListener(element, elementData, baseName, eventName, valueGetter) { 25254 if (baseName.includes("mouse")) { 25255 element.addEventListener(baseName, event => { 25256 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25257 source: this, 25258 detail: { 25259 id: this.data.id, 25260 name: eventName, 25261 value: valueGetter(event), 25262 shift: event.shiftKey, 25263 modifier: this._getKeyModifier(event) 25264 } 25265 }); 25266 }); 25267 } else { 25268 element.addEventListener(baseName, event => { 25269 if (baseName === "blur") { 25270 if (!elementData.focused || !event.relatedTarget) { 25271 return; 25272 } 25273 elementData.focused = false; 25274 } else if (baseName === "focus") { 25275 if (elementData.focused) { 25276 return; 25277 } 25278 elementData.focused = true; 25279 } 25280 if (!valueGetter) { 25281 return; 25282 } 25283 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25284 source: this, 25285 detail: { 25286 id: this.data.id, 25287 name: eventName, 25288 value: valueGetter(event) 25289 } 25290 }); 25291 }); 25292 } 25293 } 25294 _setEventListeners(element, elementData, names, getter) { 25295 const { 25296 actions 25297 } = this.data; 25298 for (const [baseName, eventName] of names) { 25299 if (eventName === "Action" || actions?.has(eventName)) { 25300 if (eventName === "Focus" || eventName === "Blur") { 25301 elementData ||= { 25302 focused: false 25303 }; 25304 } 25305 this._setEventListener(element, elementData, baseName, eventName, getter); 25306 if (eventName === "Focus" && !actions?.has("Blur")) { 25307 this._setEventListener(element, elementData, "blur", "Blur", null); 25308 } else if (eventName === "Blur" && !actions?.has("Focus")) { 25309 this._setEventListener(element, elementData, "focus", "Focus", null); 25310 } 25311 } 25312 } 25313 } 25314 _setTextStyle(element) { 25315 const TEXT_ALIGNMENT = ["left", "center", "right"]; 25316 const { 25317 fontColor 25318 } = this.data.defaultAppearanceData; 25319 const fontSize = this.data.defaultAppearanceData.fontSize || annotation_layer_DEFAULT_FONT_SIZE; 25320 const style = element.style; 25321 let computedFontSize; 25322 const BORDER_SIZE = 2; 25323 const roundToOneDecimal = x => Math.round(10 * x) / 10; 25324 if (this.data.multiLine) { 25325 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 25326 const numberOfLines = Math.round(height / ((/* inlined export .LINE_FACTOR */1.35) * fontSize)) || 1; 25327 const lineHeight = height / numberOfLines; 25328 computedFontSize = Math.min(fontSize, roundToOneDecimal(lineHeight / (/* inlined export .LINE_FACTOR */1.35))); 25329 } else { 25330 const height = Math.abs(this.data.rect[3] - this.data.rect[1] - BORDER_SIZE); 25331 computedFontSize = Math.min(fontSize, roundToOneDecimal(height / (/* inlined export .LINE_FACTOR */1.35))); 25332 } 25333 style.fontSize = `calc(${computedFontSize}px * var(--total-scale-factor))`; 25334 style.color = Util.makeHexColor(...fontColor); 25335 if (this.data.textAlignment !== null && !this.data.comb) { 25336 style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment]; 25337 } 25338 } 25339 _setRequired(element, isRequired) { 25340 if (isRequired) { 25341 element.setAttribute("required", true); 25342 } else { 25343 element.removeAttribute("required"); 25344 } 25345 element.setAttribute("aria-required", isRequired); 25346 } 25347} 25348class TextWidgetAnnotationElement extends WidgetAnnotationElement { 25349 constructor(parameters) { 25350 const isRenderable = parameters.renderForms || parameters.data.hasOwnCanvas || !parameters.data.hasAppearance && !!parameters.data.fieldValue; 25351 super(parameters, { 25352 isRenderable 25353 }); 25354 } 25355 setPropertyOnSiblings(base, key, value, keyInStorage) { 25356 const storage = this.annotationStorage; 25357 for (const element of this._getElementsByName(base.name, base.id)) { 25358 if (element.domElement) { 25359 element.domElement[key] = value; 25360 } 25361 storage.setValue(element.id, { 25362 [keyInStorage]: value 25363 }); 25364 } 25365 } 25366 render() { 25367 const storage = this.annotationStorage; 25368 const id = this.data.id; 25369 this.container.classList.add("textWidgetAnnotation"); 25370 let element = null; 25371 if (this.renderForms) { 25372 const storedData = storage.getValue(id, { 25373 value: this.data.fieldValue 25374 }); 25375 let textContent = storedData.value || ""; 25376 const maxLen = storage.getValue(id, { 25377 charLimit: this.data.maxLen 25378 }).charLimit; 25379 if (maxLen && textContent.length > maxLen) { 25380 textContent = textContent.slice(0, maxLen); 25381 } 25382 let fieldFormattedValues = storedData.formattedValue || this.data.textContent?.join("\n") || null; 25383 if (fieldFormattedValues && this.data.comb) { 25384 fieldFormattedValues = fieldFormattedValues.replaceAll(/\s+/g, ""); 25385 } 25386 const elementData = { 25387 userValue: textContent, 25388 formattedValue: fieldFormattedValues, 25389 lastCommittedValue: null, 25390 commitKey: 1, 25391 focused: false 25392 }; 25393 if (this.data.multiLine) { 25394 element = document.createElement("textarea"); 25395 element.textContent = fieldFormattedValues ?? textContent; 25396 if (this.data.doNotScroll) { 25397 element.style.overflowY = "hidden"; 25398 } 25399 } else { 25400 element = document.createElement("input"); 25401 element.type = this.data.password ? "password" : "text"; 25402 element.setAttribute("value", fieldFormattedValues ?? textContent); 25403 if (this.data.doNotScroll) { 25404 element.style.overflowX = "hidden"; 25405 } 25406 } 25407 if (this.data.hasOwnCanvas) { 25408 this.container.classList.add("hasOwnCanvas"); 25409 if (storage.has(id)) { 25410 this.container.classList.add("sandboxModified"); 25411 } 25412 } 25413 GetElementsByNameSet.add(element); 25414 this.contentElement = element; 25415 element.setAttribute("data-element-id", id); 25416 element.disabled = this.data.readOnly; 25417 element.name = this.data.fieldName; 25418 element.tabIndex = 0; 25419 const { 25420 datetimeFormat, 25421 datetimeType, 25422 timeStep 25423 } = this.data; 25424 const hasDateOrTime = !!datetimeType && this.enableScripting; 25425 if (datetimeFormat) { 25426 element.title = datetimeFormat; 25427 } 25428 this._setRequired(element, this.data.required); 25429 if (maxLen) { 25430 element.maxLength = maxLen; 25431 } 25432 element.addEventListener("input", event => { 25433 storage.setValue(id, { 25434 value: event.target.value 25435 }); 25436 this.setPropertyOnSiblings(element, "value", event.target.value, "value"); 25437 elementData.formattedValue = null; 25438 }); 25439 element.addEventListener("resetform", event => { 25440 const defaultValue = this.data.defaultFieldValue ?? ""; 25441 element.value = elementData.userValue = defaultValue; 25442 elementData.formattedValue = null; 25443 }); 25444 let blurListener = event => { 25445 const { 25446 formattedValue 25447 } = elementData; 25448 if (formattedValue !== null && formattedValue !== undefined) { 25449 event.target.value = formattedValue; 25450 } 25451 event.target.scrollLeft = 0; 25452 }; 25453 if (this.enableScripting && this.hasJSActions) { 25454 element.addEventListener("focus", event => { 25455 if (elementData.focused) { 25456 return; 25457 } 25458 const { 25459 target 25460 } = event; 25461 if (hasDateOrTime) { 25462 target.type = datetimeType; 25463 if (timeStep) { 25464 target.step = timeStep; 25465 } 25466 } 25467 if (elementData.userValue) { 25468 const value = elementData.userValue; 25469 if (hasDateOrTime) { 25470 if (datetimeType === "time") { 25471 const date = new Date(value); 25472 const parts = [date.getHours(), date.getMinutes(), date.getSeconds()]; 25473 target.value = parts.map(v => v.toString().padStart(2, "0")).join(":"); 25474 } else { 25475 target.value = new Date(value - TIMEZONE_OFFSET).toISOString().split(datetimeType === "date" ? "T" : ".", 1)[0]; 25476 } 25477 } else { 25478 target.value = value; 25479 } 25480 } 25481 elementData.lastCommittedValue = target.value; 25482 elementData.commitKey = 1; 25483 if (!this.data.actions?.has("Focus")) { 25484 elementData.focused = true; 25485 } 25486 }); 25487 element.addEventListener("updatefromsandbox", jsEvent => { 25488 this.container.classList.add("sandboxModified"); 25489 const actions = { 25490 value(event) { 25491 elementData.userValue = event.detail.value ?? ""; 25492 if (!hasDateOrTime) { 25493 storage.setValue(id, { 25494 value: elementData.userValue.toString() 25495 }); 25496 } 25497 event.target.value = elementData.userValue; 25498 }, 25499 formattedValue(event) { 25500 const { 25501 formattedValue 25502 } = event.detail; 25503 elementData.formattedValue = formattedValue; 25504 if (formattedValue !== null && formattedValue !== undefined && event.target !== document.activeElement) { 25505 event.target.value = formattedValue; 25506 } 25507 const data = { 25508 formattedValue 25509 }; 25510 if (hasDateOrTime) { 25511 data.value = formattedValue; 25512 } 25513 storage.setValue(id, data); 25514 }, 25515 selRange(event) { 25516 event.target.setSelectionRange(...event.detail.selRange); 25517 }, 25518 charLimit: event => { 25519 const { 25520 charLimit 25521 } = event.detail; 25522 const { 25523 target 25524 } = event; 25525 if (charLimit === 0) { 25526 target.removeAttribute("maxLength"); 25527 return; 25528 } 25529 target.setAttribute("maxLength", charLimit); 25530 let value = elementData.userValue; 25531 if (!value || value.length <= charLimit) { 25532 return; 25533 } 25534 value = value.slice(0, charLimit); 25535 target.value = elementData.userValue = value; 25536 storage.setValue(id, { 25537 value 25538 }); 25539 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25540 source: this, 25541 detail: { 25542 id, 25543 name: "Keystroke", 25544 value, 25545 willCommit: true, 25546 commitKey: 1, 25547 selStart: target.selectionStart, 25548 selEnd: target.selectionEnd 25549 } 25550 }); 25551 } 25552 }; 25553 this._dispatchEventFromSandbox(actions, jsEvent); 25554 }); 25555 element.addEventListener("keydown", event => { 25556 elementData.commitKey = 1; 25557 let commitKey = -1; 25558 if (event.key === "Escape") { 25559 commitKey = 0; 25560 } else if (event.key === "Enter" && !this.data.multiLine) { 25561 commitKey = 2; 25562 } else if (event.key === "Tab") { 25563 elementData.commitKey = 3; 25564 } 25565 if (commitKey === -1) { 25566 return; 25567 } 25568 const { 25569 value 25570 } = event.target; 25571 if (elementData.lastCommittedValue === value) { 25572 return; 25573 } 25574 elementData.lastCommittedValue = value; 25575 elementData.userValue = value; 25576 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25577 source: this, 25578 detail: { 25579 id, 25580 name: "Keystroke", 25581 value, 25582 willCommit: true, 25583 commitKey, 25584 selStart: event.target.selectionStart, 25585 selEnd: event.target.selectionEnd 25586 } 25587 }); 25588 }); 25589 const _blurListener = blurListener; 25590 blurListener = null; 25591 element.addEventListener("blur", event => { 25592 if (!elementData.focused || !event.relatedTarget) { 25593 return; 25594 } 25595 if (!this.data.actions?.has("Blur")) { 25596 elementData.focused = false; 25597 } 25598 const { 25599 target 25600 } = event; 25601 let { 25602 value 25603 } = target; 25604 if (hasDateOrTime) { 25605 if (value && datetimeType === "time") { 25606 const parts = value.split(":").map(v => parseInt(v, 10)); 25607 value = new Date(2000, 0, 1, parts[0], parts[1], parts[2] || 0).valueOf(); 25608 target.step = ""; 25609 } else { 25610 if (!value.includes("T")) { 25611 value = `${value}T00:00`; 25612 } 25613 value = new Date(value).valueOf(); 25614 } 25615 target.type = "text"; 25616 } 25617 elementData.userValue = value; 25618 if (elementData.lastCommittedValue !== value) { 25619 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25620 source: this, 25621 detail: { 25622 id, 25623 name: "Keystroke", 25624 value, 25625 willCommit: true, 25626 commitKey: elementData.commitKey, 25627 selStart: event.target.selectionStart, 25628 selEnd: event.target.selectionEnd 25629 } 25630 }); 25631 } 25632 _blurListener(event); 25633 }); 25634 if (this.data.actions?.has("Keystroke")) { 25635 element.addEventListener("beforeinput", event => { 25636 elementData.lastCommittedValue = null; 25637 const { 25638 data, 25639 target 25640 } = event; 25641 const { 25642 value, 25643 selectionStart, 25644 selectionEnd 25645 } = target; 25646 let selStart = selectionStart, 25647 selEnd = selectionEnd; 25648 switch (event.inputType) { 25649 case "deleteWordBackward": 25650 { 25651 const wordCharPattern = /\w/; 25652 while (selStart > 0 && !wordCharPattern.test(value[selStart - 1])) { 25653 selStart--; 25654 } 25655 while (selStart > 0 && wordCharPattern.test(value[selStart - 1])) { 25656 selStart--; 25657 } 25658 break; 25659 } 25660 case "deleteWordForward": 25661 { 25662 const match = value.substring(selectionStart).match(/^\W*\w*/); 25663 if (match) { 25664 selEnd += match[0].length; 25665 } 25666 break; 25667 } 25668 case "deleteContentBackward": 25669 if (selectionStart === selectionEnd) { 25670 selStart -= 1; 25671 } 25672 break; 25673 case "deleteContentForward": 25674 if (selectionStart === selectionEnd) { 25675 selEnd += 1; 25676 } 25677 break; 25678 } 25679 event.preventDefault(); 25680 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 25681 source: this, 25682 detail: { 25683 id, 25684 name: "Keystroke", 25685 value, 25686 change: data || "", 25687 willCommit: false, 25688 selStart, 25689 selEnd 25690 } 25691 }); 25692 }); 25693 } 25694 this._setEventListeners(element, elementData, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.value); 25695 } 25696 if (blurListener) { 25697 element.addEventListener("blur", blurListener); 25698 } 25699 if (this.data.comb) { 25700 const fieldWidth = this.data.rect[2] - this.data.rect[0]; 25701 const combWidth = fieldWidth / maxLen; 25702 element.classList.add("comb"); 25703 element.style.setProperty("--comb-width", `calc(${combWidth}px * var(--total-scale-factor))`); 25704 const alignment = this.data.textAlignment; 25705 if (alignment === 1 || alignment === 2) { 25706 const setCombOffset = () => { 25707 const free = maxLen - element.value.length; 25708 element.style.setProperty("--comb-offset", `${alignment === 1 ? free >> 1 : free}`); 25709 }; 25710 setCombOffset(); 25711 for (const evt of ["input", "blur", "resetform", "updatefromsandbox"]) { 25712 element.addEventListener(evt, setCombOffset); 25713 } 25714 } 25715 } 25716 } else { 25717 element = document.createElement("div"); 25718 element.textContent = this.data.fieldValue; 25719 element.style.verticalAlign = "middle"; 25720 element.style.display = "table-cell"; 25721 if (this.data.hasOwnCanvas) { 25722 element.hidden = true; 25723 } 25724 } 25725 this._setTextStyle(element); 25726 this._setBackgroundColor(element); 25727 this._setDefaultPropertiesFromJS(element); 25728 this.container.append(element); 25729 return this.container; 25730 } 25731} 25732class SignatureWidgetAnnotationElement extends WidgetAnnotationElement { 25733 constructor(parameters) { 25734 super(parameters, { 25735 isRenderable: !!parameters.data.hasOwnCanvas 25736 }); 25737 } 25738} 25739class CheckboxWidgetAnnotationElement extends WidgetAnnotationElement { 25740 constructor(parameters) { 25741 super(parameters, { 25742 isRenderable: parameters.renderForms 25743 }); 25744 } 25745 render() { 25746 const storage = this.annotationStorage; 25747 const data = this.data; 25748 const id = data.id; 25749 let value = storage.getValue(id, { 25750 value: data.exportValue === data.fieldValue 25751 }).value; 25752 if (typeof value === "string") { 25753 value = value !== "Off"; 25754 storage.setValue(id, { 25755 value 25756 }); 25757 } 25758 this.container.classList.add("buttonWidgetAnnotation", "checkBox"); 25759 const element = document.createElement("input"); 25760 GetElementsByNameSet.add(element); 25761 element.setAttribute("data-element-id", id); 25762 element.disabled = data.readOnly; 25763 this._setRequired(element, this.data.required); 25764 element.type = "checkbox"; 25765 element.name = data.fieldName; 25766 if (value) { 25767 element.setAttribute("checked", true); 25768 } 25769 element.setAttribute("exportValue", data.exportValue); 25770 element.tabIndex = 0; 25771 element.addEventListener("change", event => { 25772 const { 25773 name, 25774 checked 25775 } = event.target; 25776 for (const checkbox of this._getElementsByName(name, id)) { 25777 const curChecked = checked && checkbox.exportValue === data.exportValue; 25778 if (checkbox.domElement) { 25779 checkbox.domElement.checked = curChecked; 25780 } 25781 storage.setValue(checkbox.id, { 25782 value: curChecked 25783 }); 25784 } 25785 storage.setValue(id, { 25786 value: checked 25787 }); 25788 }); 25789 element.addEventListener("resetform", event => { 25790 const defaultValue = data.defaultFieldValue || "Off"; 25791 event.target.checked = defaultValue === data.exportValue; 25792 }); 25793 if (this.enableScripting && this.hasJSActions) { 25794 element.addEventListener("updatefromsandbox", jsEvent => { 25795 const actions = { 25796 value(event) { 25797 event.target.checked = event.detail.value !== "Off"; 25798 storage.setValue(id, { 25799 value: event.target.checked 25800 }); 25801 } 25802 }; 25803 this._dispatchEventFromSandbox(actions, jsEvent); 25804 }); 25805 this._setEventListeners(element, null, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 25806 } 25807 this._setDefaultPropertiesFromJS(element); 25808 this.container.append(element); 25809 return this.container; 25810 } 25811} 25812class RadioButtonWidgetAnnotationElement extends WidgetAnnotationElement { 25813 constructor(parameters) { 25814 super(parameters, { 25815 isRenderable: parameters.renderForms 25816 }); 25817 } 25818 render() { 25819 this.container.classList.add("buttonWidgetAnnotation", "radioButton"); 25820 const storage = this.annotationStorage; 25821 const data = this.data; 25822 const id = data.id; 25823 let value = storage.getValue(id, { 25824 value: data.buttonValue !== null && data.fieldValue === data.buttonValue 25825 }).value; 25826 if (typeof value === "string") { 25827 value = value !== data.buttonValue; 25828 storage.setValue(id, { 25829 value 25830 }); 25831 } 25832 if (value) { 25833 for (const radio of this._getElementsByName(data.fieldName, id)) { 25834 storage.setValue(radio.id, { 25835 value: false 25836 }); 25837 } 25838 } 25839 const element = document.createElement("input"); 25840 GetElementsByNameSet.add(element); 25841 element.setAttribute("data-element-id", id); 25842 element.disabled = data.readOnly; 25843 this._setRequired(element, this.data.required); 25844 element.type = "radio"; 25845 element.name = data.fieldName; 25846 if (value) { 25847 element.setAttribute("checked", true); 25848 } 25849 element.tabIndex = 0; 25850 element.addEventListener("change", event => { 25851 const { 25852 name, 25853 checked 25854 } = event.target; 25855 for (const radio of this._getElementsByName(name, id)) { 25856 storage.setValue(radio.id, { 25857 value: false 25858 }); 25859 } 25860 storage.setValue(id, { 25861 value: checked 25862 }); 25863 }); 25864 element.addEventListener("resetform", event => { 25865 const defaultValue = data.defaultFieldValue; 25866 event.target.checked = defaultValue !== null && defaultValue !== undefined && defaultValue === data.buttonValue; 25867 }); 25868 if (this.enableScripting && this.hasJSActions) { 25869 const pdfButtonValue = data.buttonValue; 25870 element.addEventListener("updatefromsandbox", jsEvent => { 25871 const actions = { 25872 value: event => { 25873 const checked = pdfButtonValue === event.detail.value; 25874 for (const radio of this._getElementsByName(event.target.name)) { 25875 const curChecked = checked && radio.id === id; 25876 if (radio.domElement) { 25877 radio.domElement.checked = curChecked; 25878 } 25879 storage.setValue(radio.id, { 25880 value: curChecked 25881 }); 25882 } 25883 } 25884 }; 25885 this._dispatchEventFromSandbox(actions, jsEvent); 25886 }); 25887 this._setEventListeners(element, null, [["change", "Validate"], ["change", "Action"], ["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"]], event => event.target.checked); 25888 } 25889 this._setDefaultPropertiesFromJS(element); 25890 this.container.append(element); 25891 return this.container; 25892 } 25893} 25894class PushButtonWidgetAnnotationElement extends LinkAnnotationElement { 25895 constructor(parameters) { 25896 super(parameters, { 25897 ignoreBorder: parameters.data.hasAppearance 25898 }); 25899 } 25900 render() { 25901 const container = super.render(); 25902 container.classList.add("buttonWidgetAnnotation", "pushButton"); 25903 const linkElement = container.lastChild; 25904 if (this.enableScripting && this.hasJSActions && linkElement) { 25905 this._setDefaultPropertiesFromJS(linkElement); 25906 linkElement.addEventListener("updatefromsandbox", jsEvent => { 25907 this._dispatchEventFromSandbox({}, jsEvent); 25908 }); 25909 } 25910 return container; 25911 } 25912} 25913class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement { 25914 constructor(parameters) { 25915 super(parameters, { 25916 isRenderable: parameters.renderForms 25917 }); 25918 } 25919 render() { 25920 this.container.classList.add("choiceWidgetAnnotation"); 25921 const storage = this.annotationStorage; 25922 const id = this.data.id; 25923 const storedData = storage.getValue(id, { 25924 value: this.data.fieldValue 25925 }); 25926 const selectElement = document.createElement("select"); 25927 GetElementsByNameSet.add(selectElement); 25928 selectElement.setAttribute("data-element-id", id); 25929 selectElement.disabled = this.data.readOnly; 25930 this._setRequired(selectElement, this.data.required); 25931 selectElement.name = this.data.fieldName; 25932 selectElement.tabIndex = 0; 25933 let addAnEmptyEntry = this.data.combo && this.data.options.length > 0; 25934 if (!this.data.combo) { 25935 selectElement.size = this.data.options.length; 25936 if (this.data.multiSelect) { 25937 selectElement.multiple = true; 25938 } 25939 } 25940 selectElement.addEventListener("resetform", event => { 25941 const defaultValue = this.data.defaultFieldValue; 25942 for (const option of selectElement.options) { 25943 option.selected = option.value === defaultValue; 25944 } 25945 }); 25946 const fixDisplayValue = (option, value) => { 25947 const newValue = value.replaceAll(" ", "\u00A0"); 25948 option.textContent = newValue; 25949 if (newValue !== value) { 25950 option.setAttribute("display-value", value); 25951 } 25952 }; 25953 for (const option of this.data.options) { 25954 const optionElement = document.createElement("option"); 25955 fixDisplayValue(optionElement, option.displayValue); 25956 optionElement.value = option.exportValue; 25957 if (storedData.value.includes(option.exportValue)) { 25958 optionElement.setAttribute("selected", true); 25959 addAnEmptyEntry = false; 25960 } 25961 selectElement.append(optionElement); 25962 } 25963 let removeEmptyEntry = null; 25964 if (addAnEmptyEntry) { 25965 const noneOptionElement = document.createElement("option"); 25966 noneOptionElement.value = " "; 25967 noneOptionElement.setAttribute("hidden", true); 25968 noneOptionElement.setAttribute("selected", true); 25969 selectElement.prepend(noneOptionElement); 25970 removeEmptyEntry = () => { 25971 noneOptionElement.remove(); 25972 selectElement.removeEventListener("input", removeEmptyEntry); 25973 removeEmptyEntry = null; 25974 }; 25975 selectElement.addEventListener("input", removeEmptyEntry); 25976 } 25977 const getValue = isExport => { 25978 const name = isExport ? "value" : "textContent"; 25979 const { 25980 options, 25981 multiple 25982 } = selectElement; 25983 if (!multiple) { 25984 return options.selectedIndex === -1 ? null : options[options.selectedIndex][name]; 25985 } 25986 return Array.prototype.filter.call(options, option => option.selected).map(option => option[name]); 25987 }; 25988 let selectedValues = getValue(false); 25989 const getItems = event => { 25990 const options = event.target.options; 25991 return Array.prototype.map.call(options, option => ({ 25992 displayValue: option.getAttribute("display-value") || option.textContent, 25993 exportValue: option.value 25994 })); 25995 }; 25996 if (this.enableScripting && this.hasJSActions) { 25997 selectElement.addEventListener("updatefromsandbox", jsEvent => { 25998 const actions = { 25999 value(event) { 26000 removeEmptyEntry?.(); 26001 const value = event.detail.value; 26002 const values = new Set(Array.isArray(value) ? value : [value]); 26003 for (const option of selectElement.options) { 26004 option.selected = values.has(option.value); 26005 } 26006 storage.setValue(id, { 26007 value: getValue(true) 26008 }); 26009 selectedValues = getValue(false); 26010 }, 26011 multipleSelection(event) { 26012 selectElement.multiple = true; 26013 }, 26014 remove(event) { 26015 const options = selectElement.options; 26016 const index = event.detail.remove; 26017 options[index].selected = false; 26018 selectElement.remove(index); 26019 if (options.length > 0) { 26020 const i = Array.prototype.findIndex.call(options, option => option.selected); 26021 if (i === -1) { 26022 options[0].selected = true; 26023 } 26024 } 26025 storage.setValue(id, { 26026 value: getValue(true), 26027 items: getItems(event) 26028 }); 26029 selectedValues = getValue(false); 26030 }, 26031 clear(event) { 26032 while (selectElement.length !== 0) { 26033 selectElement.remove(0); 26034 } 26035 storage.setValue(id, { 26036 value: null, 26037 items: [] 26038 }); 26039 selectedValues = getValue(false); 26040 }, 26041 insert(event) { 26042 const { 26043 index, 26044 displayValue, 26045 exportValue 26046 } = event.detail.insert; 26047 const selectChild = selectElement.children[index]; 26048 const optionElement = document.createElement("option"); 26049 fixDisplayValue(optionElement, displayValue); 26050 optionElement.value = exportValue; 26051 if (selectChild) { 26052 selectChild.before(optionElement); 26053 } else { 26054 selectElement.append(optionElement); 26055 } 26056 storage.setValue(id, { 26057 value: getValue(true), 26058 items: getItems(event) 26059 }); 26060 selectedValues = getValue(false); 26061 }, 26062 items(event) { 26063 const { 26064 items 26065 } = event.detail; 26066 while (selectElement.length !== 0) { 26067 selectElement.remove(0); 26068 } 26069 for (const item of items) { 26070 const { 26071 displayValue, 26072 exportValue 26073 } = item; 26074 const optionElement = document.createElement("option"); 26075 fixDisplayValue(optionElement, displayValue); 26076 optionElement.value = exportValue; 26077 selectElement.append(optionElement); 26078 } 26079 if (selectElement.options.length > 0) { 26080 selectElement.options[0].selected = true; 26081 } 26082 storage.setValue(id, { 26083 value: getValue(true), 26084 items: getItems(event) 26085 }); 26086 selectedValues = getValue(false); 26087 }, 26088 indices(event) { 26089 const indices = new Set(event.detail.indices); 26090 for (const option of event.target.options) { 26091 option.selected = indices.has(option.index); 26092 } 26093 storage.setValue(id, { 26094 value: getValue(true) 26095 }); 26096 selectedValues = getValue(false); 26097 }, 26098 editable(event) { 26099 event.target.disabled = !event.detail.editable; 26100 } 26101 }; 26102 this._dispatchEventFromSandbox(actions, jsEvent); 26103 }); 26104 selectElement.addEventListener("input", event => { 26105 const exportValue = getValue(true); 26106 const change = getValue(false); 26107 storage.setValue(id, { 26108 value: exportValue 26109 }); 26110 event.preventDefault(); 26111 this.linkService.eventBus?.dispatch("dispatcheventinsandbox", { 26112 source: this, 26113 detail: { 26114 id, 26115 name: "Keystroke", 26116 value: selectedValues, 26117 change, 26118 changeEx: exportValue, 26119 willCommit: false, 26120 commitKey: 1, 26121 keyDown: false 26122 } 26123 }); 26124 }); 26125 this._setEventListeners(selectElement, null, [["focus", "Focus"], ["blur", "Blur"], ["mousedown", "Mouse Down"], ["mouseenter", "Mouse Enter"], ["mouseleave", "Mouse Exit"], ["mouseup", "Mouse Up"], ["input", "Action"], ["input", "Validate"]], event => event.target.value); 26126 } else { 26127 selectElement.addEventListener("input", function (event) { 26128 storage.setValue(id, { 26129 value: getValue(true) 26130 }); 26131 }); 26132 } 26133 if (this.data.combo) { 26134 this._setTextStyle(selectElement); 26135 } else {} 26136 this._setBackgroundColor(selectElement); 26137 this._setDefaultPropertiesFromJS(selectElement); 26138 this.container.append(selectElement); 26139 return this.container; 26140 } 26141} 26142class PopupAnnotationElement extends AnnotationElement { 26143 constructor(parameters) { 26144 const { 26145 data, 26146 elements, 26147 parent 26148 } = parameters; 26149 const hasCommentManager = !!parent._commentManager; 26150 super(parameters, { 26151 isRenderable: !hasCommentManager && AnnotationElement._hasPopupData(data) 26152 }); 26153 this.elements = elements; 26154 if (hasCommentManager && AnnotationElement._hasPopupData(data)) { 26155 const popup = this.popup = this.#createPopup(); 26156 for (const element of elements) { 26157 element.popup = popup; 26158 } 26159 } else { 26160 this.popup = null; 26161 } 26162 } 26163 #createPopup() { 26164 return new PopupElement({ 26165 container: this.container, 26166 color: this.data.color, 26167 titleObj: this.data.titleObj, 26168 modificationDate: this.data.modificationDate || this.data.creationDate, 26169 contentsObj: this.data.contentsObj, 26170 richText: this.data.richText, 26171 rect: this.data.rect, 26172 parentRect: this.data.parentRect || null, 26173 parent: this.parent, 26174 elements: this.elements, 26175 open: this.data.open, 26176 commentManager: this.parent._commentManager 26177 }); 26178 } 26179 render() { 26180 const { 26181 container 26182 } = this; 26183 container.classList.add("popupAnnotation"); 26184 container.role = "comment"; 26185 const popup = this.popup = this.#createPopup(); 26186 const elementIds = []; 26187 for (const element of this.elements) { 26188 element.popup = popup; 26189 element.container.ariaHasPopup = "dialog"; 26190 elementIds.push(element.data.id); 26191 element.addHighlightArea(); 26192 } 26193 this.container.setAttribute("aria-controls", elementIds.map(id => `${AnnotationPrefix}${id}`).join(",")); 26194 return this.container; 26195 } 26196} 26197class PopupElement { 26198 #commentManager = null; 26199 #boundKeyDown = this.#keyDown.bind(this); 26200 #boundHide = this.#hide.bind(this); 26201 #boundShow = this.#show.bind(this); 26202 #boundToggle = this.#toggle.bind(this); 26203 #color = null; 26204 #container = null; 26205 #contentsObj = null; 26206 #dateObj = null; 26207 #elements = null; 26208 #parent = null; 26209 #parentRect = null; 26210 #pinned = false; 26211 #popup = null; 26212 #popupAbortController = null; 26213 #position = null; 26214 #commentButton = null; 26215 #commentButtonPosition = null; 26216 #popupPosition = null; 26217 #rect = null; 26218 #richText = null; 26219 #titleObj = null; 26220 #updates = null; 26221 #wasVisible = false; 26222 #firstElement = null; 26223 #commentText = null; 26224 constructor({ 26225 container, 26226 color, 26227 elements, 26228 titleObj, 26229 modificationDate, 26230 contentsObj, 26231 richText, 26232 parent, 26233 rect, 26234 parentRect, 26235 open, 26236 commentManager = null 26237 }) { 26238 this.#container = container; 26239 this.#titleObj = titleObj; 26240 this.#contentsObj = contentsObj; 26241 this.#richText = richText; 26242 this.#parent = parent; 26243 this.#color = color; 26244 this.#rect = rect; 26245 this.#parentRect = parentRect; 26246 this.#elements = elements; 26247 this.#commentManager = commentManager; 26248 this.#firstElement = elements[0]; 26249 this.#dateObj = PDFDateString.toDateObject(modificationDate); 26250 this.trigger = elements.flatMap(e => e.getElementsToTriggerPopup()); 26251 if (!commentManager) { 26252 this.#addEventListeners(); 26253 this.#container.hidden = true; 26254 if (open) { 26255 this.#toggle(); 26256 } 26257 } 26258 } 26259 #addEventListeners() { 26260 if (this.#popupAbortController) { 26261 return; 26262 } 26263 this.#popupAbortController = new AbortController(); 26264 const { 26265 signal 26266 } = this.#popupAbortController; 26267 for (const element of this.trigger) { 26268 element.addEventListener("click", this.#boundToggle, { 26269 signal 26270 }); 26271 element.addEventListener("pointerenter", this.#boundShow, { 26272 signal 26273 }); 26274 element.addEventListener("pointerleave", this.#boundHide, { 26275 signal 26276 }); 26277 element.classList.add("popupTriggerArea"); 26278 } 26279 for (const element of this.#elements) { 26280 element.container?.addEventListener("keydown", this.#boundKeyDown, { 26281 signal 26282 }); 26283 } 26284 } 26285 #setCommentButtonPosition() { 26286 const element = this.#elements.find(e => e.hasCommentButton); 26287 if (!element) { 26288 return; 26289 } 26290 this.#commentButtonPosition = element._normalizePoint(element.commentButtonPosition); 26291 } 26292 renderCommentButton() { 26293 if (this.#commentButton) { 26294 if (!this.#commentButton.parentNode) { 26295 this.#firstElement.container.after(this.#commentButton); 26296 } 26297 return; 26298 } 26299 if (!this.#commentButtonPosition) { 26300 this.#setCommentButtonPosition(); 26301 } 26302 if (!this.#commentButtonPosition) { 26303 return; 26304 } 26305 const { 26306 signal 26307 } = this.#popupAbortController = new AbortController(); 26308 const hasOwnButton = this.#firstElement.hasOwnCommentButton; 26309 const togglePopup = () => { 26310 this.#commentManager.toggleCommentPopup(this, true, undefined, !hasOwnButton); 26311 }; 26312 const showPopup = () => { 26313 this.#commentManager.toggleCommentPopup(this, false, true, !hasOwnButton); 26314 }; 26315 const hidePopup = () => { 26316 this.#commentManager.toggleCommentPopup(this, false, false); 26317 }; 26318 if (!hasOwnButton) { 26319 const button = this.#commentButton = document.createElement("button"); 26320 button.className = "annotationCommentButton"; 26321 const parentContainer = this.#firstElement.container; 26322 button.style.zIndex = parseInt(parentContainer.style.zIndex, 10) + 1; 26323 button.tabIndex = 0; 26324 button.ariaHasPopup = "dialog"; 26325 button.ariaControls = "commentPopup"; 26326 button.setAttribute("data-l10n-id", "pdfjs-show-comment-button"); 26327 this.#updateColor(); 26328 this.#updateCommentButtonPosition(); 26329 button.addEventListener("keydown", this.#boundKeyDown, { 26330 signal 26331 }); 26332 button.addEventListener("click", togglePopup, { 26333 signal 26334 }); 26335 button.addEventListener("pointerenter", showPopup, { 26336 signal 26337 }); 26338 button.addEventListener("pointerleave", hidePopup, { 26339 signal 26340 }); 26341 parentContainer.after(button); 26342 } else { 26343 this.#commentButton = this.#firstElement.container; 26344 for (const element of this.trigger) { 26345 element.ariaHasPopup = "dialog"; 26346 element.ariaControls = "commentPopup"; 26347 element.addEventListener("keydown", this.#boundKeyDown, { 26348 signal 26349 }); 26350 element.addEventListener("click", togglePopup, { 26351 signal 26352 }); 26353 element.addEventListener("pointerenter", showPopup, { 26354 signal 26355 }); 26356 element.addEventListener("pointerleave", hidePopup, { 26357 signal 26358 }); 26359 element.classList.add("popupTriggerArea"); 26360 } 26361 } 26362 } 26363 #updateCommentButtonPosition() { 26364 if (this.#firstElement.extraPopupElement && !this.#firstElement.editor) { 26365 return; 26366 } 26367 if (!this.#commentButton) { 26368 this.renderCommentButton(); 26369 } 26370 const [x, y] = this.#commentButtonPosition; 26371 const { 26372 style 26373 } = this.#commentButton; 26374 style.left = `calc(${x}%)`; 26375 style.top = `calc(${y}% - var(--comment-button-dim))`; 26376 } 26377 #updateColor() { 26378 if (this.#firstElement.extraPopupElement) { 26379 return; 26380 } 26381 if (!this.#commentButton) { 26382 this.renderCommentButton(); 26383 } 26384 this.#commentButton.style.backgroundColor = this.commentButtonColor || ""; 26385 } 26386 get commentButtonColor() { 26387 const { 26388 color, 26389 opacity 26390 } = this.#firstElement.commentData; 26391 if (!color) { 26392 return null; 26393 } 26394 return this.#parent._commentManager.makeCommentColor(color, opacity); 26395 } 26396 focusCommentButton() { 26397 setTimeout(() => { 26398 this.#commentButton?.focus(); 26399 }, 0); 26400 } 26401 getData() { 26402 const { 26403 richText, 26404 color, 26405 opacity, 26406 creationDate, 26407 modificationDate 26408 } = this.#firstElement.commentData; 26409 return { 26410 contentsObj: { 26411 str: this.comment 26412 }, 26413 richText, 26414 color, 26415 opacity, 26416 creationDate, 26417 modificationDate 26418 }; 26419 } 26420 get elementBeforePopup() { 26421 return this.#commentButton; 26422 } 26423 get comment() { 26424 this.#commentText ||= this.#firstElement.commentText; 26425 return this.#commentText; 26426 } 26427 set comment(text) { 26428 if (text === this.comment) { 26429 return; 26430 } 26431 this.#firstElement.commentText = this.#commentText = text; 26432 } 26433 focus() { 26434 this.#firstElement.container?.focus(); 26435 } 26436 get parentBoundingClientRect() { 26437 return this.#firstElement.layer.getBoundingClientRect(); 26438 } 26439 setCommentButtonStates({ 26440 selected, 26441 hasPopup 26442 }) { 26443 if (!this.#commentButton) { 26444 return; 26445 } 26446 this.#commentButton.classList.toggle("selected", selected); 26447 this.#commentButton.ariaExpanded = hasPopup; 26448 } 26449 setSelectedCommentButton(selected) { 26450 this.#commentButton.classList.toggle("selected", selected); 26451 } 26452 get commentPopupPosition() { 26453 if (this.#popupPosition) { 26454 return this.#popupPosition; 26455 } 26456 const { 26457 x, 26458 y, 26459 height 26460 } = this.#commentButton.getBoundingClientRect(); 26461 const { 26462 x: parentX, 26463 y: parentY, 26464 width: parentWidth, 26465 height: parentHeight 26466 } = this.#firstElement.layer.getBoundingClientRect(); 26467 return [(x - parentX) / parentWidth, (y + height - parentY) / parentHeight]; 26468 } 26469 set commentPopupPosition(pos) { 26470 this.#popupPosition = pos; 26471 } 26472 hasDefaultPopupPosition() { 26473 return this.#popupPosition === null; 26474 } 26475 get commentButtonPosition() { 26476 return this.#commentButtonPosition; 26477 } 26478 get commentButtonWidth() { 26479 return this.#commentButton.getBoundingClientRect().width / this.parentBoundingClientRect.width; 26480 } 26481 editComment(options) { 26482 const [posX, posY] = this.#popupPosition || this.commentButtonPosition.map(x => x / 100); 26483 const parentDimensions = this.parentBoundingClientRect; 26484 const { 26485 x: parentX, 26486 y: parentY, 26487 width: parentWidth, 26488 height: parentHeight 26489 } = parentDimensions; 26490 this.#commentManager.showDialog(null, this, parentX + posX * parentWidth, parentY + posY * parentHeight, { 26491 ...options, 26492 parentDimensions 26493 }); 26494 } 26495 render() { 26496 if (this.#popup) { 26497 return; 26498 } 26499 const popup = this.#popup = document.createElement("div"); 26500 popup.className = "popup"; 26501 if (this.#color) { 26502 const baseColor = popup.style.outlineColor = Util.makeHexColor(...this.#color); 26503 popup.style.backgroundColor = `color-mix(in srgb, ${baseColor} 30%, white)`; 26504 } 26505 const header = document.createElement("span"); 26506 header.className = "header"; 26507 if (this.#titleObj?.str) { 26508 const title = document.createElement("span"); 26509 title.className = "title"; 26510 header.append(title); 26511 ({ 26512 dir: title.dir, 26513 str: title.textContent 26514 } = this.#titleObj); 26515 } 26516 popup.append(header); 26517 if (this.#dateObj) { 26518 const modificationDate = document.createElement("time"); 26519 modificationDate.className = "popupDate"; 26520 modificationDate.setAttribute("data-l10n-id", "pdfjs-annotation-date-time-string"); 26521 modificationDate.setAttribute("data-l10n-args", JSON.stringify({ 26522 dateObj: this.#dateObj.valueOf() 26523 })); 26524 modificationDate.dateTime = this.#dateObj.toISOString(); 26525 header.append(modificationDate); 26526 } 26527 renderRichText({ 26528 html: this.#html || this.#contentsObj.str, 26529 dir: this.#contentsObj?.dir, 26530 className: "popupContent" 26531 }, popup); 26532 this.#container.append(popup); 26533 } 26534 get #html() { 26535 const richText = this.#richText; 26536 const contentsObj = this.#contentsObj; 26537 if (richText?.str && (!contentsObj?.str || contentsObj.str === richText.str)) { 26538 return this.#richText.html || null; 26539 } 26540 return null; 26541 } 26542 get #fontSize() { 26543 return this.#html?.attributes?.style?.fontSize || 0; 26544 } 26545 get #fontColor() { 26546 return this.#html?.attributes?.style?.color || null; 26547 } 26548 #makePopupContent(text) { 26549 const popupLines = []; 26550 const popupContent = { 26551 str: text, 26552 html: { 26553 name: "div", 26554 attributes: { 26555 dir: "auto" 26556 }, 26557 children: [{ 26558 name: "p", 26559 children: popupLines 26560 }] 26561 } 26562 }; 26563 const lineAttributes = { 26564 style: { 26565 color: this.#fontColor, 26566 fontSize: this.#fontSize ? `calc(${this.#fontSize}px * var(--total-scale-factor))` : "" 26567 } 26568 }; 26569 for (const line of text.split("\n")) { 26570 popupLines.push({ 26571 name: "span", 26572 value: line, 26573 attributes: lineAttributes 26574 }); 26575 } 26576 return popupContent; 26577 } 26578 #keyDown(event) { 26579 if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) { 26580 return; 26581 } 26582 if (event.key === "Enter" || event.key === "Escape" && this.#pinned) { 26583 this.#toggle(); 26584 } 26585 } 26586 updateEdited({ 26587 rect, 26588 popup, 26589 deleted 26590 }) { 26591 if (this.#commentManager) { 26592 if (deleted) { 26593 this.remove(); 26594 this.#commentText = null; 26595 } else if (popup) { 26596 if (popup.deleted) { 26597 this.remove(); 26598 } else { 26599 this.#updateColor(); 26600 this.#commentText = popup.text; 26601 } 26602 } 26603 if (rect) { 26604 this.#commentButtonPosition = null; 26605 this.#setCommentButtonPosition(); 26606 this.#updateCommentButtonPosition(); 26607 } 26608 return; 26609 } 26610 if (deleted || popup?.deleted) { 26611 this.remove(); 26612 return; 26613 } 26614 this.#addEventListeners(); 26615 this.#updates ||= { 26616 contentsObj: this.#contentsObj, 26617 richText: this.#richText 26618 }; 26619 if (rect) { 26620 this.#position = null; 26621 } 26622 if (popup && popup.text) { 26623 this.#richText = this.#makePopupContent(popup.text); 26624 this.#dateObj = PDFDateString.toDateObject(popup.date); 26625 this.#contentsObj = null; 26626 } 26627 this.#popup?.remove(); 26628 this.#popup = null; 26629 } 26630 resetEdited() { 26631 if (!this.#updates) { 26632 return; 26633 } 26634 ({ 26635 contentsObj: this.#contentsObj, 26636 richText: this.#richText 26637 } = this.#updates); 26638 this.#updates = null; 26639 this.#popup?.remove(); 26640 this.#popup = null; 26641 this.#position = null; 26642 } 26643 remove() { 26644 this.#popupAbortController?.abort(); 26645 this.#popupAbortController = null; 26646 this.#popup?.remove(); 26647 this.#popup = null; 26648 this.#wasVisible = false; 26649 this.#pinned = false; 26650 this.#commentButton?.remove(); 26651 this.#commentButton = null; 26652 if (this.trigger) { 26653 for (const element of this.trigger) { 26654 element.classList.remove("popupTriggerArea"); 26655 } 26656 } 26657 } 26658 #setPosition() { 26659 if (this.#position !== null) { 26660 return; 26661 } 26662 const { 26663 page: { 26664 view 26665 }, 26666 viewport: { 26667 rawDims: { 26668 pageWidth, 26669 pageHeight, 26670 pageX, 26671 pageY 26672 } 26673 } 26674 } = this.#parent; 26675 let useParentRect = !!this.#parentRect; 26676 let rect = useParentRect ? this.#parentRect : this.#rect; 26677 for (const element of this.#elements) { 26678 if (!rect || Util.intersect(element.data.rect, rect) !== null) { 26679 rect = element.data.rect; 26680 useParentRect = true; 26681 break; 26682 } 26683 } 26684 const normalizedRect = Util.normalizeRect([rect[0], view[3] - rect[1] + view[1], rect[2], view[3] - rect[3] + view[1]]); 26685 const HORIZONTAL_SPACE_AFTER_ANNOTATION = 5; 26686 const parentWidth = useParentRect ? rect[2] - rect[0] + HORIZONTAL_SPACE_AFTER_ANNOTATION : 0; 26687 const popupLeft = normalizedRect[0] + parentWidth; 26688 const popupTop = normalizedRect[1]; 26689 this.#position = [100 * (popupLeft - pageX) / pageWidth, 100 * (popupTop - pageY) / pageHeight]; 26690 const { 26691 style 26692 } = this.#container; 26693 style.left = `${this.#position[0]}%`; 26694 style.top = `${this.#position[1]}%`; 26695 } 26696 #toggle() { 26697 if (this.#commentManager) { 26698 this.#commentManager.toggleCommentPopup(this, false); 26699 return; 26700 } 26701 this.#pinned = !this.#pinned; 26702 if (this.#pinned) { 26703 this.#show(); 26704 this.#container.addEventListener("click", this.#boundToggle); 26705 this.#container.addEventListener("keydown", this.#boundKeyDown); 26706 } else { 26707 this.#hide(); 26708 this.#container.removeEventListener("click", this.#boundToggle); 26709 this.#container.removeEventListener("keydown", this.#boundKeyDown); 26710 } 26711 } 26712 #show() { 26713 if (!this.#popup) { 26714 this.render(); 26715 } 26716 if (!this.isVisible) { 26717 this.#setPosition(); 26718 this.#container.hidden = false; 26719 this.#container.style.zIndex = parseInt(this.#container.style.zIndex, 10) + 1000; 26720 } else if (this.#pinned) { 26721 this.#container.classList.add("focused"); 26722 } 26723 } 26724 #hide() { 26725 this.#container.classList.remove("focused"); 26726 if (this.#pinned || !this.isVisible) { 26727 return; 26728 } 26729 this.#container.hidden = true; 26730 this.#container.style.zIndex = parseInt(this.#container.style.zIndex, 10) - 1000; 26731 } 26732 forceHide() { 26733 this.#wasVisible = this.isVisible; 26734 if (!this.#wasVisible) { 26735 return; 26736 } 26737 this.#container.hidden = true; 26738 } 26739 maybeShow() { 26740 if (this.#commentManager) { 26741 return; 26742 } 26743 this.#addEventListeners(); 26744 if (!this.#wasVisible) { 26745 return; 26746 } 26747 if (!this.#popup) { 26748 this.#show(); 26749 } 26750 this.#wasVisible = false; 26751 this.#container.hidden = false; 26752 } 26753 get isVisible() { 26754 return !this.#commentManager && this.#container.hidden === false; 26755 } 26756} 26757class FreeTextAnnotationElement extends AnnotationElement { 26758 constructor(parameters) { 26759 super(parameters, { 26760 isRenderable: true, 26761 ignoreBorder: true 26762 }); 26763 this.textContent = parameters.data.textContent; 26764 this.textPosition = parameters.data.textPosition; 26765 this.annotationEditorType = AnnotationEditorType.FREETEXT; 26766 } 26767 render() { 26768 this.container.classList.add("freeTextAnnotation"); 26769 if (this.textContent) { 26770 const content = this.contentElement = document.createElement("div"); 26771 content.classList.add("annotationTextContent"); 26772 content.setAttribute("role", "comment"); 26773 for (const line of this.textContent) { 26774 const lineSpan = document.createElement("span"); 26775 lineSpan.textContent = line; 26776 content.append(lineSpan); 26777 } 26778 this.container.append(content); 26779 } 26780 if (!this.data.popupRef && this.hasPopupData) { 26781 this.hasOwnCommentButton = true; 26782 this._createPopup(); 26783 } 26784 this._editOnDoubleClick(); 26785 return this.container; 26786 } 26787} 26788class LineAnnotationElement extends AnnotationElement { 26789 #line = null; 26790 constructor(parameters) { 26791 super(parameters, { 26792 isRenderable: true, 26793 ignoreBorder: true 26794 }); 26795 } 26796 render() { 26797 this.container.classList.add("lineAnnotation"); 26798 const { 26799 data, 26800 width, 26801 height 26802 } = this; 26803 const svg = this.svgFactory.create(width, height, true); 26804 const line = this.#line = this.svgFactory.createElement("svg:line"); 26805 line.setAttribute("x1", data.rect[2] - data.lineCoordinates[0]); 26806 line.setAttribute("y1", data.rect[3] - data.lineCoordinates[1]); 26807 line.setAttribute("x2", data.rect[2] - data.lineCoordinates[2]); 26808 line.setAttribute("y2", data.rect[3] - data.lineCoordinates[3]); 26809 line.setAttribute("stroke-width", data.borderStyle.width || 1); 26810 line.setAttribute("stroke", "transparent"); 26811 line.setAttribute("fill", "transparent"); 26812 svg.append(line); 26813 this.container.append(svg); 26814 if (!data.popupRef && this.hasPopupData) { 26815 this.hasOwnCommentButton = true; 26816 this._createPopup(); 26817 } 26818 return this.container; 26819 } 26820 getElementsToTriggerPopup() { 26821 return this.#line; 26822 } 26823 addHighlightArea() { 26824 this.container.classList.add("highlightArea"); 26825 } 26826} 26827class SquareAnnotationElement extends AnnotationElement { 26828 #square = null; 26829 constructor(parameters) { 26830 super(parameters, { 26831 isRenderable: true, 26832 ignoreBorder: true 26833 }); 26834 } 26835 render() { 26836 this.container.classList.add("squareAnnotation"); 26837 const { 26838 data, 26839 width, 26840 height 26841 } = this; 26842 const svg = this.svgFactory.create(width, height, true); 26843 const borderWidth = data.borderStyle.width; 26844 const square = this.#square = this.svgFactory.createElement("svg:rect"); 26845 square.setAttribute("x", borderWidth / 2); 26846 square.setAttribute("y", borderWidth / 2); 26847 square.setAttribute("width", width - borderWidth); 26848 square.setAttribute("height", height - borderWidth); 26849 square.setAttribute("stroke-width", borderWidth || 1); 26850 square.setAttribute("stroke", "transparent"); 26851 square.setAttribute("fill", "transparent"); 26852 svg.append(square); 26853 this.container.append(svg); 26854 if (!data.popupRef && this.hasPopupData) { 26855 this.hasOwnCommentButton = true; 26856 this._createPopup(); 26857 } 26858 return this.container; 26859 } 26860 getElementsToTriggerPopup() { 26861 return this.#square; 26862 } 26863 addHighlightArea() { 26864 this.container.classList.add("highlightArea"); 26865 } 26866} 26867class CircleAnnotationElement extends AnnotationElement { 26868 #circle = null; 26869 constructor(parameters) { 26870 super(parameters, { 26871 isRenderable: true, 26872 ignoreBorder: true 26873 }); 26874 } 26875 render() { 26876 this.container.classList.add("circleAnnotation"); 26877 const { 26878 data, 26879 width, 26880 height 26881 } = this; 26882 const svg = this.svgFactory.create(width, height, true); 26883 const borderWidth = data.borderStyle.width; 26884 const circle = this.#circle = this.svgFactory.createElement("svg:ellipse"); 26885 circle.setAttribute("cx", width / 2); 26886 circle.setAttribute("cy", height / 2); 26887 circle.setAttribute("rx", width / 2 - borderWidth / 2); 26888 circle.setAttribute("ry", height / 2 - borderWidth / 2); 26889 circle.setAttribute("stroke-width", borderWidth || 1); 26890 circle.setAttribute("stroke", "transparent"); 26891 circle.setAttribute("fill", "transparent"); 26892 svg.append(circle); 26893 this.container.append(svg); 26894 if (!data.popupRef && this.hasPopupData) { 26895 this.hasOwnCommentButton = true; 26896 this._createPopup(); 26897 } 26898 return this.container; 26899 } 26900 getElementsToTriggerPopup() { 26901 return this.#circle; 26902 } 26903 addHighlightArea() { 26904 this.container.classList.add("highlightArea"); 26905 } 26906} 26907class PolylineAnnotationElement extends AnnotationElement { 26908 #polyline = null; 26909 constructor(parameters) { 26910 super(parameters, { 26911 isRenderable: true, 26912 ignoreBorder: true 26913 }); 26914 this.containerClassName = "polylineAnnotation"; 26915 this.svgElementName = "svg:polyline"; 26916 } 26917 render() { 26918 this.container.classList.add(this.containerClassName); 26919 const { 26920 data: { 26921 rect, 26922 vertices, 26923 borderStyle, 26924 popupRef 26925 }, 26926 width, 26927 height 26928 } = this; 26929 if (!vertices) { 26930 return this.container; 26931 } 26932 const svg = this.svgFactory.create(width, height, true); 26933 let points = []; 26934 for (let i = 0, ii = vertices.length; i < ii; i += 2) { 26935 const x = vertices[i] - rect[0]; 26936 const y = rect[3] - vertices[i + 1]; 26937 points.push(`${x},${y}`); 26938 } 26939 points = points.join(" "); 26940 const polyline = this.#polyline = this.svgFactory.createElement(this.svgElementName); 26941 polyline.setAttribute("points", points); 26942 polyline.setAttribute("stroke-width", borderStyle.width || 1); 26943 polyline.setAttribute("stroke", "transparent"); 26944 polyline.setAttribute("fill", "transparent"); 26945 svg.append(polyline); 26946 this.container.append(svg); 26947 if (!popupRef && this.hasPopupData) { 26948 this.hasOwnCommentButton = true; 26949 this._createPopup(); 26950 } 26951 return this.container; 26952 } 26953 getElementsToTriggerPopup() { 26954 return this.#polyline; 26955 } 26956 addHighlightArea() { 26957 this.container.classList.add("highlightArea"); 26958 } 26959} 26960class PolygonAnnotationElement extends PolylineAnnotationElement { 26961 constructor(parameters) { 26962 super(parameters); 26963 this.containerClassName = "polygonAnnotation"; 26964 this.svgElementName = "svg:polygon"; 26965 } 26966} 26967class CaretAnnotationElement extends AnnotationElement { 26968 constructor(parameters) { 26969 super(parameters, { 26970 isRenderable: true, 26971 ignoreBorder: true 26972 }); 26973 } 26974 render() { 26975 this.container.classList.add("caretAnnotation"); 26976 if (!this.data.popupRef && this.hasPopupData) { 26977 this.hasOwnCommentButton = true; 26978 this._createPopup(); 26979 } 26980 return this.container; 26981 } 26982} 26983class InkAnnotationElement extends AnnotationElement { 26984 #polylinesGroupElement = null; 26985 #polylines = []; 26986 constructor(parameters) { 26987 super(parameters, { 26988 isRenderable: true, 26989 ignoreBorder: true 26990 }); 26991 this.containerClassName = "inkAnnotation"; 26992 this.svgElementName = "svg:polyline"; 26993 this.annotationEditorType = this.data.it === "InkHighlight" ? AnnotationEditorType.HIGHLIGHT : AnnotationEditorType.INK; 26994 } 26995 #getTransform(rotation, rect) { 26996 switch (rotation) { 26997 case 90: 26998 return { 26999 transform: `rotate(90) translate(${-rect[0]},${rect[1]}) scale(1,-1)`, 27000 width: rect[3] - rect[1], 27001 height: rect[2] - rect[0] 27002 }; 27003 case 180: 27004 return { 27005 transform: `rotate(180) translate(${-rect[2]},${rect[1]}) scale(1,-1)`, 27006 width: rect[2] - rect[0], 27007 height: rect[3] - rect[1] 27008 }; 27009 case 270: 27010 return { 27011 transform: `rotate(270) translate(${-rect[2]},${rect[3]}) scale(1,-1)`, 27012 width: rect[3] - rect[1], 27013 height: rect[2] - rect[0] 27014 }; 27015 default: 27016 return { 27017 transform: `translate(${-rect[0]},${rect[3]}) scale(1,-1)`, 27018 width: rect[2] - rect[0], 27019 height: rect[3] - rect[1] 27020 }; 27021 } 27022 } 27023 render() { 27024 this.container.classList.add(this.containerClassName); 27025 const { 27026 data: { 27027 rect, 27028 rotation, 27029 inkLists, 27030 borderStyle, 27031 popupRef 27032 } 27033 } = this; 27034 const { 27035 transform, 27036 width, 27037 height 27038 } = this.#getTransform(rotation, rect); 27039 const svg = this.svgFactory.create(width, height, true); 27040 const g = this.#polylinesGroupElement = this.svgFactory.createElement("svg:g"); 27041 svg.append(g); 27042 g.setAttribute("stroke-width", borderStyle.width || 1); 27043 g.setAttribute("stroke-linecap", "round"); 27044 g.setAttribute("stroke-linejoin", "round"); 27045 g.setAttribute("stroke-miterlimit", 10); 27046 g.setAttribute("stroke", "transparent"); 27047 g.setAttribute("fill", "transparent"); 27048 g.setAttribute("transform", transform); 27049 for (const inkList of inkLists) { 27050 const polyline = this.svgFactory.createElement(this.svgElementName); 27051 this.#polylines.push(polyline); 27052 polyline.setAttribute("points", inkList.join(",")); 27053 g.append(polyline); 27054 } 27055 if (!popupRef && this.hasPopupData) { 27056 this.hasOwnCommentButton = true; 27057 this._createPopup(); 27058 } 27059 this.container.append(svg); 27060 this._editOnDoubleClick(); 27061 return this.container; 27062 } 27063 updateEdited(params) { 27064 super.updateEdited(params); 27065 const { 27066 thickness, 27067 points, 27068 rect 27069 } = params; 27070 const g = this.#polylinesGroupElement; 27071 if (thickness >= 0) { 27072 g.setAttribute("stroke-width", thickness || 1); 27073 } 27074 if (points) { 27075 for (let i = 0, ii = this.#polylines.length; i < ii; i++) { 27076 this.#polylines[i].setAttribute("points", points[i].join(",")); 27077 } 27078 } 27079 if (rect) { 27080 const { 27081 transform, 27082 width, 27083 height 27084 } = this.#getTransform(this.data.rotation, rect); 27085 const root = g.parentElement; 27086 root.setAttribute("viewBox", `0 0 ${width} ${height}`); 27087 g.setAttribute("transform", transform); 27088 } 27089 } 27090 getElementsToTriggerPopup() { 27091 return this.#polylines; 27092 } 27093 addHighlightArea() { 27094 this.container.classList.add("highlightArea"); 27095 } 27096} 27097class HighlightAnnotationElement extends AnnotationElement { 27098 constructor(parameters) { 27099 super(parameters, { 27100 isRenderable: true, 27101 ignoreBorder: true, 27102 createQuadrilaterals: true 27103 }); 27104 this.annotationEditorType = AnnotationEditorType.HIGHLIGHT; 27105 } 27106 render() { 27107 const { 27108 data: { 27109 overlaidText, 27110 popupRef 27111 } 27112 } = this; 27113 if (!popupRef && this.hasPopupData) { 27114 this.hasOwnCommentButton = true; 27115 this._createPopup(); 27116 } 27117 this.container.classList.add("highlightAnnotation"); 27118 this._editOnDoubleClick(); 27119 if (overlaidText) { 27120 const mark = document.createElement("mark"); 27121 mark.classList.add("overlaidText"); 27122 mark.textContent = overlaidText; 27123 this.container.append(mark); 27124 } 27125 return this.container; 27126 } 27127} 27128class UnderlineAnnotationElement extends AnnotationElement { 27129 constructor(parameters) { 27130 super(parameters, { 27131 isRenderable: true, 27132 ignoreBorder: true, 27133 createQuadrilaterals: true 27134 }); 27135 } 27136 render() { 27137 const { 27138 data: { 27139 overlaidText, 27140 popupRef 27141 } 27142 } = this; 27143 if (!popupRef && this.hasPopupData) { 27144 this.hasOwnCommentButton = true; 27145 this._createPopup(); 27146 } 27147 this.container.classList.add("underlineAnnotation"); 27148 if (overlaidText) { 27149 const underline = document.createElement("u"); 27150 underline.classList.add("overlaidText"); 27151 underline.textContent = overlaidText; 27152 this.container.append(underline); 27153 } 27154 return this.container; 27155 } 27156} 27157class SquigglyAnnotationElement extends AnnotationElement { 27158 constructor(parameters) { 27159 super(parameters, { 27160 isRenderable: true, 27161 ignoreBorder: true, 27162 createQuadrilaterals: true 27163 }); 27164 } 27165 render() { 27166 const { 27167 data: { 27168 overlaidText, 27169 popupRef 27170 } 27171 } = this; 27172 if (!popupRef && this.hasPopupData) { 27173 this.hasOwnCommentButton = true; 27174 this._createPopup(); 27175 } 27176 this.container.classList.add("squigglyAnnotation"); 27177 if (overlaidText) { 27178 const underline = document.createElement("u"); 27179 underline.classList.add("overlaidText"); 27180 underline.textContent = overlaidText; 27181 this.container.append(underline); 27182 } 27183 return this.container; 27184 } 27185} 27186class StrikeOutAnnotationElement extends AnnotationElement { 27187 constructor(parameters) { 27188 super(parameters, { 27189 isRenderable: true, 27190 ignoreBorder: true, 27191 createQuadrilaterals: true 27192 }); 27193 } 27194 render() { 27195 const { 27196 data: { 27197 overlaidText, 27198 popupRef 27199 } 27200 } = this; 27201 if (!popupRef && this.hasPopupData) { 27202 this.hasOwnCommentButton = true; 27203 this._createPopup(); 27204 } 27205 this.container.classList.add("strikeoutAnnotation"); 27206 if (overlaidText) { 27207 const strikeout = document.createElement("s"); 27208 strikeout.classList.add("overlaidText"); 27209 strikeout.textContent = overlaidText; 27210 this.container.append(strikeout); 27211 } 27212 return this.container; 27213 } 27214} 27215class StampAnnotationElement extends AnnotationElement { 27216 constructor(parameters) { 27217 super(parameters, { 27218 isRenderable: true, 27219 ignoreBorder: true 27220 }); 27221 this.annotationEditorType = AnnotationEditorType.STAMP; 27222 } 27223 render() { 27224 this.container.classList.add("stampAnnotation"); 27225 this.container.setAttribute("role", "img"); 27226 if (!this.data.popupRef && this.hasPopupData) { 27227 this.hasOwnCommentButton = true; 27228 this._createPopup(); 27229 } 27230 this._editOnDoubleClick(); 27231 return this.container; 27232 } 27233} 27234class FileAttachmentAnnotationElement extends AnnotationElement { 27235 #trigger = null; 27236 constructor(parameters) { 27237 super(parameters, { 27238 isRenderable: true 27239 }); 27240 const { 27241 fileId, 27242 file 27243 } = this.data; 27244 this.filename = file.filename; 27245 this.content = file.content; 27246 this.fileId = fileId; 27247 this.linkService.eventBus?.dispatch("fileattachmentannotation", { 27248 source: this, 27249 attachmentId: this.fileId, 27250 ...file 27251 }); 27252 } 27253 render() { 27254 this.container.classList.add("fileAttachmentAnnotation"); 27255 const { 27256 container, 27257 data 27258 } = this; 27259 let trigger; 27260 if (data.hasAppearance || data.fillAlpha === 0) { 27261 trigger = document.createElement("div"); 27262 } else { 27263 trigger = document.createElement("img"); 27264 trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(data.name) ? "paperclip" : "pushpin"}.svg`; 27265 if (data.fillAlpha && data.fillAlpha < 1) { 27266 trigger.style = `filter: opacity(${Math.round(data.fillAlpha * 100)}%);`; 27267 } 27268 } 27269 trigger.addEventListener("dblclick", this.#download.bind(this)); 27270 this.#trigger = trigger; 27271 const { 27272 isMac 27273 } = FeatureTest.platform; 27274 container.addEventListener("keydown", evt => { 27275 if (evt.key === "Enter" && (isMac ? evt.metaKey : evt.ctrlKey)) { 27276 this.#download(); 27277 } 27278 }); 27279 if (!data.popupRef && this.hasPopupData) { 27280 this.hasOwnCommentButton = true; 27281 this._createPopup(); 27282 } else { 27283 trigger.classList.add("popupTriggerArea"); 27284 } 27285 container.append(trigger); 27286 return container; 27287 } 27288 getElementsToTriggerPopup() { 27289 return this.#trigger; 27290 } 27291 addHighlightArea() { 27292 this.container.classList.add("highlightArea"); 27293 } 27294 async #download() { 27295 const { 27296 fileId, 27297 filename, 27298 content: fallbackContent 27299 } = this; 27300 const content = (await this.linkService.getAttachmentContent(fileId)) || fallbackContent; 27301 if (content) { 27302 this.downloadManager?.openOrDownloadData(content, filename); 27303 } 27304 } 27305} 27306class MediaAnnotationElement extends AnnotationElement { 27307 #abortController = new AbortController(); 27308 #contentUrl = null; 27309 #media = null; 27310 constructor(parameters) { 27311 super(parameters, { 27312 isRenderable: !!parameters.data.richMedia 27313 }); 27314 } 27315 render() { 27316 this.container.classList.add("mediaAnnotation"); 27317 const { 27318 filename 27319 } = this.data.richMedia; 27320 const button = document.createElement("button"); 27321 button.className = "mediaPlayButton"; 27322 button.type = "button"; 27323 button.title = button.ariaLabel = filename; 27324 button.addEventListener("click", () => this.#load(button), { 27325 signal: this.#abortController.signal 27326 }); 27327 this.container.append(button); 27328 return this.container; 27329 } 27330 async #load(button) { 27331 const { 27332 fileId, 27333 filename, 27334 contentType 27335 } = this.data.richMedia; 27336 button.disabled = true; 27337 let content; 27338 try { 27339 content = await this.linkService.getAttachmentContent(fileId); 27340 } catch { 27341 return; 27342 } finally { 27343 button.disabled = false; 27344 } 27345 if (!content || !button.isConnected) { 27346 return; 27347 } 27348 const { 27349 signal 27350 } = this.#abortController; 27351 const url = URL.createObjectURL(new Blob([content], { 27352 type: contentType 27353 })); 27354 this.#contentUrl = url; 27355 const isAudio = contentType.startsWith("audio/"); 27356 const media = document.createElement(isAudio ? "audio" : "video"); 27357 this.#media = media; 27358 media.className = "mediaContent"; 27359 this._setBackgroundColor(media); 27360 media.src = url; 27361 media.title = filename; 27362 media.controls = true; 27363 media.autoplay = true; 27364 media.tabIndex = 0; 27365 if (isAudio) { 27366 let hovered = false; 27367 let focused = false; 27368 const updateControls = () => { 27369 media.controls = hovered || focused; 27370 }; 27371 this.container.addEventListener("pointerenter", () => { 27372 hovered = true; 27373 updateControls(); 27374 }, { 27375 signal 27376 }); 27377 this.container.addEventListener("pointerleave", () => { 27378 hovered = false; 27379 updateControls(); 27380 }, { 27381 signal 27382 }); 27383 this.container.addEventListener("focusin", () => { 27384 focused = true; 27385 updateControls(); 27386 }, { 27387 signal 27388 }); 27389 this.container.addEventListener("focusout", () => { 27390 focused = false; 27391 updateControls(); 27392 }, { 27393 signal 27394 }); 27395 } 27396 media.addEventListener("emptied", () => this.#revokeContentUrl(url), { 27397 once: true, 27398 signal 27399 }); 27400 button.replaceWith(media); 27401 media.play().catch(() => {}); 27402 } 27403 #revokeContentUrl(url = this.#contentUrl) { 27404 if (url && url === this.#contentUrl) { 27405 URL.revokeObjectURL(url); 27406 this.#contentUrl = null; 27407 } 27408 } 27409 destroy() { 27410 this.#abortController.abort(); 27411 if (this.#media) { 27412 this.#media.pause(); 27413 this.#media.removeAttribute("src"); 27414 this.#media.load(); 27415 this.#media = null; 27416 } 27417 this.#revokeContentUrl(); 27418 } 27419} 27420class AnnotationLayer { 27421 #accessibilityManager = null; 27422 #annotationCanvasMap = null; 27423 #annotationStorage = null; 27424 #editableAnnotations = new Map(); 27425 #structTreeLayer = null; 27426 #linkService = null; 27427 #elements = []; 27428 #hasAriaAttributesFromStructTree = false; 27429 zIndex = 0; 27430 constructor({ 27431 div, 27432 accessibilityManager, 27433 annotationCanvasMap, 27434 annotationEditorUIManager, 27435 page, 27436 viewport, 27437 structTreeLayer, 27438 commentManager, 27439 linkService, 27440 annotationStorage 27441 }) { 27442 this.div = div; 27443 this.#accessibilityManager = accessibilityManager; 27444 this.#annotationCanvasMap = annotationCanvasMap; 27445 this.#structTreeLayer = structTreeLayer || null; 27446 this.#linkService = linkService || null; 27447 this.#annotationStorage = annotationStorage || new AnnotationStorage(); 27448 this.page = page; 27449 this.viewport = viewport; 27450 this._annotationEditorUIManager = annotationEditorUIManager; 27451 this._commentManager = commentManager || null; 27452 } 27453 hasEditableAnnotations() { 27454 return this.#editableAnnotations.size > 0; 27455 } 27456 async render(params) { 27457 const { 27458 annotations, 27459 optionalContentConfig 27460 } = params; 27461 const layer = this.div; 27462 setLayerDimensions(layer, this.viewport); 27463 const popupToElements = new Map(); 27464 const popupAnnotations = []; 27465 const elementParams = { 27466 data: null, 27467 layer, 27468 linkService: this.#linkService, 27469 downloadManager: params.downloadManager, 27470 imageResourcesPath: params.imageResourcesPath || "", 27471 renderForms: params.renderForms !== false, 27472 svgFactory: new DOMSVGFactory(), 27473 annotationStorage: this.#annotationStorage, 27474 enableComment: params.enableComment === true, 27475 enableScripting: params.enableScripting === true, 27476 hasJSActions: params.hasJSActions, 27477 fieldObjects: params.fieldObjects, 27478 parent: this, 27479 elements: null 27480 }; 27481 for (const data of annotations) { 27482 if (data.noHTML) { 27483 continue; 27484 } 27485 const isPopupAnnotation = data.annotationType === AnnotationType.POPUP; 27486 if (!isPopupAnnotation) { 27487 if (data.rect[2] === data.rect[0] || data.rect[3] === data.rect[1]) { 27488 continue; 27489 } 27490 } else { 27491 const elements = popupToElements.get(data.id); 27492 if (!elements) { 27493 continue; 27494 } 27495 if (!this._commentManager) { 27496 popupAnnotations.push(data); 27497 continue; 27498 } 27499 elementParams.elements = elements; 27500 } 27501 elementParams.data = data; 27502 const element = AnnotationElementFactory.create(elementParams); 27503 if (!element.isRenderable) { 27504 continue; 27505 } 27506 if (!isPopupAnnotation) { 27507 this.#elements.push(element); 27508 if (data.popupRef) { 27509 popupToElements.getOrInsertComputed(data.popupRef, makeArr).push(element); 27510 } 27511 } 27512 const rendered = element.render(); 27513 if (data.hidden) { 27514 rendered.style.visibility = "hidden"; 27515 } 27516 element.updateOC(optionalContentConfig); 27517 if (element._isEditable) { 27518 this.#editableAnnotations.set(element.data.id, element); 27519 this._annotationEditorUIManager?.renderAnnotationElement(element); 27520 } 27521 } 27522 await this.#addElementsToDOM(); 27523 for (const data of popupAnnotations) { 27524 const elements = elementParams.elements = popupToElements.get(data.id); 27525 elementParams.data = data; 27526 const element = AnnotationElementFactory.create(elementParams); 27527 if (!element.isRenderable) { 27528 continue; 27529 } 27530 const rendered = element.render(); 27531 element.contentElement.id = `${AnnotationPrefix}${data.id}`; 27532 if (data.hidden) { 27533 rendered.style.visibility = "hidden"; 27534 } 27535 elements.at(-1).container.after(rendered); 27536 } 27537 this.#setAnnotationCanvasMap(); 27538 } 27539 async #addElementsToDOM() { 27540 if (this.#elements.length === 0) { 27541 return; 27542 } 27543 this.div.replaceChildren(); 27544 const promises = []; 27545 if (!this.#hasAriaAttributesFromStructTree) { 27546 this.#hasAriaAttributesFromStructTree = true; 27547 for (const { 27548 contentElement, 27549 data: { 27550 hidden, 27551 id, 27552 oc 27553 } 27554 } of this.#elements) { 27555 const annotationId = contentElement.id = `${AnnotationPrefix}${id}`; 27556 const enableLinkOwnership = contentElement.localName === "a" && !hidden && !oc; 27557 promises.push(this.#structTreeLayer?.getAriaAttributes(annotationId, { 27558 enableLinkOwnership 27559 }).then(ariaAttributes => { 27560 if (ariaAttributes) { 27561 for (const [key, value] of ariaAttributes) { 27562 contentElement.setAttribute(key, value); 27563 } 27564 } 27565 })); 27566 } 27567 } 27568 this.#elements.sort(({ 27569 data: { 27570 rect: [a0, a1, a2, a3] 27571 } 27572 }, { 27573 data: { 27574 rect: [b0, b1, b2, b3] 27575 } 27576 }) => { 27577 if (a0 === a2 && a1 === a3) { 27578 return +1; 27579 } 27580 if (b0 === b2 && b1 === b3) { 27581 return -1; 27582 } 27583 const top1 = a3; 27584 const bot1 = a1; 27585 const mid1 = (a1 + a3) / 2; 27586 const top2 = b3; 27587 const bot2 = b1; 27588 const mid2 = (b1 + b3) / 2; 27589 if (mid1 >= top2 && mid2 <= bot1) { 27590 return -1; 27591 } 27592 if (mid2 >= top1 && mid1 <= bot2) { 27593 return +1; 27594 } 27595 const centerX1 = (a0 + a2) / 2; 27596 const centerX2 = (b0 + b2) / 2; 27597 return centerX1 - centerX2; 27598 }); 27599 const fragment = document.createDocumentFragment(); 27600 for (const element of this.#elements) { 27601 fragment.append(element.container); 27602 if (this._commentManager) { 27603 (element.extraPopupElement?.popup || element.popup)?.renderCommentButton(); 27604 } else if (element.extraPopupElement) { 27605 fragment.append(element.extraPopupElement.render()); 27606 } 27607 } 27608 this.div.append(fragment); 27609 await Promise.all(promises); 27610 if (this.#accessibilityManager) { 27611 const annotationIds = await this.#structTreeLayer?.getAnnotationIds(); 27612 for (const { 27613 contentElement 27614 } of this.#elements) { 27615 if (annotationIds?.has(contentElement.id)) { 27616 continue; 27617 } 27618 this.#accessibilityManager.addPointerInTextLayer(contentElement, false); 27619 } 27620 } 27621 } 27622 async addLinkAnnotations(annotations) { 27623 const elementParams = { 27624 data: null, 27625 layer: this.div, 27626 linkService: this.#linkService, 27627 svgFactory: new DOMSVGFactory(), 27628 parent: this 27629 }; 27630 for (const data of annotations) { 27631 data.borderStyle ||= AnnotationLayer._defaultBorderStyle; 27632 elementParams.data = data; 27633 const element = AnnotationElementFactory.create(elementParams); 27634 if (!element.isRenderable) { 27635 continue; 27636 } 27637 element.render(); 27638 element.contentElement.id = `${AnnotationPrefix}${data.id}`; 27639 this.#elements.push(element); 27640 } 27641 await this.#addElementsToDOM(); 27642 } 27643 update({ 27644 viewport, 27645 optionalContentConfig 27646 }) { 27647 const layer = this.div; 27648 this.viewport = viewport; 27649 setLayerDimensions(layer, { 27650 rotation: viewport.rotation 27651 }); 27652 for (const element of this.#elements) { 27653 element.updateOC(optionalContentConfig); 27654 } 27655 this.#setAnnotationCanvasMap(); 27656 layer.hidden = false; 27657 } 27658 destroy() { 27659 for (const element of this.#elements) { 27660 element.destroy?.(); 27661 this.#accessibilityManager?.removePointerInTextLayer(element.contentElement); 27662 } 27663 this.#elements.length = 0; 27664 this.#editableAnnotations.clear(); 27665 this.div.replaceChildren(); 27666 } 27667 #setAnnotationCanvasMap() { 27668 if (!this.#annotationCanvasMap) { 27669 return; 27670 } 27671 const layer = this.div; 27672 for (const [id, canvas] of this.#annotationCanvasMap) { 27673 const element = layer.querySelector(`[data-annotation-id="${id}"]`); 27674 if (!element) { 27675 continue; 27676 } 27677 if (Array.isArray(canvas)) { 27678 for (const cvs of canvas) { 27679 cvs.className = "annotationContent"; 27680 cvs.ariaHidden = true; 27681 } 27682 } else { 27683 canvas.className = "annotationContent"; 27684 canvas.ariaHidden = true; 27685 } 27686 const toRemove = []; 27687 for (const child of element.children) { 27688 if (child.nodeName === "CANVAS") { 27689 toRemove.push(child); 27690 } 27691 } 27692 for (const child of toRemove) { 27693 child.remove(); 27694 } 27695 const firstCanvas = Array.isArray(canvas) ? canvas[0] : canvas; 27696 const { 27697 firstChild 27698 } = element; 27699 if (!firstChild) { 27700 element.append(firstCanvas); 27701 } else if (!firstChild.classList.contains("annotationContent")) { 27702 firstChild.before(firstCanvas); 27703 } else { 27704 firstChild.after(firstCanvas); 27705 } 27706 if (Array.isArray(canvas)) { 27707 let lastCanvas = firstCanvas; 27708 for (let i = 1, ii = canvas.length; i < ii; i++) { 27709 lastCanvas.after(canvas[i]); 27710 lastCanvas = canvas[i]; 27711 } 27712 } 27713 this.#annotationCanvasMap.delete(id); 27714 const editableAnnotation = this.#editableAnnotations.get(id); 27715 if (!editableAnnotation) { 27716 continue; 27717 } 27718 if (editableAnnotation._hasNoCanvas) { 27719 this._annotationEditorUIManager?.setMissingCanvas(id, element.id, canvas); 27720 editableAnnotation._hasNoCanvas = false; 27721 } else { 27722 editableAnnotation.canvas = canvas; 27723 } 27724 } 27725 } 27726 refreshCanvases() { 27727 this.#setAnnotationCanvasMap(); 27728 } 27729 getEditableAnnotations() { 27730 return this.#editableAnnotations.values(); 27731 } 27732 getEditableAnnotation(id) { 27733 return this.#editableAnnotations.get(id); 27734 } 27735 addFakeAnnotation(editor) { 27736 const { 27737 div 27738 } = this; 27739 const { 27740 id, 27741 rotation 27742 } = editor; 27743 const element = new EditorAnnotationElement({ 27744 data: { 27745 id, 27746 rect: editor.getPDFRect(), 27747 rotation 27748 }, 27749 editor, 27750 layer: div, 27751 parent: this, 27752 enableComment: !!this._commentManager, 27753 linkService: this.#linkService, 27754 annotationStorage: this.#annotationStorage 27755 }); 27756 element.render(); 27757 element.contentElement.id = `${AnnotationPrefix}${id}`; 27758 element.createOrUpdatePopup(); 27759 this.#elements.push(element); 27760 return element; 27761 } 27762 removeAnnotation(id) { 27763 const index = this.#elements.findIndex(el => el.data.id === id); 27764 if (index < 0) { 27765 return; 27766 } 27767 const [element] = this.#elements.splice(index, 1); 27768 this.#accessibilityManager?.removePointerInTextLayer(element.contentElement); 27769 } 27770 updateFakeAnnotations(editors) { 27771 if (editors.length === 0) { 27772 return; 27773 } 27774 for (const editor of editors) { 27775 editor.updateFakeAnnotationElement(this); 27776 } 27777 this.#addElementsToDOM(); 27778 } 27779 togglePointerEvents(enabled = false) { 27780 this.div.classList.toggle("disabled", !enabled); 27781 } 27782 static get _defaultBorderStyle() { 27783 return shadow(this, "_defaultBorderStyle", Object.freeze({ 27784 width: 1, 27785 rawWidth: 1, 27786 style: AnnotationBorderStyleType.SOLID, 27787 dashArray: [3], 27788 horizontalCornerRadius: 0, 27789 verticalCornerRadius: 0 27790 })); 27791 } 27792} 27793 27794;// ./src/display/editor/freetext.js 27795 27796 27797 27798 27799 27800 27801 27802 27803 27804 27805const EOL_PATTERN = /\r\n?|\n/g; 27806class FreeTextEditor extends AnnotationEditor { 27807 #content = ""; 27808 #editorDivId = `${this.id}-editor`; 27809 #editModeAC = null; 27810 #fontSize; 27811 _colorPicker = null; 27812 static _freeTextDefaultContent = ""; 27813 static _internalPadding = 0; 27814 static _defaultColor = null; 27815 static _defaultFontSize = 10; 27816 static get _keyboardManager() { 27817 const proto = FreeTextEditor.prototype; 27818 const arrowChecker = self => self.isEmpty(); 27819 const small = AnnotationEditorUIManager.TRANSLATE_SMALL; 27820 const big = AnnotationEditorUIManager.TRANSLATE_BIG; 27821 return shadow(this, "_keyboardManager", new KeyboardManager([[["ctrl+s", "mac+meta+s", "ctrl+p", "mac+meta+p"], proto.commitOrRemove, { 27822 bubbles: true 27823 }], [["ctrl+Enter", "mac+meta+Enter"], proto.commitOrRemove], [["Escape"], proto.commitOrRemove], [["ArrowLeft"], proto._translateEmpty, { 27824 args: [-small, 0], 27825 checker: arrowChecker 27826 }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto._translateEmpty, { 27827 args: [-big, 0], 27828 checker: arrowChecker 27829 }], [["ArrowRight"], proto._translateEmpty, { 27830 args: [small, 0], 27831 checker: arrowChecker 27832 }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto._translateEmpty, { 27833 args: [big, 0], 27834 checker: arrowChecker 27835 }], [["ArrowUp"], proto._translateEmpty, { 27836 args: [0, -small], 27837 checker: arrowChecker 27838 }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto._translateEmpty, { 27839 args: [0, -big], 27840 checker: arrowChecker 27841 }], [["ArrowDown"], proto._translateEmpty, { 27842 args: [0, small], 27843 checker: arrowChecker 27844 }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto._translateEmpty, { 27845 args: [0, big], 27846 checker: arrowChecker 27847 }]])); 27848 } 27849 static _type = "freetext"; 27850 static _editorType = AnnotationEditorType.FREETEXT; 27851 constructor(params) { 27852 super({ 27853 ...params, 27854 name: "freeTextEditor" 27855 }); 27856 this.color = params.color || FreeTextEditor._defaultColor || AnnotationEditor._defaultLineColor; 27857 this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; 27858 if (!this.annotationElementId) { 27859 this._uiManager.a11yAlert(AnnotationEditor._l10nAlert.freetext); 27860 } 27861 this.canAddComment = false; 27862 } 27863 static initialize(l10n, uiManager) { 27864 AnnotationEditor.initialize(l10n, uiManager); 27865 const style = getComputedStyle(document.documentElement); 27866 this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); 27867 } 27868 static updateDefaultParams(type, value) { 27869 switch (type) { 27870 case AnnotationEditorParamsType.FREETEXT_SIZE: 27871 FreeTextEditor._defaultFontSize = value; 27872 break; 27873 case AnnotationEditorParamsType.FREETEXT_COLOR: 27874 FreeTextEditor._defaultColor = value; 27875 break; 27876 } 27877 } 27878 updateParams(type, value) { 27879 switch (type) { 27880 case AnnotationEditorParamsType.FREETEXT_SIZE: 27881 this.#updateFontSize(value); 27882 break; 27883 case AnnotationEditorParamsType.FREETEXT_COLOR: 27884 this.#updateColor(value); 27885 break; 27886 } 27887 } 27888 static get defaultPropertiesToUpdate() { 27889 return [[AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || AnnotationEditor._defaultLineColor]]; 27890 } 27891 get propertiesToUpdate() { 27892 return [[AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [AnnotationEditorParamsType.FREETEXT_COLOR, this.color]]; 27893 } 27894 get toolbarButtons() { 27895 this._colorPicker ||= new BasicColorPicker(this); 27896 return [["colorPicker", this._colorPicker]]; 27897 } 27898 get colorType() { 27899 return AnnotationEditorParamsType.FREETEXT_COLOR; 27900 } 27901 #updateFontSize(fontSize) { 27902 const setFontsize = size => { 27903 this.editorDiv.style.fontSize = `calc(${size}px * var(--total-scale-factor))`; 27904 this.translate(0, -(size - this.#fontSize) * this.parentScale); 27905 this.#fontSize = size; 27906 this.#setEditorDimensions(); 27907 }; 27908 const savedFontsize = this.#fontSize; 27909 this.addCommands({ 27910 cmd: setFontsize.bind(this, fontSize), 27911 undo: setFontsize.bind(this, savedFontsize), 27912 post: this._uiManager.updateUI.bind(this._uiManager, this), 27913 mustExec: true, 27914 type: AnnotationEditorParamsType.FREETEXT_SIZE, 27915 overwriteIfSameType: true, 27916 keepUndo: true 27917 }); 27918 } 27919 onUpdatedColor() { 27920 this.editorDiv.style.color = this.color; 27921 this._colorPicker?.update(this.color); 27922 super.onUpdatedColor(); 27923 } 27924 #updateColor(color) { 27925 const setColor = col => { 27926 this.color = col; 27927 this.onUpdatedColor(); 27928 }; 27929 const savedColor = this.color; 27930 this.addCommands({ 27931 cmd: setColor.bind(this, color), 27932 undo: setColor.bind(this, savedColor), 27933 post: this._uiManager.updateUI.bind(this._uiManager, this), 27934 mustExec: true, 27935 type: AnnotationEditorParamsType.FREETEXT_COLOR, 27936 overwriteIfSameType: true, 27937 keepUndo: true 27938 }); 27939 } 27940 _translateEmpty(x, y) { 27941 this._uiManager.translateSelectedEditors(x, y, true); 27942 } 27943 getInitialTranslation() { 27944 const scale = this.parentScale; 27945 return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale]; 27946 } 27947 rebuild() { 27948 if (!this.parent) { 27949 return; 27950 } 27951 super.rebuild(); 27952 if (this.div === null) { 27953 return; 27954 } 27955 if (!this.isAttachedToDOM) { 27956 this.parent.add(this); 27957 } 27958 } 27959 enableEditMode() { 27960 if (!super.enableEditMode()) { 27961 return false; 27962 } 27963 this.overlayDiv.classList.remove("enabled"); 27964 this.editorDiv.contentEditable = true; 27965 this._isDraggable = false; 27966 this.div.removeAttribute("aria-activedescendant"); 27967 this.#editModeAC = new AbortController(); 27968 const signal = this._uiManager.combinedSignal(this.#editModeAC); 27969 this.editorDiv.addEventListener("keydown", this.editorDivKeydown.bind(this), { 27970 signal 27971 }); 27972 this.editorDiv.addEventListener("focus", this.editorDivFocus.bind(this), { 27973 signal 27974 }); 27975 this.editorDiv.addEventListener("blur", this.editorDivBlur.bind(this), { 27976 signal 27977 }); 27978 this.editorDiv.addEventListener("input", this.editorDivInput.bind(this), { 27979 signal 27980 }); 27981 this.editorDiv.addEventListener("paste", this.editorDivPaste.bind(this), { 27982 signal 27983 }); 27984 return true; 27985 } 27986 disableEditMode() { 27987 if (!super.disableEditMode()) { 27988 return false; 27989 } 27990 this.overlayDiv.classList.add("enabled"); 27991 this.editorDiv.contentEditable = false; 27992 this.div.setAttribute("aria-activedescendant", this.#editorDivId); 27993 this._isDraggable = true; 27994 this.#editModeAC?.abort(); 27995 this.#editModeAC = null; 27996 this.div.focus({ 27997 preventScroll: true 27998 }); 27999 this.isEditing = false; 28000 this.parent.div.classList.add("freetextEditing"); 28001 return true; 28002 } 28003 focusin(event) { 28004 if (!this._focusEventsAllowed) { 28005 return; 28006 } 28007 super.focusin(event); 28008 if (event.target !== this.editorDiv) { 28009 this.editorDiv.focus(); 28010 } 28011 } 28012 onceAdded(focus) { 28013 if (this.width) { 28014 return; 28015 } 28016 this.enableEditMode(); 28017 if (focus) { 28018 this.editorDiv.focus(); 28019 } 28020 if (this._initialOptions?.isCentered) { 28021 this.center(); 28022 } 28023 this._initialOptions = null; 28024 } 28025 isEmpty() { 28026 return !this.editorDiv || this.editorDiv.innerText.trim() === ""; 28027 } 28028 remove() { 28029 this.isEditing = false; 28030 if (this.parent) { 28031 this.parent.setEditingState(true); 28032 this.parent.div.classList.add("freetextEditing"); 28033 } 28034 super.remove(); 28035 } 28036 #extractText() { 28037 const buffer = []; 28038 this.editorDiv.normalize(); 28039 let prevChild = null; 28040 for (const child of this.editorDiv.childNodes) { 28041 if (prevChild?.nodeType === Node.TEXT_NODE && child.nodeName === "BR") { 28042 continue; 28043 } 28044 buffer.push(FreeTextEditor.#getNodeContent(child)); 28045 prevChild = child; 28046 } 28047 return buffer.join("\n"); 28048 } 28049 #setEditorDimensions() { 28050 const [parentWidth, parentHeight] = this.parentDimensions; 28051 let rect; 28052 if (this.isAttachedToDOM) { 28053 rect = this.div.getBoundingClientRect(); 28054 } else { 28055 const { 28056 currentLayer, 28057 div 28058 } = this; 28059 const savedDisplay = div.style.display; 28060 const savedVisibility = div.classList.contains("hidden"); 28061 div.classList.remove("hidden"); 28062 div.style.display = "hidden"; 28063 currentLayer.div.append(this.div); 28064 rect = div.getBoundingClientRect(); 28065 div.remove(); 28066 div.style.display = savedDisplay; 28067 div.classList.toggle("hidden", savedVisibility); 28068 } 28069 if (this.rotation % 180 === this.parentRotation % 180) { 28070 this.width = rect.width / parentWidth; 28071 this.height = rect.height / parentHeight; 28072 } else { 28073 this.width = rect.height / parentWidth; 28074 this.height = rect.width / parentHeight; 28075 } 28076 this.fixAndSetPosition(); 28077 } 28078 commit() { 28079 if (!this.isInEditMode()) { 28080 return; 28081 } 28082 super.commit(); 28083 this.disableEditMode(); 28084 const savedText = this.#content; 28085 const newText = this.#content = this.#extractText().trimEnd(); 28086 if (savedText === newText) { 28087 return; 28088 } 28089 const setText = text => { 28090 this.#content = text; 28091 if (!text) { 28092 this.remove(); 28093 return; 28094 } 28095 this.#setContent(); 28096 this._uiManager.rebuild(this); 28097 this.#setEditorDimensions(); 28098 }; 28099 this.addCommands({ 28100 cmd: () => { 28101 setText(newText); 28102 }, 28103 undo: () => { 28104 setText(savedText); 28105 }, 28106 mustExec: false 28107 }); 28108 this.#setEditorDimensions(); 28109 } 28110 shouldGetKeyboardEvents() { 28111 return this.isInEditMode(); 28112 } 28113 enterInEditMode() { 28114 this.enableEditMode(); 28115 this.editorDiv.focus(); 28116 } 28117 keydown(event) { 28118 if (event.target === this.div && event.key === "Enter") { 28119 this.enterInEditMode(); 28120 event.preventDefault(); 28121 } 28122 } 28123 editorDivKeydown(event) { 28124 FreeTextEditor._keyboardManager.exec(this, event); 28125 } 28126 editorDivFocus(event) { 28127 this.isEditing = true; 28128 } 28129 editorDivBlur(event) { 28130 this.isEditing = false; 28131 } 28132 editorDivInput(event) { 28133 this.parent.div.classList.toggle("freetextEditing", this.isEmpty()); 28134 } 28135 disableEditing() { 28136 this.editorDiv.setAttribute("role", "comment"); 28137 this.editorDiv.removeAttribute("aria-multiline"); 28138 } 28139 enableEditing() { 28140 this.editorDiv.setAttribute("role", "textbox"); 28141 this.editorDiv.setAttribute("aria-multiline", true); 28142 } 28143 get canChangeContent() { 28144 return true; 28145 } 28146 render() { 28147 if (this.div) { 28148 return this.div; 28149 } 28150 let baseX, baseY; 28151 if (this._isCopy || this.annotationElementId) { 28152 baseX = this.x; 28153 baseY = this.y; 28154 } 28155 super.render(); 28156 this.editorDiv = document.createElement("div"); 28157 this.editorDiv.className = "internal"; 28158 this.editorDiv.setAttribute("id", this.#editorDivId); 28159 this.editorDiv.setAttribute("data-l10n-id", "pdfjs-free-text2"); 28160 this.editorDiv.setAttribute("data-l10n-attrs", "default-content"); 28161 this.enableEditing(); 28162 this.editorDiv.contentEditable = true; 28163 const { 28164 style 28165 } = this.editorDiv; 28166 style.fontSize = `calc(${this.#fontSize}px * var(--total-scale-factor))`; 28167 style.color = this.color; 28168 this.div.append(this.editorDiv); 28169 this.overlayDiv = document.createElement("div"); 28170 this.overlayDiv.classList.add("overlay", "enabled"); 28171 this.div.append(this.overlayDiv); 28172 if (this._isCopy || this.annotationElementId) { 28173 const [parentWidth, parentHeight] = this.parentDimensions; 28174 if (this.annotationElementId) { 28175 const { 28176 position 28177 } = this._initialData; 28178 let [tx, ty] = this.getInitialTranslation(); 28179 [tx, ty] = this.pageTranslationToScreen(tx, ty); 28180 const [pageWidth, pageHeight] = this.pageDimensions; 28181 const [pageX, pageY] = this.pageTranslation; 28182 let posX, posY; 28183 switch (this.rotation) { 28184 case 0: 28185 posX = baseX + (position[0] - pageX) / pageWidth; 28186 posY = baseY + this.height - (position[1] - pageY) / pageHeight; 28187 break; 28188 case 90: 28189 posX = baseX + (position[0] - pageX) / pageWidth; 28190 posY = baseY - (position[1] - pageY) / pageHeight; 28191 [tx, ty] = [ty, -tx]; 28192 break; 28193 case 180: 28194 posX = baseX - this.width + (position[0] - pageX) / pageWidth; 28195 posY = baseY - (position[1] - pageY) / pageHeight; 28196 [tx, ty] = [-tx, -ty]; 28197 break; 28198 case 270: 28199 posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth; 28200 posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight; 28201 [tx, ty] = [-ty, tx]; 28202 break; 28203 } 28204 this.setAt(posX * parentWidth, posY * parentHeight, tx, ty); 28205 } else { 28206 this._moveAfterPaste(baseX, baseY); 28207 } 28208 this.#setContent(); 28209 this._isDraggable = true; 28210 this.editorDiv.contentEditable = false; 28211 } else { 28212 this._isDraggable = false; 28213 this.editorDiv.contentEditable = true; 28214 } 28215 return this.div; 28216 } 28217 static #getNodeContent(node) { 28218 return (node.nodeType === Node.TEXT_NODE ? node.nodeValue : node.innerText).replaceAll(EOL_PATTERN, ""); 28219 } 28220 editorDivPaste(event) { 28221 const clipboardData = event.clipboardData || window.clipboardData; 28222 const { 28223 types 28224 } = clipboardData; 28225 if (types.length === 1 && types[0] === "text/plain") { 28226 return; 28227 } 28228 event.preventDefault(); 28229 const paste = FreeTextEditor.#deserializeContent(clipboardData.getData("text") || "").replaceAll(EOL_PATTERN, "\n"); 28230 if (!paste) { 28231 return; 28232 } 28233 const selection = window.getSelection(); 28234 if (!selection.rangeCount) { 28235 return; 28236 } 28237 this.editorDiv.normalize(); 28238 selection.deleteFromDocument(); 28239 const range = selection.getRangeAt(0); 28240 if (!paste.includes("\n")) { 28241 range.insertNode(document.createTextNode(paste)); 28242 this.editorDiv.normalize(); 28243 selection.collapseToStart(); 28244 return; 28245 } 28246 const { 28247 startContainer, 28248 startOffset 28249 } = range; 28250 const bufferBefore = []; 28251 const bufferAfter = []; 28252 if (startContainer.nodeType === Node.TEXT_NODE) { 28253 const parent = startContainer.parentElement; 28254 bufferAfter.push(startContainer.nodeValue.slice(startOffset).replaceAll(EOL_PATTERN, "")); 28255 if (parent !== this.editorDiv) { 28256 let buffer = bufferBefore; 28257 for (const child of this.editorDiv.childNodes) { 28258 if (child === parent) { 28259 buffer = bufferAfter; 28260 continue; 28261 } 28262 buffer.push(FreeTextEditor.#getNodeContent(child)); 28263 } 28264 } 28265 bufferBefore.push(startContainer.nodeValue.slice(0, startOffset).replaceAll(EOL_PATTERN, "")); 28266 } else if (startContainer === this.editorDiv) { 28267 let buffer = bufferBefore; 28268 let i = 0; 28269 for (const child of this.editorDiv.childNodes) { 28270 if (i++ === startOffset) { 28271 buffer = bufferAfter; 28272 } 28273 buffer.push(FreeTextEditor.#getNodeContent(child)); 28274 } 28275 } 28276 this.#content = `${bufferBefore.join("\n")}${paste}${bufferAfter.join("\n")}`; 28277 this.#setContent(); 28278 const newRange = new Range(); 28279 let beforeLength = Math.sumPrecise(bufferBefore.map(line => line.length)); 28280 for (const { 28281 firstChild 28282 } of this.editorDiv.childNodes) { 28283 if (firstChild.nodeType === Node.TEXT_NODE) { 28284 const length = firstChild.nodeValue.length; 28285 if (beforeLength <= length) { 28286 newRange.setStart(firstChild, beforeLength); 28287 newRange.setEnd(firstChild, beforeLength); 28288 break; 28289 } 28290 beforeLength -= length; 28291 } 28292 } 28293 selection.removeAllRanges(); 28294 selection.addRange(newRange); 28295 } 28296 #setContent() { 28297 this.editorDiv.replaceChildren(); 28298 if (!this.#content) { 28299 return; 28300 } 28301 for (const line of this.#content.split("\n")) { 28302 const div = document.createElement("div"); 28303 div.append(line ? document.createTextNode(line) : document.createElement("br")); 28304 this.editorDiv.append(div); 28305 } 28306 } 28307 #serializeContent() { 28308 return this.#content.replaceAll("\xa0", " "); 28309 } 28310 static #deserializeContent(content) { 28311 return content.replaceAll(" ", "\xa0"); 28312 } 28313 get contentDiv() { 28314 return this.editorDiv; 28315 } 28316 getPDFRect() { 28317 const padding = FreeTextEditor._internalPadding * this.parentScale; 28318 return this.getRect(padding, padding); 28319 } 28320 static async deserialize(data, parent, uiManager) { 28321 let initialData = null; 28322 if (data instanceof FreeTextAnnotationElement) { 28323 const { 28324 data: { 28325 defaultAppearanceData: { 28326 fontSize, 28327 fontColor 28328 }, 28329 rect, 28330 rotation, 28331 id, 28332 popupRef, 28333 richText, 28334 contentsObj, 28335 creationDate, 28336 modificationDate 28337 }, 28338 textContent, 28339 textPosition, 28340 parent: { 28341 page: { 28342 pageNumber 28343 } 28344 } 28345 } = data; 28346 if (!textContent?.length) { 28347 return null; 28348 } 28349 initialData = data = { 28350 annotationType: AnnotationEditorType.FREETEXT, 28351 color: Array.from(fontColor), 28352 fontSize, 28353 value: textContent.join("\n"), 28354 position: textPosition, 28355 pageIndex: pageNumber - 1, 28356 rect: rect.slice(0), 28357 rotation, 28358 annotationElementId: id, 28359 id, 28360 deleted: false, 28361 popupRef, 28362 comment: contentsObj?.str || null, 28363 richText, 28364 creationDate, 28365 modificationDate 28366 }; 28367 } 28368 const editor = await super.deserialize(data, parent, uiManager); 28369 editor.#fontSize = data.fontSize; 28370 editor.color = Util.makeHexColor(...data.color); 28371 editor.#content = FreeTextEditor.#deserializeContent(data.value); 28372 editor._initialData = initialData; 28373 if (data.comment) { 28374 editor.setCommentData(data); 28375 } 28376 return editor; 28377 } 28378 serialize(isForCopying = false) { 28379 if (this.isEmpty()) { 28380 return null; 28381 } 28382 if (this.deleted) { 28383 return this.serializeDeleted(); 28384 } 28385 const color = AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.color); 28386 const serialized = Object.assign(super.serialize(isForCopying), { 28387 color, 28388 fontSize: this.#fontSize, 28389 value: this.#serializeContent() 28390 }); 28391 this.addComment(serialized); 28392 if (isForCopying) { 28393 serialized.isCopy = true; 28394 return serialized; 28395 } 28396 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 28397 return null; 28398 } 28399 serialized.id = this.annotationElementId; 28400 return serialized; 28401 } 28402 #hasElementChanged(serialized) { 28403 const { 28404 value, 28405 fontSize, 28406 color, 28407 pageIndex 28408 } = this._initialData; 28409 return this.hasEditedComment || this._hasBeenMoved || serialized.value !== value || serialized.fontSize !== fontSize || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex; 28410 } 28411 renderAnnotationElement(annotation) { 28412 const content = super.renderAnnotationElement(annotation); 28413 if (!content) { 28414 return null; 28415 } 28416 const { 28417 style 28418 } = content; 28419 style.fontSize = `calc(${this.#fontSize}px * var(--total-scale-factor))`; 28420 style.color = this.color; 28421 content.replaceChildren(); 28422 for (const line of this.#content.split("\n")) { 28423 const div = document.createElement("div"); 28424 div.append(line ? document.createTextNode(line) : document.createElement("br")); 28425 content.append(div); 28426 } 28427 annotation.updateEdited({ 28428 rect: this.getPDFRect(), 28429 popup: this._uiManager.hasCommentManager() || this.hasEditedComment ? this.comment : { 28430 text: this.#content 28431 } 28432 }); 28433 return content; 28434 } 28435 resetAnnotationElement(annotation) { 28436 super.resetAnnotationElement(annotation); 28437 annotation.resetEdited(); 28438 } 28439} 28440 28441;// ./src/display/editor/draw.js 28442 28443 28444 28445
28446 28447 28448
vendor: 24,694 bytes, lines 28449-29298
28449 28450 28451 28452 28453 28454class DrawingOptions { 28455 #svgProperties = Object.create(null); 28456 updateProperty(name, value) { 28457 this[name] = value; 28458 this.updateSVGProperty(name, value); 28459 } 28460 updateProperties(properties) { 28461 if (!properties) { 28462 return; 28463 } 28464 for (const [name, value] of Object.entries(properties)) { 28465 if (!name.startsWith("_")) { 28466 this.updateProperty(name, value); 28467 } 28468 } 28469 } 28470 updateSVGProperty(name, value) { 28471 this.#svgProperties[name] = value; 28472 } 28473 toSVGProperties() { 28474 const root = this.#svgProperties; 28475 this.#svgProperties = Object.create(null); 28476 return { 28477 root 28478 }; 28479 } 28480 reset() { 28481 this.#svgProperties = Object.create(null); 28482 } 28483 updateAll(options = this) { 28484 this.updateProperties(options); 28485 } 28486 clone() { 28487 unreachable("Not implemented"); 28488 } 28489} 28490class DrawingEditor extends AnnotationEditor { 28491 #internalDiv = null; 28492 #mustBeCommitted; 28493 _clipPathId = null; 28494 _colorPicker = null; 28495 _drawId = null; 28496 _drawOutlines = null; 28497 _focusDrawId = null; 28498 static _currentDrawId = -1; 28499 static _currentParent = null; 28500 static #currentDraw = null; 28501 static #currentDrawingAC = null; 28502 static #currentDrawingOptions = null; 28503 static #currentClipPathId = null; 28504 static _INNER_MARGIN = 3; 28505 constructor(params) { 28506 super(params); 28507 this.#mustBeCommitted = params.mustBeCommitted || false; 28508 this._addOutlines(params); 28509 } 28510 onUpdatedColor() { 28511 this._colorPicker?.update(this.color); 28512 super.onUpdatedColor(); 28513 } 28514 onUpdatedOpacity() { 28515 this._colorPicker?.updateOpacity?.(this.opacity); 28516 } 28517 _addOutlines(params) { 28518 if (params.drawOutlines) { 28519 this.#createDrawOutlines(params); 28520 this.#addToDrawLayer(); 28521 } 28522 } 28523 #createDrawOutlines({ 28524 drawOutlines, 28525 drawId, 28526 drawingOptions, 28527 clipPathId 28528 }) { 28529 this._drawOutlines = drawOutlines; 28530 this._drawingOptions ||= drawingOptions; 28531 if (!this.annotationElementId) { 28532 this._uiManager.a11yAlert(AnnotationEditor._l10nAlert[this.editorType]); 28533 } 28534 if (drawId >= 0) { 28535 this._drawId = drawId; 28536 this._clipPathId = clipPathId ?? null; 28537 this.parent.drawLayer.finalizeDraw(drawId, drawOutlines.defaultProperties); 28538 this.#createFocusOutline(this.parent); 28539 } else { 28540 this._drawId = this.#createDrawing(drawOutlines, this.parent); 28541 } 28542 this.#updateBbox(drawOutlines.box); 28543 } 28544 #createDrawing(drawOutlines, parent) { 28545 const { 28546 id, 28547 clipPathId 28548 } = parent.drawLayer.draw(DrawingEditor._mergeSVGProperties(this._drawingOptions.toSVGProperties(), drawOutlines.defaultSVGProperties), false, this.constructor._hasClipPath); 28549 if (this.constructor._hasClipPath) { 28550 this._clipPathId = clipPathId; 28551 } 28552 this.#createFocusOutline(parent); 28553 return id; 28554 } 28555 #createFocusOutline(parent) { 28556 const properties = this._drawOutlines.getFocusSVGProperties(this.#rotationAngle); 28557 if (properties) { 28558 this._focusDrawId = parent.drawLayer.drawOutline(properties, this._drawOutlines.focusMustRemoveSelfIntersections); 28559 } 28560 } 28561 #updateFocusOutline(angle = this.#rotationAngle) { 28562 if (this._focusDrawId === null) { 28563 return; 28564 } 28565 this.parent?.drawLayer.updateProperties(this._focusDrawId, this._drawOutlines.getFocusSVGProperties(angle)); 28566 } 28567 #toggleFocusOutlineClass(rootClass) { 28568 if (this._focusDrawId !== null) { 28569 this.parent?.drawLayer.updateProperties(this._focusDrawId, { 28570 rootClass 28571 }); 28572 } 28573 } 28574 #updateVisibility() { 28575 const { 28576 parent, 28577 _drawId, 28578 _focusDrawId, 28579 _isVisible 28580 } = this; 28581 if (!parent || _drawId === null) { 28582 return; 28583 } 28584 const rootClass = { 28585 hidden: !_isVisible 28586 }; 28587 parent.drawLayer.updateProperties(_drawId, { 28588 rootClass 28589 }); 28590 if (_focusDrawId !== null) { 28591 parent.drawLayer.updateProperties(_focusDrawId, { 28592 rootClass 28593 }); 28594 } 28595 } 28596 static _mergeSVGProperties(p1, p2) { 28597 const p1Keys = new Set(Object.keys(p1)); 28598 for (const [key, value] of Object.entries(p2)) { 28599 if (p1Keys.has(key)) { 28600 Object.assign(p1[key], value); 28601 } else { 28602 p1[key] = value; 28603 } 28604 } 28605 return p1; 28606 } 28607 static getDefaultDrawingOptions(_options) { 28608 unreachable("Not implemented"); 28609 } 28610 static get typesMap() { 28611 unreachable("Not implemented"); 28612 } 28613 static get isDrawer() { 28614 return true; 28615 } 28616 static get _hasClipPath() { 28617 return false; 28618 } 28619 static get _hasDrawClass() { 28620 return true; 28621 } 28622 static get supportMultipleDrawings() { 28623 return false; 28624 } 28625 get _drawRotation() { 28626 return this.rotation; 28627 } 28628 get _opacityName() { 28629 return this.constructor.typesMap.get(this.opacityType); 28630 } 28631 get #rotationAngle() { 28632 return (this.parentRotation - this._drawRotation + 360) % 360; 28633 } 28634 static updateDefaultParams(type, value) { 28635 const propertyName = this.typesMap.get(type); 28636 if (propertyName) { 28637 this._defaultDrawingOptions.updateProperty(propertyName, value); 28638 } 28639 if (this._currentParent) { 28640 DrawingEditor.#currentDraw.updateProperty(propertyName, value); 28641 this._currentParent.drawLayer.updateProperties(this._currentDrawId, this._defaultDrawingOptions.toSVGProperties()); 28642 } 28643 } 28644 updateParams(type, value) { 28645 const propertyName = this.constructor.typesMap.get(type); 28646 if (propertyName) { 28647 this._updateProperty(type, propertyName, value); 28648 } 28649 } 28650 static get defaultPropertiesToUpdate() { 28651 const properties = []; 28652 const options = this._defaultDrawingOptions; 28653 for (const [type, name] of this.typesMap) { 28654 properties.push([type, options[name]]); 28655 } 28656 return properties; 28657 } 28658 get propertiesToUpdate() { 28659 const properties = []; 28660 const { 28661 _drawingOptions 28662 } = this; 28663 for (const [type, name] of this.constructor.typesMap) { 28664 properties.push([type, _drawingOptions[name]]); 28665 } 28666 return properties; 28667 } 28668 _updateProperty(type, name, value) { 28669 const options = this._drawingOptions; 28670 const savedValue = options[name]; 28671 const setter = val => { 28672 options.updateProperty(name, val); 28673 const bbox = this._drawOutlines.updateProperty(name, val); 28674 if (bbox) { 28675 this.#updateBbox(bbox); 28676 } 28677 this.parent?.drawLayer.updateProperties(this._drawId, options.toSVGProperties()); 28678 if (type === this.colorType) { 28679 this.onUpdatedColor(); 28680 } else if (type === this.opacityType) { 28681 this.onUpdatedOpacity(); 28682 } 28683 }; 28684 this.addCommands({ 28685 cmd: setter.bind(this, value), 28686 undo: setter.bind(this, savedValue), 28687 post: this._uiManager.updateUI.bind(this._uiManager, this), 28688 mustExec: true, 28689 type, 28690 overwriteIfSameType: true, 28691 keepUndo: true 28692 }); 28693 } 28694 _updateColorAndOpacity(color, opacity, type = this.colorAndOpacityType) { 28695 const colorName = this.constructor.typesMap.get(this.colorType); 28696 const opacityName = this._opacityName; 28697 const options = this._drawingOptions; 28698 const savedColor = options[colorName]; 28699 const savedOpacity = options[opacityName]; 28700 const setter = (c, op) => { 28701 options.updateProperty(colorName, c); 28702 options.updateProperty(opacityName, op); 28703 this._drawOutlines.updateProperty(colorName, c); 28704 this._drawOutlines.updateProperty(opacityName, op); 28705 this.parent?.drawLayer.updateProperties(this._drawId, options.toSVGProperties()); 28706 this.onUpdatedColor(); 28707 this.onUpdatedOpacity(); 28708 }; 28709 this.addCommands({ 28710 cmd: setter.bind(this, color, opacity), 28711 undo: setter.bind(this, savedColor, savedOpacity), 28712 post: this._uiManager.updateUI.bind(this._uiManager, this), 28713 mustExec: true, 28714 type, 28715 overwriteIfSameType: true, 28716 keepUndo: true 28717 }); 28718 } 28719 _onResizing() { 28720 this.parent?.drawLayer.updateProperties(this._drawId, DrawingEditor._mergeSVGProperties(this._drawOutlines.getPathResizingSVGProperties(this.#convertToDrawSpace()), { 28721 bbox: this.#rotateBox() 28722 })); 28723 } 28724 _onResized() { 28725 this.parent?.drawLayer.updateProperties(this._drawId, DrawingEditor._mergeSVGProperties(this._drawOutlines.getPathResizedSVGProperties(this.#convertToDrawSpace()), { 28726 bbox: this.#rotateBox() 28727 })); 28728 this.#updateFocusOutline(); 28729 } 28730 _onTranslating(_x, _y) { 28731 this.parent?.drawLayer.updateProperties(this._drawId, { 28732 bbox: this.#rotateBox() 28733 }); 28734 } 28735 _onTranslated() { 28736 this.parent?.drawLayer.updateProperties(this._drawId, DrawingEditor._mergeSVGProperties(this._drawOutlines.getPathTranslatedSVGProperties(this.#convertToDrawSpace(), this.parentDimensions), { 28737 bbox: this.#rotateBox() 28738 })); 28739 } 28740 _onStartDragging() { 28741 this.parent?.drawLayer.updateProperties(this._drawId, { 28742 rootClass: { 28743 moving: true 28744 } 28745 }); 28746 } 28747 _onStopDragging() { 28748 this.parent?.drawLayer.updateProperties(this._drawId, { 28749 rootClass: { 28750 moving: false 28751 } 28752 }); 28753 } 28754 get _mustBeDisabledOnCommit() { 28755 return true; 28756 } 28757 commit() { 28758 super.commit(); 28759 if (this._mustBeDisabledOnCommit) { 28760 this.disableEditMode(); 28761 this.disableEditing(); 28762 } 28763 } 28764 disableEditing() { 28765 super.disableEditing(); 28766 this.div.classList.toggle("disabled", true); 28767 } 28768 enableEditing() { 28769 super.enableEditing(); 28770 this.div.classList.toggle("disabled", false); 28771 } 28772 getBaseTranslation() { 28773 return [0, 0]; 28774 } 28775 get isResizable() { 28776 return true; 28777 } 28778 onceAdded(focus) { 28779 if (!this.annotationElementId) { 28780 this.parent.addUndoableEditor(this); 28781 } 28782 this._isDraggable = true; 28783 if (this.#mustBeCommitted) { 28784 this.#mustBeCommitted = false; 28785 this.commit(); 28786 this.parent.setSelected(this); 28787 if (focus && this.isOnScreen) { 28788 this.div.focus(); 28789 } 28790 } 28791 } 28792 remove() { 28793 this._uiManager.removeShouldRescale(this); 28794 this.#cleanDrawLayer(); 28795 super.remove(); 28796 } 28797 rebuild() { 28798 if (!this.parent) { 28799 return; 28800 } 28801 super.rebuild(); 28802 if (this.div === null) { 28803 return; 28804 } 28805 this.#addToDrawLayer(); 28806 this.#updateBbox(this._drawOutlines.box); 28807 if (!this.isAttachedToDOM) { 28808 this.parent.add(this); 28809 } 28810 } 28811 setParent(parent) { 28812 let mustBeSelected = false; 28813 if (this.parent && !parent) { 28814 this._uiManager.removeShouldRescale(this); 28815 this.#cleanDrawLayer(); 28816 } else if (parent) { 28817 this._uiManager.addShouldRescale(this); 28818 this.#addToDrawLayer(parent); 28819 mustBeSelected = !this.parent && this.div?.classList.contains("selectedEditor"); 28820 } 28821 super.setParent(parent); 28822 this.#updateVisibility(); 28823 if (mustBeSelected) { 28824 this.select(); 28825 } 28826 } 28827 #cleanDrawLayer() { 28828 if (this._drawId === null || !this.parent) { 28829 return; 28830 } 28831 const { 28832 drawLayer 28833 } = this.parent; 28834 drawLayer.remove(this._drawId); 28835 this._drawId = null; 28836 if (this._focusDrawId !== null) { 28837 drawLayer.remove(this._focusDrawId); 28838 this._focusDrawId = null; 28839 } 28840 this._drawingOptions.reset(); 28841 } 28842 #addToDrawLayer(parent = this.parent) { 28843 if (this._drawId !== null && this.parent === parent) { 28844 return; 28845 } 28846 if (this._drawId !== null) { 28847 const { 28848 drawLayer 28849 } = this.parent; 28850 drawLayer.updateParent(this._drawId, parent.drawLayer); 28851 if (this._focusDrawId !== null) { 28852 drawLayer.updateParent(this._focusDrawId, parent.drawLayer); 28853 } 28854 return; 28855 } 28856 this._drawingOptions.updateAll(); 28857 this._drawId = this.#createDrawing(this._drawOutlines, parent); 28858 if (this._clipPathId && this.#internalDiv) { 28859 this.#internalDiv.style.clipPath = this._clipPathId; 28860 } 28861 } 28862 #convertToParentSpace([x, y, width, height]) { 28863 const { 28864 parentDimensions: [pW, pH], 28865 _drawRotation: rotation 28866 } = this; 28867 switch (rotation) { 28868 case 90: 28869 return [y, 1 - x, width * (pH / pW), height * (pW / pH)]; 28870 case 180: 28871 return [1 - x, 1 - y, width, height]; 28872 case 270: 28873 return [1 - y, x, width * (pH / pW), height * (pW / pH)]; 28874 default: 28875 return [x, y, width, height]; 28876 } 28877 } 28878 #convertToDrawSpace() { 28879 const { 28880 x, 28881 y, 28882 width, 28883 height, 28884 parentDimensions: [pW, pH], 28885 _drawRotation: rotation 28886 } = this; 28887 switch (rotation) { 28888 case 90: 28889 return [1 - y, x, width * (pW / pH), height * (pH / pW)]; 28890 case 180: 28891 return [1 - x, 1 - y, width, height]; 28892 case 270: 28893 return [y, 1 - x, width * (pW / pH), height * (pH / pW)]; 28894 default: 28895 return [x, y, width, height]; 28896 } 28897 } 28898 #updateBbox(bbox) { 28899 [this.x, this.y, this.width, this.height] = this.#convertToParentSpace(bbox); 28900 if (this.div) { 28901 this.fixAndSetPosition(); 28902 this.setDims(); 28903 } 28904 this._onResized(); 28905 } 28906 #rotateBox(parentRotation = this.parentRotation) { 28907 const { 28908 x, 28909 y, 28910 width, 28911 height, 28912 _drawRotation: rotation, 28913 parentDimensions: [pW, pH] 28914 } = this; 28915 switch ((rotation * 4 + parentRotation) / 90) { 28916 case 1: 28917 return [1 - y - height, x, height, width]; 28918 case 2: 28919 return [1 - x - width, 1 - y - height, width, height]; 28920 case 3: 28921 return [y, 1 - x - width, height, width]; 28922 case 4: 28923 return [x, y - width * (pW / pH), height * (pH / pW), width * (pW / pH)]; 28924 case 5: 28925 return [1 - y, x, width * (pW / pH), height * (pH / pW)]; 28926 case 6: 28927 return [1 - x - height * (pH / pW), 1 - y, height * (pH / pW), width * (pW / pH)]; 28928 case 7: 28929 return [y - width * (pW / pH), 1 - x - height * (pH / pW), width * (pW / pH), height * (pH / pW)]; 28930 case 8: 28931 return [x - width, y - height, width, height]; 28932 case 9: 28933 return [1 - y, x - width, height, width]; 28934 case 10: 28935 return [1 - x, 1 - y, width, height]; 28936 case 11: 28937 return [y - height, 1 - x, height, width]; 28938 case 12: 28939 return [x - height * (pH / pW), y, height * (pH / pW), width * (pW / pH)]; 28940 case 13: 28941 return [1 - y - width * (pW / pH), x - height * (pH / pW), width * (pW / pH), height * (pH / pW)]; 28942 case 14: 28943 return [1 - x, 1 - y - width * (pW / pH), height * (pH / pW), width * (pW / pH)]; 28944 case 15: 28945 return [y, 1 - x, width * (pW / pH), height * (pH / pW)]; 28946 default: 28947 return [x, y, width, height]; 28948 } 28949 } 28950 rotate(parentRotation = this.parentRotation) { 28951 if (!this.parent || this._drawId === null) { 28952 return; 28953 } 28954 const angle = (parentRotation - this._drawRotation + 360) % 360; 28955 this.parent.drawLayer.updateProperties(this._drawId, DrawingEditor._mergeSVGProperties({ 28956 bbox: this.#rotateBox(parentRotation) 28957 }, this._drawOutlines.updateRotation(angle))); 28958 this.#updateFocusOutline(angle); 28959 } 28960 show(visible = this._isVisible) { 28961 super.show(visible); 28962 this.#updateVisibility(); 28963 } 28964 select() { 28965 super.select(); 28966 this.#toggleFocusOutlineClass({ 28967 hovered: false, 28968 selected: true 28969 }); 28970 } 28971 unselect() { 28972 super.unselect(); 28973 this.#toggleFocusOutlineClass({ 28974 selected: false 28975 }); 28976 } 28977 pointerover() { 28978 if (!this.isSelected) { 28979 this.#toggleFocusOutlineClass({ 28980 hovered: true 28981 }); 28982 } 28983 } 28984 pointerleave() { 28985 if (!this.isSelected) { 28986 this.#toggleFocusOutlineClass({ 28987 hovered: false 28988 }); 28989 } 28990 } 28991 onScaleChanging() { 28992 if (!this.parent) { 28993 return; 28994 } 28995 const bbox = this._drawOutlines.updateParentDimensions(this.parentDimensions, this.parent.scale); 28996 if (bbox) { 28997 this.#updateBbox(bbox); 28998 } 28999 } 29000 static onScaleChangingWhenDrawing() {} 29001 render() { 29002 if (this.div) { 29003 return this.div; 29004 } 29005 let baseX, baseY; 29006 if (this._isCopy) { 29007 baseX = this.x; 29008 baseY = this.y; 29009 } 29010 const div = super.render(); 29011 if (this.constructor._hasDrawClass) { 29012 div.classList.add("draw"); 29013 } 29014 const drawDiv = this.#internalDiv = document.createElement("div"); 29015 div.append(drawDiv); 29016 drawDiv.setAttribute("aria-hidden", "true"); 29017 drawDiv.className = "internal"; 29018 if (this._clipPathId) { 29019 drawDiv.style.clipPath = this._clipPathId; 29020 } 29021 bindEvents(this, drawDiv, ["pointerover", "pointerleave"]); 29022 this.setDims(); 29023 this._uiManager.addShouldRescale(this); 29024 this.disableEditing(); 29025 if (this._isCopy) { 29026 this._moveAfterPaste(baseX, baseY); 29027 } 29028 return div; 29029 } 29030 static createDrawerInstance(_params) { 29031 unreachable("Not implemented"); 29032 } 29033 static _getDrawingTarget(_parent, { 29034 target 29035 }) { 29036 return target; 29037 } 29038 static _getPointerCoords({ 29039 offsetX, 29040 offsetY, 29041 clientX, 29042 clientY 29043 }, referenceEvent = null) { 29044 if (!referenceEvent) { 29045 return [offsetX, offsetY]; 29046 } 29047 let deltaX = clientX - referenceEvent.clientX; 29048 let deltaY = clientY - referenceEvent.clientY; 29049 switch (this._currentParent.viewport.rotation) { 29050 case 90: 29051 [deltaX, deltaY] = [deltaY, -deltaX]; 29052 break; 29053 case 180: 29054 [deltaX, deltaY] = [-deltaX, -deltaY]; 29055 break; 29056 case 270: 29057 [deltaX, deltaY] = [-deltaY, deltaX]; 29058 break; 29059 } 29060 return [referenceEvent.offsetX + deltaX, referenceEvent.offsetY + deltaY]; 29061 } 29062 static _addDrawingListeners(_target, _signal) {} 29063 static _endDrawingSession(isAborted = false) { 29064 return this._currentParent.endDrawingSession(isAborted); 29065 } 29066 static startDrawing(parent, uiManager, isLTR, event) { 29067 const { 29068 pointerId, 29069 pointerType 29070 } = event; 29071 if (CurrentPointers.isInitializedAndDifferentPointerType(pointerType)) { 29072 return; 29073 } 29074 const target = this._getDrawingTarget(parent, event); 29075 const [x, y] = this._getPointerCoords(event); 29076 const { 29077 viewport: { 29078 rotation 29079 } 29080 } = parent; 29081 const { 29082 x: boxX, 29083 y: boxY, 29084 width: parentWidth, 29085 height: parentHeight 29086 } = target.getBoundingClientRect(); 29087 const ac = DrawingEditor.#currentDrawingAC = new AbortController(); 29088 const signal = parent.combinedSignal(ac); 29089 CurrentPointers.setPointer(pointerType, pointerId); 29090 window.addEventListener("pointerup", e => { 29091 if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) { 29092 this._endDraw(e); 29093 } 29094 }, { 29095 signal 29096 }); 29097 window.addEventListener("pointercancel", e => { 29098 if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) { 29099 this._endDrawingSession(); 29100 } 29101 }, { 29102 signal 29103 }); 29104 window.addEventListener("pointerdown", e => { 29105 if (!CurrentPointers.isSamePointerType(e.pointerType)) { 29106 return; 29107 } 29108 CurrentPointers.initializeAndAddPointerId(e.pointerId); 29109 if (DrawingEditor.#currentDraw.isCancellable()) { 29110 DrawingEditor.#currentDraw.removeLastElement(); 29111 if (DrawingEditor.#currentDraw.isEmpty()) { 29112 this._endDrawingSession(true); 29113 } else { 29114 this._endDraw(null); 29115 } 29116 } 29117 }, { 29118 capture: true, 29119 passive: false, 29120 signal 29121 }); 29122 window.addEventListener("contextmenu", noContextMenu, { 29123 signal 29124 }); 29125 target.addEventListener("pointermove", this._drawMove.bind(this), { 29126 signal 29127 }); 29128 target.addEventListener("touchmove", e => { 29129 if (CurrentPointers.isSameTimeStamp(e.timeStamp)) { 29130 stopEvent(e); 29131 } 29132 }, { 29133 signal 29134 }); 29135 this._addDrawingListeners(target, signal); 29136 parent.toggleDrawing(); 29137 uiManager._editorUndoBar?.hide(); 29138 if (DrawingEditor.#currentDraw) { 29139 parent.drawLayer.updateProperties(this._currentDrawId, DrawingEditor.#currentDraw.startNew(x, y, parentWidth, parentHeight, rotation)); 29140 return; 29141 } 29142 uiManager.updateUIForDefaultProperties(this); 29143 DrawingEditor.#currentDraw = this.createDrawerInstance({ 29144 x, 29145 y, 29146 box: [boxX, boxY, parentWidth, parentHeight], 29147 rotation, 29148 parent, 29149 isLTR 29150 }); 29151 DrawingEditor.#currentDrawingOptions = this.getDefaultDrawingOptions(); 29152 this._currentParent = parent; 29153 const { 29154 id, 29155 clipPathId 29156 } = parent.drawLayer.draw(this._mergeSVGProperties(DrawingEditor.#currentDrawingOptions.toSVGProperties(), DrawingEditor.#currentDraw.defaultSVGProperties), true, this._hasClipPath); 29157 this._currentDrawId = id; 29158 DrawingEditor.#currentClipPathId = this._hasClipPath ? clipPathId : null; 29159 } 29160 static _drawMove(event) { 29161 CurrentPointers.isSameTimeStamp(event.timeStamp); 29162 if (!DrawingEditor.#currentDraw) { 29163 return; 29164 } 29165 if (!CurrentPointers.isSamePointerId(event.pointerId)) { 29166 return; 29167 } 29168 if (CurrentPointers.isUsingMultiplePointers()) { 29169 this._endDraw(event); 29170 return; 29171 } 29172 let properties; 29173 const coalesced = event.getCoalescedEvents?.(); 29174 if (coalesced?.length) { 29175 const points = []; 29176 for (const sample of coalesced) { 29177 points.push(...this._getPointerCoords(sample, event)); 29178 } 29179 properties = DrawingEditor.#currentDraw.addPoints(points); 29180 } else { 29181 properties = DrawingEditor.#currentDraw.add(...this._getPointerCoords(event)); 29182 } 29183 this._currentParent.drawLayer.updateProperties(this._currentDrawId, properties); 29184 CurrentPointers.setTimeStamp(event.timeStamp); 29185 stopEvent(event); 29186 } 29187 static _cleanup(all) { 29188 if (all) { 29189 this._currentDrawId = -1; 29190 this._currentParent = null; 29191 DrawingEditor.#currentDraw = null; 29192 DrawingEditor.#currentDrawingOptions = null; 29193 DrawingEditor.#currentClipPathId = null; 29194 CurrentPointers.clearTimeStamp(); 29195 } 29196 if (DrawingEditor.#currentDrawingAC) { 29197 DrawingEditor.#currentDrawingAC.abort(); 29198 DrawingEditor.#currentDrawingAC = null; 29199 CurrentPointers.clearPointerIds(); 29200 } 29201 } 29202 static _endDraw(event) { 29203 const parent = this._currentParent; 29204 if (!parent) { 29205 return; 29206 } 29207 parent.toggleDrawing(true); 29208 this._cleanup(false); 29209 parent.drawLayer.updateProperties(this._currentDrawId, event?.target === parent.div ? DrawingEditor.#currentDraw.end(...this._getPointerCoords(event)) : DrawingEditor.#currentDraw.end()); 29210 if (this.supportMultipleDrawings) { 29211 const draw = DrawingEditor.#currentDraw; 29212 const drawId = this._currentDrawId; 29213 const lastElement = draw.getLastElement(); 29214 parent.addCommands({ 29215 cmd: () => { 29216 parent.drawLayer.updateProperties(drawId, draw.setLastElement(lastElement)); 29217 }, 29218 undo: () => { 29219 parent.drawLayer.updateProperties(drawId, draw.removeLastElement()); 29220 }, 29221 mustExec: false, 29222 type: AnnotationEditorParamsType.DRAW_STEP 29223 }); 29224 return; 29225 } 29226 this.endDrawing(false); 29227 } 29228 static endDrawing(isAborted) { 29229 const parent = this._currentParent; 29230 if (!parent) { 29231 return null; 29232 } 29233 parent.toggleDrawing(true); 29234 parent.cleanUndoStack(AnnotationEditorParamsType.DRAW_STEP); 29235 if (!DrawingEditor.#currentDraw.isEmpty()) { 29236 const { 29237 pageDimensions: [pageWidth, pageHeight], 29238 scale 29239 } = parent; 29240 const editor = parent.createAndAddNewEditor({ 29241 offsetX: 0, 29242 offsetY: 0 29243 }, false, { 29244 drawId: this._currentDrawId, 29245 clipPathId: DrawingEditor.#currentClipPathId, 29246 drawOutlines: DrawingEditor.#currentDraw.getOutlines(pageWidth * scale, pageHeight * scale, scale, this._INNER_MARGIN), 29247 drawingOptions: DrawingEditor.#currentDrawingOptions, 29248 mustBeCommitted: !isAborted 29249 }); 29250 this._cleanup(true); 29251 return editor; 29252 } 29253 parent.drawLayer.remove(this._currentDrawId); 29254 this._cleanup(true); 29255 return null; 29256 } 29257 createDrawingOptions(_data) {} 29258 static deserializeDraw(_pageX, _pageY, _pageWidth, _pageHeight, _innerMargin, _data, _uiManager) { 29259 unreachable("Not implemented"); 29260 } 29261 static async deserialize(data, parent, uiManager) { 29262 const { 29263 rawDims: { 29264 pageWidth, 29265 pageHeight, 29266 pageX, 29267 pageY 29268 } 29269 } = parent.viewport; 29270 const drawOutlines = this.deserializeDraw(pageX, pageY, pageWidth, pageHeight, this._INNER_MARGIN, data, uiManager); 29271 const editor = await super.deserialize(data, parent, uiManager); 29272 editor.createDrawingOptions(data); 29273 editor.#createDrawOutlines({ 29274 drawOutlines 29275 }); 29276 editor.#addToDrawLayer(); 29277 editor.onScaleChanging(); 29278 editor.rotate(); 29279 return editor; 29280 } 29281 serializeDraw(isForCopying) { 29282 const [pageX, pageY] = this.pageTranslation; 29283 const [pageWidth, pageHeight] = this.pageDimensions; 29284 return this._drawOutlines.serialize([pageX, pageY, pageWidth, pageHeight], isForCopying); 29285 } 29286 renderAnnotationElement(annotation) { 29287 annotation.updateEdited({ 29288 rect: this.getPDFRect() 29289 }); 29290 return null; 29291 } 29292 static canCreateNewEmptyEditor() { 29293 return false; 29294 } 29295} 29296 29297;// ./src/display/editor/drawers/outline.js 29298
vendor: 2,840 bytes, lines 29299-29401
29299 29300class Outline { 29301 static PRECISION = 1e-4; 29302 focusOutline = null; 29303 toSVGPath() { 29304 unreachable("Abstract method `toSVGPath` must be implemented."); 29305 } 29306 get box() { 29307 unreachable("Abstract getter `box` must be implemented."); 29308 } 29309 serialize(_bbox, _rotation) { 29310 unreachable("Abstract method `serialize` must be implemented."); 29311 } 29312 get defaultSVGProperties() { 29313 unreachable("Abstract getter `defaultSVGProperties` must be implemented."); 29314 } 29315 get defaultProperties() { 29316 return this.defaultSVGProperties; 29317 } 29318 getFocusSVGProperties(_rotation) { 29319 return null; 29320 } 29321 get focusMustRemoveSelfIntersections() { 29322 return false; 29323 } 29324 updateProperty(_name, _value) { 29325 return null; 29326 } 29327 updateParentDimensions(_dimensions, _scale) { 29328 return null; 29329 } 29330 serializeQuadPoints(_pageTranslation, _pageDimensions) { 29331 return null; 29332 } 29333 updateRotation(_rotation) { 29334 return {}; 29335 } 29336 getPathResizingSVGProperties(_bbox) { 29337 return {}; 29338 } 29339 getPathResizedSVGProperties(_bbox) { 29340 return {}; 29341 } 29342 getPathTranslatedSVGProperties(_bbox, _parentDimensions) { 29343 return {}; 29344 } 29345 static _rotateBox([x, y, width, height], angle) { 29346 switch (angle) { 29347 case 90: 29348 return [1 - y - height, x, height, width]; 29349 case 180: 29350 return [1 - x - width, 1 - y - height, width, height]; 29351 case 270: 29352 return [y, 1 - x - width, height, width]; 29353 } 29354 return [x, y, width, height]; 29355 } 29356 static _rescale(src, tx, ty, sx, sy, dest) { 29357 dest ||= new Float32Array(src.length); 29358 for (let i = 0, ii = src.length; i < ii; i += 2) { 29359 dest[i] = tx + src[i] * sx; 29360 dest[i + 1] = ty + src[i + 1] * sy; 29361 } 29362 return dest; 29363 } 29364 static _rescaleAndSwap(src, tx, ty, sx, sy, dest) { 29365 dest ||= new Float32Array(src.length); 29366 for (let i = 0, ii = src.length; i < ii; i += 2) { 29367 dest[i] = tx + src[i + 1] * sx; 29368 dest[i + 1] = ty + src[i] * sy; 29369 } 29370 return dest; 29371 } 29372 static _translate(src, tx, ty, dest) { 29373 dest ||= new Float32Array(src.length); 29374 for (let i = 0, ii = src.length; i < ii; i += 2) { 29375 dest[i] = tx + src[i]; 29376 dest[i + 1] = ty + src[i + 1]; 29377 } 29378 return dest; 29379 } 29380 static svgRound(x) { 29381 return Math.round(x * 10000); 29382 } 29383 static _normalizePoint(x, y, parentWidth, parentHeight, rotation) { 29384 switch (rotation) { 29385 case 90: 29386 return [1 - y / parentWidth, x / parentHeight]; 29387 case 180: 29388 return [1 - x / parentWidth, 1 - y / parentHeight]; 29389 case 270: 29390 return [y / parentWidth, 1 - x / parentHeight]; 29391 default: 29392 return [x / parentWidth, y / parentHeight]; 29393 } 29394 } 29395 static createBezierPoints(x1, y1, x2, y2, x3, y3) { 29396 return [(x1 + 5 * x2) / 6, (y1 + 5 * y2) / 6, (5 * x2 + x3) / 6, (5 * y2 + y3) / 6, (x2 + x3) / 2, (y2 + y3) / 2]; 29397 } 29398} 29399 29400;// ./src/display/editor/drawers/freedraw.js 29401
vendor: 15,053 bytes, lines 29402-29779
29402 29403 29404 29405class FreeDrawOutliner { 29406 #box; 29407 #bottom = []; 29408 #innerMargin; 29409 #isLTR; 29410 #top = []; 29411 #last = new Float32Array(18); 29412 #lastX; 29413 #lastY; 29414 #min; 29415 #min_dist; 29416 #scaleFactor; 29417 #thickness; 29418 #points = []; 29419 static #MIN_DIST = 8; 29420 static #MIN_DIFF = 2; 29421 static #MIN = FreeDrawOutliner.#MIN_DIST + FreeDrawOutliner.#MIN_DIFF; 29422 constructor(x, y, box, scaleFactor, thickness, isLTR, innerMargin = 0) { 29423 this.#box = box; 29424 this.#thickness = thickness * scaleFactor; 29425 this.#isLTR = isLTR; 29426 this.#last.set([NaN, NaN, NaN, NaN, x, y], 6); 29427 this.#innerMargin = innerMargin; 29428 this.#min_dist = FreeDrawOutliner.#MIN_DIST * scaleFactor; 29429 this.#min = FreeDrawOutliner.#MIN * scaleFactor; 29430 this.#scaleFactor = scaleFactor; 29431 this.#points.push(x, y); 29432 } 29433 isEmpty() { 29434 return isNaN(this.#last[8]); 29435 } 29436 isCancellable() { 29437 return this.#points.length <= 10; 29438 } 29439 removeLastElement() { 29440 this.#last.fill(NaN); 29441 this.#top.length = this.#bottom.length = this.#points.length = 0; 29442 return { 29443 path: { 29444 d: "" 29445 } 29446 }; 29447 } 29448 #getLastCoords() { 29449 const lastTop = this.#last.subarray(4, 6); 29450 const lastBottom = this.#last.subarray(16, 18); 29451 const [x, y, width, height] = this.#box; 29452 return [(this.#lastX + (lastTop[0] - lastBottom[0]) / 2 - x) / width, (this.#lastY + (lastTop[1] - lastBottom[1]) / 2 - y) / height, (this.#lastX + (lastBottom[0] - lastTop[0]) / 2 - x) / width, (this.#lastY + (lastBottom[1] - lastTop[1]) / 2 - y) / height]; 29453 } 29454 add(x, y) { 29455 this.#lastX = x; 29456 this.#lastY = y; 29457 const [layerX, layerY, layerWidth, layerHeight] = this.#box; 29458 let [x1, y1, x2, y2] = this.#last.subarray(8, 12); 29459 const diffX = x - x2; 29460 const diffY = y - y2; 29461 const d = Math.hypot(diffX, diffY); 29462 if (d < this.#min) { 29463 return false; 29464 } 29465 const diffD = d - this.#min_dist; 29466 const K = diffD / d; 29467 const shiftX = K * diffX; 29468 const shiftY = K * diffY; 29469 let x0 = x1; 29470 let y0 = y1; 29471 x1 = x2; 29472 y1 = y2; 29473 x2 += shiftX; 29474 y2 += shiftY; 29475 this.#points?.push(x, y); 29476 const nX = -shiftY / diffD; 29477 const nY = shiftX / diffD; 29478 const thX = nX * this.#thickness; 29479 const thY = nY * this.#thickness; 29480 this.#last.set(this.#last.subarray(2, 8), 0); 29481 this.#last.set([x2 + thX, y2 + thY], 4); 29482 this.#last.set(this.#last.subarray(14, 18), 12); 29483 this.#last.set([x2 - thX, y2 - thY], 16); 29484 if (isNaN(this.#last[6])) { 29485 if (this.#top.length === 0) { 29486 this.#last.set([x1 + thX, y1 + thY], 2); 29487 this.#top.push(NaN, NaN, NaN, NaN, (x1 + thX - layerX) / layerWidth, (y1 + thY - layerY) / layerHeight); 29488 this.#last.set([x1 - thX, y1 - thY], 14); 29489 this.#bottom.push(NaN, NaN, NaN, NaN, (x1 - thX - layerX) / layerWidth, (y1 - thY - layerY) / layerHeight); 29490 } 29491 this.#last.set([x0, y0, x1, y1, x2, y2], 6); 29492 return !this.isEmpty(); 29493 } 29494 this.#last.set([x0, y0, x1, y1, x2, y2], 6); 29495 const angle = Math.abs(Math.atan2(y0 - y1, x0 - x1) - Math.atan2(shiftY, shiftX)); 29496 if (angle < Math.PI / 2) { 29497 [x1, y1, x2, y2] = this.#last.subarray(2, 6); 29498 this.#top.push(NaN, NaN, NaN, NaN, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight); 29499 [x1, y1, x0, y0] = this.#last.subarray(14, 18); 29500 this.#bottom.push(NaN, NaN, NaN, NaN, ((x0 + x1) / 2 - layerX) / layerWidth, ((y0 + y1) / 2 - layerY) / layerHeight); 29501 return true; 29502 } 29503 [x0, y0, x1, y1, x2, y2] = this.#last.subarray(0, 6); 29504 this.#top.push(((x0 + 5 * x1) / 6 - layerX) / layerWidth, ((y0 + 5 * y1) / 6 - layerY) / layerHeight, ((5 * x1 + x2) / 6 - layerX) / layerWidth, ((5 * y1 + y2) / 6 - layerY) / layerHeight, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight); 29505 [x2, y2, x1, y1, x0, y0] = this.#last.subarray(12, 18); 29506 this.#bottom.push(((x0 + 5 * x1) / 6 - layerX) / layerWidth, ((y0 + 5 * y1) / 6 - layerY) / layerHeight, ((5 * x1 + x2) / 6 - layerX) / layerWidth, ((5 * y1 + y2) / 6 - layerY) / layerHeight, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight); 29507 return true; 29508 } 29509 toSVGPath() { 29510 if (this.isEmpty()) { 29511 return ""; 29512 } 29513 const top = this.#top; 29514 const bottom = this.#bottom; 29515 if (isNaN(this.#last[6]) && !this.isEmpty()) { 29516 return this.#toSVGPathTwoPoints(); 29517 } 29518 const buffer = []; 29519 buffer.push(`M${top[4]} ${top[5]}`); 29520 for (let i = 6; i < top.length; i += 6) { 29521 if (isNaN(top[i])) { 29522 buffer.push(`L${top[i + 4]} ${top[i + 5]}`); 29523 } else { 29524 buffer.push(`C${top[i]} ${top[i + 1]} ${top[i + 2]} ${top[i + 3]} ${top[i + 4]} ${top[i + 5]}`); 29525 } 29526 } 29527 this.#toSVGPathEnd(buffer); 29528 for (let i = bottom.length - 6; i >= 6; i -= 6) { 29529 if (isNaN(bottom[i])) { 29530 buffer.push(`L${bottom[i + 4]} ${bottom[i + 5]}`); 29531 } else { 29532 buffer.push(`C${bottom[i]} ${bottom[i + 1]} ${bottom[i + 2]} ${bottom[i + 3]} ${bottom[i + 4]} ${bottom[i + 5]}`); 29533 } 29534 } 29535 this.#toSVGPathStart(buffer); 29536 return buffer.join(" "); 29537 } 29538 #toSVGPathTwoPoints() { 29539 const [x, y, width, height] = this.#box; 29540 const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); 29541 return `M${(this.#last[2] - x) / width} ${(this.#last[3] - y) / height} L${(this.#last[4] - x) / width} ${(this.#last[5] - y) / height} L${lastTopX} ${lastTopY} L${lastBottomX} ${lastBottomY} L${(this.#last[16] - x) / width} ${(this.#last[17] - y) / height} L${(this.#last[14] - x) / width} ${(this.#last[15] - y) / height} Z`; 29542 } 29543 #toSVGPathStart(buffer) { 29544 const bottom = this.#bottom; 29545 buffer.push(`L${bottom[4]} ${bottom[5]} Z`); 29546 } 29547 #toSVGPathEnd(buffer) { 29548 const [x, y, width, height] = this.#box; 29549 const lastTop = this.#last.subarray(4, 6); 29550 const lastBottom = this.#last.subarray(16, 18); 29551 const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); 29552 buffer.push(`L${(lastTop[0] - x) / width} ${(lastTop[1] - y) / height} L${lastTopX} ${lastTopY} L${lastBottomX} ${lastBottomY} L${(lastBottom[0] - x) / width} ${(lastBottom[1] - y) / height}`); 29553 } 29554 newFreeDrawOutline(outline, points, box, scaleFactor, innerMargin, isLTR) { 29555 return new FreeDrawOutline(outline, points, box, scaleFactor, innerMargin, isLTR); 29556 } 29557 getOutlines() { 29558 const top = this.#top; 29559 const bottom = this.#bottom; 29560 const last = this.#last; 29561 const [layerX, layerY, layerWidth, layerHeight] = this.#box; 29562 const points = new Float32Array((this.#points?.length ?? 0) + 2); 29563 for (let i = 0, ii = points.length - 2; i < ii; i += 2) { 29564 points[i] = (this.#points[i] - layerX) / layerWidth; 29565 points[i + 1] = (this.#points[i + 1] - layerY) / layerHeight; 29566 } 29567 points[points.length - 2] = (this.#lastX - layerX) / layerWidth; 29568 points[points.length - 1] = (this.#lastY - layerY) / layerHeight; 29569 if (isNaN(last[6]) && !this.isEmpty()) { 29570 return this.#getOutlineTwoPoints(points); 29571 } 29572 const outline = new Float32Array(this.#top.length + 24 + this.#bottom.length); 29573 let N = top.length; 29574 for (let i = 0; i < N; i += 2) { 29575 if (isNaN(top[i])) { 29576 outline[i] = outline[i + 1] = NaN; 29577 continue; 29578 } 29579 outline[i] = top[i]; 29580 outline[i + 1] = top[i + 1]; 29581 } 29582 N = this.#getOutlineEnd(outline, N); 29583 for (let i = bottom.length - 6; i >= 6; i -= 6) { 29584 for (let j = 0; j < 6; j += 2) { 29585 if (isNaN(bottom[i + j])) { 29586 outline[N] = outline[N + 1] = NaN; 29587 N += 2; 29588 continue; 29589 } 29590 outline[N] = bottom[i + j]; 29591 outline[N + 1] = bottom[i + j + 1]; 29592 N += 2; 29593 } 29594 } 29595 this.#getOutlineStart(outline, N); 29596 return this.newFreeDrawOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR); 29597 } 29598 #getOutlineTwoPoints(points) { 29599 const last = this.#last; 29600 const [layerX, layerY, layerWidth, layerHeight] = this.#box; 29601 const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); 29602 const outline = new Float32Array(36); 29603 outline.set([NaN, NaN, NaN, NaN, (last[2] - layerX) / layerWidth, (last[3] - layerY) / layerHeight, NaN, NaN, NaN, NaN, (last[4] - layerX) / layerWidth, (last[5] - layerY) / layerHeight, NaN, NaN, NaN, NaN, lastTopX, lastTopY, NaN, NaN, NaN, NaN, lastBottomX, lastBottomY, NaN, NaN, NaN, NaN, (last[16] - layerX) / layerWidth, (last[17] - layerY) / layerHeight, NaN, NaN, NaN, NaN, (last[14] - layerX) / layerWidth, (last[15] - layerY) / layerHeight], 0); 29604 return this.newFreeDrawOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR); 29605 } 29606 #getOutlineStart(outline, pos) { 29607 const bottom = this.#bottom; 29608 outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], pos); 29609 return pos += 6; 29610 } 29611 #getOutlineEnd(outline, pos) { 29612 const lastTop = this.#last.subarray(4, 6); 29613 const lastBottom = this.#last.subarray(16, 18); 29614 const [layerX, layerY, layerWidth, layerHeight] = this.#box; 29615 const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); 29616 outline.set([NaN, NaN, NaN, NaN, (lastTop[0] - layerX) / layerWidth, (lastTop[1] - layerY) / layerHeight, NaN, NaN, NaN, NaN, lastTopX, lastTopY, NaN, NaN, NaN, NaN, lastBottomX, lastBottomY, NaN, NaN, NaN, NaN, (lastBottom[0] - layerX) / layerWidth, (lastBottom[1] - layerY) / layerHeight], pos); 29617 return pos += 24; 29618 } 29619} 29620class FreeDrawOutline extends Outline { 29621 #box; 29622 #bbox = new Float32Array(4); 29623 #innerMargin; 29624 #isLTR; 29625 #points; 29626 #scaleFactor; 29627 #outline; 29628 constructor(outline, points, box, scaleFactor, innerMargin, isLTR) { 29629 super(); 29630 this.#outline = outline; 29631 this.#points = points; 29632 this.#box = box; 29633 this.#scaleFactor = scaleFactor; 29634 this.#innerMargin = innerMargin; 29635 this.#isLTR = isLTR; 29636 this.firstPoint = [NaN, NaN]; 29637 this.lastPoint = [NaN, NaN]; 29638 this.#computeMinMax(isLTR); 29639 const [x, y, width, height] = this.#bbox; 29640 for (let i = 0, ii = outline.length; i < ii; i += 2) { 29641 outline[i] = (outline[i] - x) / width; 29642 outline[i + 1] = (outline[i + 1] - y) / height; 29643 } 29644 for (let i = 0, ii = points.length; i < ii; i += 2) { 29645 points[i] = (points[i] - x) / width; 29646 points[i + 1] = (points[i + 1] - y) / height; 29647 } 29648 } 29649 toSVGPath() { 29650 const buffer = [`M${this.#outline[4]} ${this.#outline[5]}`]; 29651 for (let i = 6, ii = this.#outline.length; i < ii; i += 6) { 29652 if (isNaN(this.#outline[i])) { 29653 buffer.push(`L${this.#outline[i + 4]} ${this.#outline[i + 5]}`); 29654 continue; 29655 } 29656 buffer.push(`C${this.#outline[i]} ${this.#outline[i + 1]} ${this.#outline[i + 2]} ${this.#outline[i + 3]} ${this.#outline[i + 4]} ${this.#outline[i + 5]}`); 29657 } 29658 buffer.push("Z"); 29659 return buffer.join(" "); 29660 } 29661 serialize([blX, blY, trX, trY], rotation) { 29662 const width = trX - blX; 29663 const height = trY - blY; 29664 let outline; 29665 let points; 29666 switch (rotation) { 29667 case 0: 29668 outline = Outline._rescale(this.#outline, blX, trY, width, -height); 29669 points = Outline._rescale(this.#points, blX, trY, width, -height); 29670 break; 29671 case 90: 29672 outline = Outline._rescaleAndSwap(this.#outline, blX, blY, width, height); 29673 points = Outline._rescaleAndSwap(this.#points, blX, blY, width, height); 29674 break; 29675 case 180: 29676 outline = Outline._rescale(this.#outline, trX, blY, -width, height); 29677 points = Outline._rescale(this.#points, trX, blY, -width, height); 29678 break; 29679 case 270: 29680 outline = Outline._rescaleAndSwap(this.#outline, trX, trY, -width, -height); 29681 points = Outline._rescaleAndSwap(this.#points, trX, trY, -width, -height); 29682 break; 29683 } 29684 return { 29685 outline: Array.from(outline), 29686 points: [Array.from(points)] 29687 }; 29688 } 29689 #computeMinMax(isLTR) { 29690 const outline = this.#outline; 29691 let lastX = outline[4]; 29692 let lastY = outline[5]; 29693 const minMax = [lastX, lastY, lastX, lastY]; 29694 let firstPointX = lastX; 29695 let firstPointY = lastY; 29696 let lastPointX = lastX; 29697 let lastPointY = lastY; 29698 const ltrCallback = isLTR ? Math.max : Math.min; 29699 const bezierBbox = new Float32Array(4); 29700 for (let i = 6, ii = outline.length; i < ii; i += 6) { 29701 const x = outline[i + 4], 29702 y = outline[i + 5]; 29703 if (isNaN(outline[i])) { 29704 Util.pointBoundingBox(x, y, minMax); 29705 if (firstPointY > y) { 29706 firstPointX = x; 29707 firstPointY = y; 29708 } else if (firstPointY === y) { 29709 firstPointX = ltrCallback(firstPointX, x); 29710 } 29711 if (lastPointY < y) { 29712 lastPointX = x; 29713 lastPointY = y; 29714 } else if (lastPointY === y) { 29715 lastPointX = ltrCallback(lastPointX, x); 29716 } 29717 } else { 29718 bezierBbox.set(BBOX_INIT, 0); 29719 Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6), bezierBbox); 29720 Util.rectBoundingBox(...bezierBbox, minMax); 29721 if (firstPointY > bezierBbox[1]) { 29722 firstPointX = bezierBbox[0]; 29723 firstPointY = bezierBbox[1]; 29724 } else if (firstPointY === bezierBbox[1]) { 29725 firstPointX = ltrCallback(firstPointX, bezierBbox[0]); 29726 } 29727 if (lastPointY < bezierBbox[3]) { 29728 lastPointX = bezierBbox[2]; 29729 lastPointY = bezierBbox[3]; 29730 } else if (lastPointY === bezierBbox[3]) { 29731 lastPointX = ltrCallback(lastPointX, bezierBbox[2]); 29732 } 29733 } 29734 lastX = x; 29735 lastY = y; 29736 } 29737 const bbox = this.#bbox; 29738 bbox[0] = minMax[0] - this.#innerMargin; 29739 bbox[1] = minMax[1] - this.#innerMargin; 29740 bbox[2] = minMax[2] - minMax[0] + 2 * this.#innerMargin; 29741 bbox[3] = minMax[3] - minMax[1] + 2 * this.#innerMargin; 29742 this.firstPoint = [firstPointX, firstPointY]; 29743 this.lastPoint = [lastPointX, lastPointY]; 29744 } 29745 get box() { 29746 return this.#bbox; 29747 } 29748 newOutliner(x, y, box, scaleFactor, thickness, isLTR, innerMargin = 0) { 29749 return new FreeDrawOutliner(x, y, box, scaleFactor, thickness, isLTR, innerMargin); 29750 } 29751 updateThickness(thickness) { 29752 const outline = this.getNewOutline(thickness); 29753 this.#outline = outline.#outline; 29754 this.#points = outline.#points; 29755 this.#bbox.set(outline.#bbox); 29756 this.firstPoint = outline.firstPoint; 29757 this.lastPoint = outline.lastPoint; 29758 return this.#bbox; 29759 } 29760 getNewOutline(thickness, innerMargin) { 29761 const [x, y, width, height] = this.#bbox; 29762 const [layerX, layerY, layerWidth, layerHeight] = this.#box; 29763 const sx = width * layerWidth; 29764 const sy = height * layerHeight; 29765 const tx = x * layerWidth + layerX; 29766 const ty = y * layerHeight + layerY; 29767 const points = this.#points; 29768 const outliner = this.newOutliner(points[0] * sx + tx, points[1] * sy + ty, this.#box, this.#scaleFactor, thickness, this.#isLTR, innerMargin ?? this.#innerMargin); 29769 for (let i = 2, ii = points.length; i < ii; i += 2) { 29770 outliner.add(points[i] * sx + tx, points[i + 1] * sy + ty); 29771 } 29772 return outliner.getOutlines(); 29773 } 29774} 29775 29776;// ./src/display/editor/drawers/highlight.js 29777 29778 29779
29780 29781 29782 29783 29784
vendor: 42,652 bytes, lines 29785-31311
29785 29786 29787 29788 29789function getHighlightSVGProperties(outline) { 29790 return { 29791 bbox: outline.box, 29792 root: { 29793 viewBox: "0 0 1 1" 29794 }, 29795 rootClass: { 29796 highlight: true, 29797 free: outline.isFree 29798 }, 29799 path: { 29800 d: outline.toSVGPath() 29801 } 29802 }; 29803} 29804function getHighlightFocusSVGProperties(outline, rotation) { 29805 const { 29806 focusOutline 29807 } = outline; 29808 return { 29809 bbox: Outline._rotateBox(focusOutline.box, rotation), 29810 root: { 29811 "data-main-rotation": rotation 29812 }, 29813 rootClass: { 29814 highlightOutline: true, 29815 free: outline.isFree 29816 }, 29817 path: { 29818 d: focusOutline.toSVGPath() 29819 } 29820 }; 29821} 29822class HighlightOutliner { 29823 #box; 29824 #firstPoint; 29825 #lastPoint; 29826 #verticalEdges = []; 29827 #intervals = []; 29828 constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) { 29829 const minMax = BBOX_INIT.slice(); 29830 const NUMBER_OF_DIGITS = 4; 29831 const EPSILON = 10 ** -NUMBER_OF_DIGITS; 29832 for (const { 29833 x, 29834 y, 29835 width, 29836 height 29837 } of boxes) { 29838 const x1 = Math.floor((x - borderWidth) / EPSILON) * EPSILON; 29839 const x2 = Math.ceil((x + width + borderWidth) / EPSILON) * EPSILON; 29840 const y1 = Math.floor((y - borderWidth) / EPSILON) * EPSILON; 29841 const y2 = Math.ceil((y + height + borderWidth) / EPSILON) * EPSILON; 29842 const left = [x1, y1, y2, true]; 29843 const right = [x2, y1, y2, false]; 29844 this.#verticalEdges.push(left, right); 29845 Util.rectBoundingBox(x1, y1, x2, y2, minMax); 29846 } 29847 const bboxWidth = minMax[2] - minMax[0] + 2 * innerMargin; 29848 const bboxHeight = minMax[3] - minMax[1] + 2 * innerMargin; 29849 const shiftedMinX = minMax[0] - innerMargin; 29850 const shiftedMinY = minMax[1] - innerMargin; 29851 let firstPointX = isLTR ? -Infinity : Infinity; 29852 let firstPointY = Infinity; 29853 const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2); 29854 const lastPoint = [lastEdge[0], lastEdge[2]]; 29855 for (const edge of this.#verticalEdges) { 29856 const [x, y1, y2, left] = edge; 29857 if (!left && isLTR) { 29858 if (y1 < firstPointY) { 29859 firstPointY = y1; 29860 firstPointX = x; 29861 } else if (y1 === firstPointY) { 29862 firstPointX = Math.max(firstPointX, x); 29863 } 29864 } else if (left && !isLTR) { 29865 if (y1 < firstPointY) { 29866 firstPointY = y1; 29867 firstPointX = x; 29868 } else if (y1 === firstPointY) { 29869 firstPointX = Math.min(firstPointX, x); 29870 } 29871 } 29872 edge[0] = (x - shiftedMinX) / bboxWidth; 29873 edge[1] = (y1 - shiftedMinY) / bboxHeight; 29874 edge[2] = (y2 - shiftedMinY) / bboxHeight; 29875 } 29876 this.#box = new Float32Array([shiftedMinX, shiftedMinY, bboxWidth, bboxHeight]); 29877 this.#firstPoint = [firstPointX, firstPointY]; 29878 this.#lastPoint = lastPoint; 29879 } 29880 getOutlines() { 29881 this.#verticalEdges.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]); 29882 const outlineVerticalEdges = []; 29883 for (const edge of this.#verticalEdges) { 29884 if (edge[3]) { 29885 outlineVerticalEdges.push(...this.#breakEdge(edge)); 29886 this.#insert(edge); 29887 } else { 29888 this.#remove(edge); 29889 outlineVerticalEdges.push(...this.#breakEdge(edge)); 29890 } 29891 } 29892 return this.#getOutlines(outlineVerticalEdges); 29893 } 29894 #getOutlines(outlineVerticalEdges) { 29895 const edges = []; 29896 const allEdges = new Set(); 29897 for (const edge of outlineVerticalEdges) { 29898 const [x, y1, y2] = edge; 29899 edges.push([x, y1, edge], [x, y2, edge]); 29900 } 29901 edges.sort((a, b) => a[1] - b[1] || a[0] - b[0]); 29902 for (let i = 0, ii = edges.length; i < ii; i += 2) { 29903 const edge1 = edges[i][2]; 29904 const edge2 = edges[i + 1][2]; 29905 edge1.push(edge2); 29906 edge2.push(edge1); 29907 allEdges.add(edge1); 29908 allEdges.add(edge2); 29909 } 29910 const outlines = []; 29911 let outline; 29912 while (allEdges.size > 0) { 29913 const edge = allEdges.values().next().value; 29914 let [x, y1, y2, edge1, edge2] = edge; 29915 allEdges.delete(edge); 29916 let lastPointX = x; 29917 let lastPointY = y1; 29918 outline = [x, y2]; 29919 outlines.push(outline); 29920 while (true) { 29921 let e; 29922 if (allEdges.has(edge1)) { 29923 e = edge1; 29924 } else if (allEdges.has(edge2)) { 29925 e = edge2; 29926 } else { 29927 break; 29928 } 29929 allEdges.delete(e); 29930 [x, y1, y2, edge1, edge2] = e; 29931 if (lastPointX !== x) { 29932 outline.push(lastPointX, lastPointY, x, lastPointY === y1 ? y1 : y2); 29933 lastPointX = x; 29934 } 29935 lastPointY = lastPointY === y1 ? y2 : y1; 29936 } 29937 outline.push(lastPointX, lastPointY); 29938 } 29939 return new HighlightOutline(outlines, this.#box, this.#firstPoint, this.#lastPoint); 29940 } 29941 #binarySearch(y) { 29942 const array = this.#intervals; 29943 let start = 0; 29944 let end = array.length - 1; 29945 while (start <= end) { 29946 const middle = start + end >> 1; 29947 const y1 = array[middle][0]; 29948 if (y1 === y) { 29949 return middle; 29950 } 29951 if (y1 < y) { 29952 start = middle + 1; 29953 } else { 29954 end = middle - 1; 29955 } 29956 } 29957 return end + 1; 29958 } 29959 #insert([, y1, y2]) { 29960 const index = this.#binarySearch(y1); 29961 this.#intervals.splice(index, 0, [y1, y2]); 29962 } 29963 #remove([, y1, y2]) { 29964 const index = this.#binarySearch(y1); 29965 for (let i = index; i < this.#intervals.length; i++) { 29966 const [start, end] = this.#intervals[i]; 29967 if (start !== y1) { 29968 break; 29969 } 29970 if (start === y1 && end === y2) { 29971 this.#intervals.splice(i, 1); 29972 return; 29973 } 29974 } 29975 for (let i = index - 1; i >= 0; i--) { 29976 const [start, end] = this.#intervals[i]; 29977 if (start !== y1) { 29978 break; 29979 } 29980 if (start === y1 && end === y2) { 29981 this.#intervals.splice(i, 1); 29982 return; 29983 } 29984 } 29985 } 29986 #breakEdge(edge) { 29987 const [x, y1, y2] = edge; 29988 const results = [[x, y1, y2]]; 29989 const index = this.#binarySearch(y2); 29990 for (let i = 0; i < index; i++) { 29991 const [start, end] = this.#intervals[i]; 29992 for (let j = 0, jj = results.length; j < jj; j++) { 29993 const [, y3, y4] = results[j]; 29994 if (end <= y3 || y4 <= start) { 29995 continue; 29996 } 29997 if (y3 >= start) { 29998 if (y4 > end) { 29999 results[j][1] = end; 30000 } else { 30001 if (jj === 1) { 30002 return []; 30003 } 30004 results.splice(j, 1); 30005 j--; 30006 jj--; 30007 } 30008 continue; 30009 } 30010 results[j][2] = start; 30011 if (y4 > end) { 30012 results.push([x, end, y4]); 30013 } 30014 } 30015 } 30016 return results; 30017 } 30018} 30019class HighlightOutline extends Outline { 30020 #box; 30021 #boxes = null; 30022 #outlines; 30023 constructor(outlines, box, firstPoint, lastPoint) { 30024 super(); 30025 this.#outlines = outlines; 30026 this.#box = box; 30027 this.firstPoint = firstPoint; 30028 this.lastPoint = lastPoint; 30029 } 30030 static build(boxes, isLTR) { 30031 const outline = new HighlightOutliner(boxes, 0.001).getOutlines(); 30032 outline.#boxes = boxes; 30033 outline.focusOutline = new HighlightOutliner(boxes, 0.0025, 0.001, isLTR).getOutlines(); 30034 return outline; 30035 } 30036 get isFree() { 30037 return false; 30038 } 30039 get defaultSVGProperties() { 30040 return getHighlightSVGProperties(this); 30041 } 30042 getFocusSVGProperties(rotation) { 30043 return getHighlightFocusSVGProperties(this, rotation); 30044 } 30045 updateRotation(rotation) { 30046 return { 30047 root: { 30048 "data-main-rotation": rotation 30049 } 30050 }; 30051 } 30052 serializeQuadPoints([pageX, pageY], [pageWidth, pageHeight]) { 30053 const boxes = this.#boxes; 30054 const quadPoints = new Float32Array(boxes.length * 8); 30055 let i = 0; 30056 for (const { 30057 x, 30058 y, 30059 width, 30060 height 30061 } of boxes) { 30062 const sx = x * pageWidth + pageX; 30063 const sy = (1 - y) * pageHeight + pageY; 30064 quadPoints[i] = quadPoints[i + 4] = sx; 30065 quadPoints[i + 1] = quadPoints[i + 3] = sy; 30066 quadPoints[i + 2] = quadPoints[i + 6] = sx + width * pageWidth; 30067 quadPoints[i + 5] = quadPoints[i + 7] = sy - height * pageHeight; 30068 i += 8; 30069 } 30070 return quadPoints; 30071 } 30072 toSVGPath() { 30073 const buffer = []; 30074 for (const polygon of this.#outlines) { 30075 let [prevX, prevY] = polygon; 30076 buffer.push(`M${prevX} ${prevY}`); 30077 for (let i = 2; i < polygon.length; i += 2) { 30078 const x = polygon[i]; 30079 const y = polygon[i + 1]; 30080 if (x === prevX) { 30081 buffer.push(`V${y}`); 30082 prevY = y; 30083 } else if (y === prevY) { 30084 buffer.push(`H${x}`); 30085 prevX = x; 30086 } 30087 } 30088 buffer.push("Z"); 30089 } 30090 return buffer.join(" "); 30091 } 30092 serialize([blX, blY, trX, trY], _rotation) { 30093 const outlines = []; 30094 const width = trX - blX; 30095 const height = trY - blY; 30096 for (const outline of this.#outlines) { 30097 const points = new Array(outline.length); 30098 for (let i = 0; i < outline.length; i += 2) { 30099 points[i] = blX + outline[i] * width; 30100 points[i + 1] = trY - outline[i + 1] * height; 30101 } 30102 outlines.push(points); 30103 } 30104 return outlines; 30105 } 30106 get box() { 30107 return this.#box; 30108 } 30109} 30110class FreeHighlightOutliner extends FreeDrawOutliner { 30111 newFreeDrawOutline(outline, points, box, scaleFactor, innerMargin, isLTR) { 30112 return new FreeHighlightOutline(outline, points, box, scaleFactor, innerMargin, isLTR); 30113 } 30114} 30115class FreeHighlightDrawer { 30116 #outliner; 30117 #thickness; 30118 constructor(x, y, box, scaleFactor, thickness, isLTR, innerMargin) { 30119 this.#outliner = new FreeHighlightOutliner(x, y, box, scaleFactor, thickness, isLTR, innerMargin); 30120 this.#thickness = thickness; 30121 } 30122 add(x, y) { 30123 return this.#outliner.add(x, y) ? { 30124 path: { 30125 d: this.#outliner.toSVGPath() 30126 } 30127 } : null; 30128 } 30129 addPoints(points) { 30130 let hasChanged = false; 30131 for (let i = 0, ii = points.length; i < ii; i += 2) { 30132 hasChanged = this.#outliner.add(points[i], points[i + 1]) || hasChanged; 30133 } 30134 return hasChanged ? { 30135 path: { 30136 d: this.#outliner.toSVGPath() 30137 } 30138 } : null; 30139 } 30140 end(x, y) { 30141 return x === undefined ? null : this.add(x, y); 30142 } 30143 isEmpty() { 30144 return this.#outliner.isEmpty(); 30145 } 30146 isCancellable() { 30147 return this.#outliner.isCancellable(); 30148 } 30149 removeLastElement() { 30150 return this.#outliner.removeLastElement(); 30151 } 30152 updateProperty(_name, _value) { 30153 return null; 30154 } 30155 getOutlines() { 30156 const outlines = this.#outliner.getOutlines(); 30157 outlines.buildFocusOutline(2 * this.#thickness); 30158 return outlines; 30159 } 30160 get defaultSVGProperties() { 30161 return { 30162 bbox: [0, 0, 1, 1], 30163 root: { 30164 viewBox: "0 0 1 1" 30165 }, 30166 rootClass: { 30167 highlight: true, 30168 free: true 30169 }, 30170 path: { 30171 d: this.#outliner.toSVGPath() 30172 } 30173 }; 30174 } 30175} 30176class FreeHighlightOutline extends FreeDrawOutline { 30177 static #EXTRA_THICKNESS = 1.5; 30178 newOutliner(x, y, box, scaleFactor, thickness, isLTR, innerMargin = 0) { 30179 return new FreeHighlightOutliner(x, y, box, scaleFactor, thickness, isLTR, innerMargin); 30180 } 30181 get isFree() { 30182 return true; 30183 } 30184 buildFocusOutline(thickness) { 30185 this.focusOutline = this.getNewOutline(thickness / 2 + FreeHighlightOutline.#EXTRA_THICKNESS, 0.0025); 30186 } 30187 get defaultSVGProperties() { 30188 return getHighlightSVGProperties(this); 30189 } 30190 getFocusSVGProperties(rotation) { 30191 return getHighlightFocusSVGProperties(this, rotation); 30192 } 30193 get focusMustRemoveSelfIntersections() { 30194 return true; 30195 } 30196 updateRotation(rotation) { 30197 return { 30198 root: { 30199 "data-main-rotation": rotation 30200 } 30201 }; 30202 } 30203 updateProperty(name, value) { 30204 if (name !== "thickness") { 30205 return null; 30206 } 30207 const bbox = this.updateThickness(value / 2); 30208 this.buildFocusOutline(value); 30209 return bbox; 30210 } 30211 getPathResizedSVGProperties() { 30212 return { 30213 path: { 30214 d: this.toSVGPath() 30215 } 30216 }; 30217 } 30218} 30219 30220;// ./src/display/editor/highlight.js 30221 30222 30223 30224 30225 30226 30227 30228 30229 30230 30231 30232 30233 30234class HighlightDrawingOptions extends DrawingOptions { 30235 constructor(properties = null) { 30236 super(); 30237 super.updateProperties(properties); 30238 } 30239 updateSVGProperty(name, value) { 30240 if (name !== "thickness") { 30241 super.updateSVGProperty(name, value); 30242 } 30243 } 30244 clone() { 30245 const clone = new HighlightDrawingOptions(); 30246 clone.updateAll(this); 30247 return clone; 30248 } 30249} 30250class HighlightEditor extends DrawingEditor { 30251 #anchorNode = null; 30252 #anchorOffset = 0; 30253 #focusNode = null; 30254 #focusOffset = 0; 30255 #methodOfCreation = ""; 30256 #text = ""; 30257 static _DEFAULT_OPACITY = 1; 30258 static _DEFAULT_THICKNESS = 12; 30259 static _defaultDrawingOptions = null; 30260 static _type = "highlight"; 30261 static _editorType = AnnotationEditorType.HIGHLIGHT; 30262 static get _keyboardManager() { 30263 const proto = HighlightEditor.prototype; 30264 return shadow(this, "_keyboardManager", new KeyboardManager([[["ArrowLeft"], proto._moveCaret, { 30265 args: [0] 30266 }], [["ArrowRight"], proto._moveCaret, { 30267 args: [1] 30268 }], [["ArrowUp"], proto._moveCaret, { 30269 args: [2] 30270 }], [["ArrowDown"], proto._moveCaret, { 30271 args: [3] 30272 }]])); 30273 } 30274 constructor(params) { 30275 super({ 30276 ...params, 30277 name: "highlightEditor" 30278 }); 30279 this.#anchorNode = params.anchorNode || null; 30280 this.#anchorOffset = params.anchorOffset || 0; 30281 this.#focusNode = params.focusNode || null; 30282 this.#focusOffset = params.focusOffset || 0; 30283 this.#methodOfCreation = params.methodOfCreation || (this._drawOutlines?.isFree ? "main_toolbar" : ""); 30284 this.#text = params.text || ""; 30285 this._isDraggable = false; 30286 this.defaultL10nId = "pdfjs-editor-highlight-editor"; 30287 this.rotate(); 30288 } 30289 static initialize(l10n, uiManager) { 30290 AnnotationEditor.initialize(l10n, uiManager); 30291 this._defaultDrawingOptions ||= new HighlightDrawingOptions({ 30292 fill: uiManager.highlightColors?.values().next().value || "#fff066", 30293 "fill-opacity": HighlightEditor._DEFAULT_OPACITY, 30294 thickness: HighlightEditor._DEFAULT_THICKNESS 30295 }); 30296 } 30297 static getDefaultDrawingOptions(options) { 30298 const clone = this._defaultDrawingOptions.clone(); 30299 clone.updateProperties(options); 30300 return clone; 30301 } 30302 static get typesMap() { 30303 return shadow(this, "typesMap", new Map([[AnnotationEditorParamsType.HIGHLIGHT_COLOR, "fill"], [AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, "thickness"]])); 30304 } 30305 static get isDrawer() { 30306 return false; 30307 } 30308 static get _hasClipPath() { 30309 return true; 30310 } 30311 static get _hasDrawClass() { 30312 return false; 30313 } 30314 _addOutlines(params) { 30315 const { 30316 boxes, 30317 drawOutlines 30318 } = params; 30319 if (!boxes && !drawOutlines) { 30320 return; 30321 } 30322 this._drawingOptions ||= params.drawingOptions || HighlightEditor.getDefaultDrawingOptions(); 30323 if (boxes) { 30324 params = { 30325 ...params, 30326 drawOutlines: HighlightOutline.build(boxes, this._uiManager.direction === "ltr") 30327 }; 30328 } 30329 super._addOutlines(params); 30330 } 30331 get colorType() { 30332 return AnnotationEditorParamsType.HIGHLIGHT_COLOR; 30333 } 30334 get color() { 30335 return this._drawingOptions.fill; 30336 } 30337 get opacity() { 30338 return this._drawingOptions["fill-opacity"]; 30339 } 30340 get _opacityName() { 30341 return "fill-opacity"; 30342 } 30343 get _drawRotation() { 30344 return this._drawOutlines?.isFree ? this.rotation : 0; 30345 } 30346 get isResizable() { 30347 return false; 30348 } 30349 get _mustBeDisabledOnCommit() { 30350 return false; 30351 } 30352 get _mustFixPosition() { 30353 return !this._drawOutlines?.isFree; 30354 } 30355 get telemetryInitialData() { 30356 return { 30357 action: "added", 30358 type: this._drawOutlines.isFree ? "free_highlight" : "highlight", 30359 color: this._uiManager.getNonHCMColorName(this.color), 30360 thickness: this._drawingOptions.thickness, 30361 methodOfCreation: this.#methodOfCreation 30362 }; 30363 } 30364 get telemetryFinalData() { 30365 return { 30366 type: "highlight", 30367 color: this._uiManager.getNonHCMColorName(this.color) 30368 }; 30369 } 30370 static computeTelemetryFinalData(data) { 30371 return { 30372 numberOfColors: data.get("color").size 30373 }; 30374 } 30375 translateInPage(x, y) {} 30376 get toolbarPosition() { 30377 return this.#relativeToBox(this._drawOutlines.focusOutline.lastPoint); 30378 } 30379 get commentButtonPosition() { 30380 return this.#relativeToBox(this._drawOutlines.firstPoint); 30381 } 30382 #relativeToBox([pointX, pointY]) { 30383 const [x, y, width, height] = this._drawOutlines.box; 30384 return [(pointX - x) / width, (pointY - y) / height]; 30385 } 30386 updateParams(type, value) { 30387 switch (type) { 30388 case AnnotationEditorParamsType.HIGHLIGHT_COLOR: 30389 this._updateColorAndOpacity(value, HighlightEditor._DEFAULT_OPACITY, type); 30390 this._reportTelemetry({ 30391 action: "color_changed", 30392 color: this._uiManager.getNonHCMColorName(value) 30393 }, true); 30394 break; 30395 case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS: 30396 super.updateParams(type, value); 30397 this._reportTelemetry({ 30398 action: "thickness_changed", 30399 thickness: value 30400 }, true); 30401 break; 30402 } 30403 } 30404 get propertiesToUpdate() { 30405 const properties = super.propertiesToUpdate; 30406 properties.push([AnnotationEditorParamsType.HIGHLIGHT_FREE, this._drawOutlines.isFree]); 30407 return properties; 30408 } 30409 get toolbarButtons() { 30410 if (this._uiManager.highlightColors) { 30411 this._colorPicker = new ColorPicker({ 30412 editor: this 30413 }); 30414 return [["colorPicker", this._colorPicker]]; 30415 } 30416 return super.toolbarButtons; 30417 } 30418 fixAndSetPosition() { 30419 return super.fixAndSetPosition(this._drawRotation); 30420 } 30421 getRect(tx, ty) { 30422 return super.getRect(tx, ty, this._drawRotation); 30423 } 30424 onceAdded(focus) { 30425 if (!this.annotationElementId) { 30426 this.parent.addUndoableEditor(this); 30427 } 30428 if (focus) { 30429 this.div.focus(); 30430 } 30431 } 30432 remove() { 30433 this._reportTelemetry({ 30434 action: "deleted" 30435 }); 30436 super.remove(); 30437 } 30438 render() { 30439 if (this.div) { 30440 return this.div; 30441 } 30442 const div = super.render(); 30443 if (this.#text) { 30444 div.setAttribute("aria-label", this.#text); 30445 div.setAttribute("role", "mark"); 30446 } 30447 if (this._drawOutlines.isFree) { 30448 div.classList.add("free"); 30449 } else { 30450 div.addEventListener("keydown", this.#keydown.bind(this), { 30451 signal: this._uiManager._signal 30452 }); 30453 } 30454 this.enableEditing(); 30455 return div; 30456 } 30457 #keydown(event) { 30458 HighlightEditor._keyboardManager.exec(this, event); 30459 } 30460 _moveCaret(direction) { 30461 this.parent.unselect(this); 30462 switch (direction) { 30463 case 0: 30464 case 2: 30465 this.#setCaret(true); 30466 break; 30467 case 1: 30468 case 3: 30469 this.#setCaret(false); 30470 break; 30471 } 30472 } 30473 #setCaret(start) { 30474 if (!this.#anchorNode) { 30475 return; 30476 } 30477 const selection = window.getSelection(); 30478 if (start) { 30479 selection.setPosition(this.#anchorNode, this.#anchorOffset); 30480 } else { 30481 selection.setPosition(this.#focusNode, this.#focusOffset); 30482 } 30483 } 30484 unselect() { 30485 super.unselect(); 30486 if (!this._drawOutlines.isFree) { 30487 this.#setCaret(false); 30488 } 30489 } 30490 static createDrawerInstance({ 30491 x, 30492 y, 30493 box, 30494 parent, 30495 isLTR 30496 }) { 30497 return new FreeHighlightDrawer(x, y, box, parent.scale, this._defaultDrawingOptions.thickness / 2, isLTR, 0.001); 30498 } 30499 static _getDrawingTarget(parent, { 30500 target 30501 }) { 30502 return target.closest(".textLayer"); 30503 } 30504 static _getPointerCoords({ 30505 x, 30506 y 30507 }) { 30508 return [x, y]; 30509 } 30510 static _addDrawingListeners(target, signal) { 30511 target.classList.add("free"); 30512 signal.addEventListener("abort", () => target.classList.remove("free"), { 30513 once: true 30514 }); 30515 window.addEventListener("blur", () => this._endDraw(null), { 30516 signal 30517 }); 30518 window.addEventListener("pointerdown", stopEvent, { 30519 capture: true, 30520 passive: false, 30521 signal 30522 }); 30523 } 30524 static _endDrawingSession(isAborted = false) { 30525 return this.endDrawing(isAborted); 30526 } 30527 createDrawingOptions({ 30528 color, 30529 opacity, 30530 thickness 30531 }) { 30532 const { 30533 _defaultDrawingOptions: defaults, 30534 _DEFAULT_OPACITY 30535 } = HighlightEditor; 30536 this._drawingOptions = HighlightEditor.getDefaultDrawingOptions({ 30537 fill: Util.makeHexColor(...color), 30538 "fill-opacity": opacity || _DEFAULT_OPACITY, 30539 thickness: thickness || defaults.thickness 30540 }); 30541 } 30542 static deserializeDraw(pageX, pageY, pageWidth, pageHeight, _innerMargin, data, uiManager) { 30543 const { 30544 quadPoints 30545 } = data; 30546 if (quadPoints) { 30547 const boxes = []; 30548 for (let i = 0, ii = quadPoints.length; i < ii; i += 8) { 30549 boxes.push({ 30550 x: (quadPoints[i] - pageX) / pageWidth, 30551 y: 1 - (quadPoints[i + 1] - pageY) / pageHeight, 30552 width: (quadPoints[i + 2] - quadPoints[i]) / pageWidth, 30553 height: (quadPoints[i + 1] - quadPoints[i + 5]) / pageHeight 30554 }); 30555 } 30556 return HighlightOutline.build(boxes, uiManager.direction === "ltr"); 30557 } 30558 const thickness = data.thickness || this._defaultDrawingOptions.thickness; 30559 const points = (data.inkLists || data.outlines.points)[0]; 30560 const outliner = new FreeHighlightOutliner(points[0] - pageX, pageHeight - (points[1] - pageY), [0, 0, pageWidth, pageHeight], 1, thickness / 2, true, 0.001); 30561 for (let i = 0, ii = points.length; i < ii; i += 2) { 30562 outliner.add(points[i] - pageX, pageHeight - (points[i + 1] - pageY)); 30563 } 30564 const outlines = outliner.getOutlines(); 30565 outlines.buildFocusOutline(thickness); 30566 return outlines; 30567 } 30568 static async deserialize(data, parent, uiManager) { 30569 let initialData = null; 30570 if (data instanceof HighlightAnnotationElement) { 30571 const { 30572 data: { 30573 quadPoints, 30574 rect, 30575 rotation, 30576 id, 30577 color, 30578 opacity, 30579 popupRef, 30580 richText, 30581 contentsObj, 30582 creationDate, 30583 modificationDate 30584 }, 30585 parent: { 30586 page: { 30587 pageNumber 30588 } 30589 } 30590 } = data; 30591 initialData = data = { 30592 annotationType: AnnotationEditorType.HIGHLIGHT, 30593 color: Array.from(color), 30594 opacity, 30595 quadPoints, 30596 pageIndex: pageNumber - 1, 30597 rect: rect.slice(0), 30598 rotation, 30599 annotationElementId: id, 30600 id, 30601 deleted: false, 30602 popupRef, 30603 richText, 30604 comment: contentsObj?.str || null, 30605 creationDate, 30606 modificationDate 30607 }; 30608 } else if (data instanceof InkAnnotationElement) { 30609 const { 30610 data: { 30611 inkLists, 30612 rect, 30613 rotation, 30614 id, 30615 color, 30616 borderStyle: { 30617 rawWidth: thickness 30618 }, 30619 popupRef, 30620 richText, 30621 contentsObj, 30622 creationDate, 30623 modificationDate 30624 }, 30625 parent: { 30626 page: { 30627 pageNumber 30628 } 30629 } 30630 } = data; 30631 initialData = data = { 30632 annotationType: AnnotationEditorType.HIGHLIGHT, 30633 color: Array.from(color), 30634 thickness, 30635 inkLists, 30636 pageIndex: pageNumber - 1, 30637 rect: rect.slice(0), 30638 rotation, 30639 annotationElementId: id, 30640 id, 30641 deleted: false, 30642 popupRef, 30643 richText, 30644 comment: contentsObj?.str || null, 30645 creationDate, 30646 modificationDate 30647 }; 30648 } 30649 const editor = await super.deserialize(data, parent, uiManager); 30650 editor._initialData = initialData; 30651 if (data.comment) { 30652 editor.setCommentData(data); 30653 } 30654 return editor; 30655 } 30656 serialize(isForCopying = false) { 30657 if (this.isEmpty() || isForCopying) { 30658 return null; 30659 } 30660 if (this.deleted) { 30661 return this.serializeDeleted(); 30662 } 30663 const serialized = super.serialize(isForCopying); 30664 Object.assign(serialized, { 30665 color: AnnotationEditor._colorManager.convert(this._uiManager.getNonHCMColor(this.color)), 30666 opacity: this.opacity, 30667 thickness: this._drawingOptions.thickness, 30668 quadPoints: this._drawOutlines.serializeQuadPoints(this.pageTranslation, this.pageDimensions), 30669 outlines: this._drawOutlines.serialize(serialized.rect, this._drawRotation) 30670 }); 30671 this.addComment(serialized); 30672 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 30673 return null; 30674 } 30675 serialized.id = this.annotationElementId; 30676 return serialized; 30677 } 30678 #hasElementChanged(serialized) { 30679 const { 30680 color 30681 } = this._initialData; 30682 return this.hasEditedComment || serialized.color.some((c, i) => c !== color[i]); 30683 } 30684 renderAnnotationElement(annotation) { 30685 if (this.deleted) { 30686 annotation.hide(); 30687 return null; 30688 } 30689 annotation.updateEdited({ 30690 rect: this.getPDFRect(), 30691 popup: this.comment 30692 }); 30693 return null; 30694 } 30695} 30696 30697;// ./src/display/editor/drawers/inkdraw.js 30698 30699 30700 30701 30702 30703 30704 30705class InkDrawOutliner { 30706 #last = new Float64Array(6); 30707 #tip = new Float64Array(2); 30708 #line; 30709 #lines; 30710 #rotation; 30711 #thickness; 30712 #points; 30713 #lastSVGPath = ""; 30714 #lastIndex = 0; 30715 #outlines = new InkDrawOutline(); 30716 #parentWidth; 30717 #parentHeight; 30718 constructor(x, y, parentWidth, parentHeight, rotation, thickness) { 30719 this.#parentWidth = parentWidth; 30720 this.#parentHeight = parentHeight; 30721 this.#rotation = rotation; 30722 this.#thickness = thickness; 30723 [x, y] = this.#normalizePoint(x, y); 30724 const line = this.#line = [NaN, NaN, NaN, NaN, x, y]; 30725 this.#points = [x, y]; 30726 this.#lines = [{ 30727 line, 30728 points: this.#points 30729 }]; 30730 this.#last.set(line, 0); 30731 this.#tip.set([x, y], 0); 30732 } 30733 updateProperty(name, value) { 30734 if (name === "stroke-width") { 30735 this.#thickness = value; 30736 } 30737 } 30738 #normalizePoint(x, y) { 30739 return Outline._normalizePoint(x, y, this.#parentWidth, this.#parentHeight, this.#rotation); 30740 } 30741 isEmpty() { 30742 return !this.#lines?.length; 30743 } 30744 isCancellable() { 30745 return this.#points.length <= 10; 30746 } 30747 add(x, y) { 30748 if (this.#add(x, y)) { 30749 this.toSVGPath(); 30750 } 30751 return { 30752 path: { 30753 d: this.#toSVGPathWithTip() 30754 } 30755 }; 30756 } 30757 addPoints(points) { 30758 let needsPathUpdate = false; 30759 for (let i = 0, ii = points.length; i < ii; i += 2) { 30760 if (!this.#add(points[i], points[i + 1])) { 30761 continue; 30762 } 30763 needsPathUpdate = true; 30764 if (this.#points.length <= 6) { 30765 this.toSVGPath(); 30766 needsPathUpdate = false; 30767 } 30768 } 30769 if (needsPathUpdate) { 30770 this.toSVGPath(); 30771 } 30772 return { 30773 path: { 30774 d: this.#toSVGPathWithTip() 30775 } 30776 }; 30777 } 30778 #add(x, y) { 30779 [x, y] = this.#normalizePoint(x, y); 30780 this.#tip.set([x, y], 0); 30781 const [x1, y1, x2, y2] = this.#last.subarray(2, 6); 30782 const diffX = x - x2; 30783 const diffY = y - y2; 30784 const d = Math.hypot(this.#parentWidth * diffX, this.#parentHeight * diffY); 30785 if (d <= 2) { 30786 return false; 30787 } 30788 this.#points.push(x, y); 30789 if (isNaN(x1)) { 30790 this.#last.set([x2, y2, x, y], 2); 30791 this.#line.push(NaN, NaN, NaN, NaN, x, y); 30792 return true; 30793 } 30794 if (isNaN(this.#last[0])) { 30795 this.#line.splice(6, 6); 30796 } 30797 this.#last.set([x1, y1, x2, y2, x, y], 0); 30798 this.#line.push(...Outline.createBezierPoints(x1, y1, x2, y2, x, y)); 30799 return true; 30800 } 30801 end(x, y) { 30802 if (x !== undefined && this.#add(x, y)) { 30803 return { 30804 path: { 30805 d: this.toSVGPath() 30806 } 30807 }; 30808 } 30809 if (this.#points.length === 2) { 30810 return { 30811 path: { 30812 d: this.toSVGPath() 30813 } 30814 }; 30815 } 30816 return { 30817 path: { 30818 d: this.#lastSVGPath 30819 } 30820 }; 30821 } 30822 startNew(x, y, parentWidth, parentHeight, rotation) { 30823 this.#parentWidth = parentWidth; 30824 this.#parentHeight = parentHeight; 30825 this.#rotation = rotation; 30826 [x, y] = this.#normalizePoint(x, y); 30827 const line = this.#line = [NaN, NaN, NaN, NaN, x, y]; 30828 this.#points = [x, y]; 30829 this.#tip.set([x, y], 0); 30830 const last = this.#lines.at(-1); 30831 if (last) { 30832 last.line = new Float32Array(last.line); 30833 last.points = new Float32Array(last.points); 30834 } 30835 this.#lines.push({ 30836 line, 30837 points: this.#points 30838 }); 30839 this.#last.set(line, 0); 30840 this.#lastIndex = 0; 30841 this.toSVGPath(); 30842 return null; 30843 } 30844 getLastElement() { 30845 return this.#lines.at(-1); 30846 } 30847 setLastElement(element) { 30848 if (!this.#lines) { 30849 return this.#outlines.setLastElement(element); 30850 } 30851 this.#lines.push(element); 30852 this.#line = element.line; 30853 this.#points = element.points; 30854 this.#lastIndex = 0; 30855 return { 30856 path: { 30857 d: this.toSVGPath() 30858 } 30859 }; 30860 } 30861 removeLastElement() { 30862 if (!this.#lines) { 30863 return this.#outlines.removeLastElement(); 30864 } 30865 this.#lines.pop(); 30866 this.#lastSVGPath = ""; 30867 for (let i = 0, ii = this.#lines.length; i < ii; i++) { 30868 const { 30869 line, 30870 points 30871 } = this.#lines[i]; 30872 this.#line = line; 30873 this.#points = points; 30874 this.#lastIndex = 0; 30875 this.toSVGPath(); 30876 } 30877 return { 30878 path: { 30879 d: this.#lastSVGPath 30880 } 30881 }; 30882 } 30883 #toSVGPathWithTip() { 30884 const tipX = Outline.svgRound(this.#tip[0]); 30885 const tipY = Outline.svgRound(this.#tip[1]); 30886 if (this.#points.length === 2) { 30887 const firstX = Outline.svgRound(this.#line[4]); 30888 const firstY = Outline.svgRound(this.#line[5]); 30889 return `${this.#lastSVGPath} M ${firstX} ${firstY} L ${tipX} ${tipY}`; 30890 } 30891 return `${this.#lastSVGPath} L ${tipX} ${tipY}`; 30892 } 30893 toSVGPath() { 30894 const firstX = Outline.svgRound(this.#line[4]); 30895 const firstY = Outline.svgRound(this.#line[5]); 30896 if (this.#points.length === 2) { 30897 this.#lastSVGPath = `${this.#lastSVGPath} M ${firstX} ${firstY} Z`; 30898 return this.#lastSVGPath; 30899 } 30900 if (this.#points.length <= 6) { 30901 const i = this.#lastSVGPath.lastIndexOf("M"); 30902 this.#lastSVGPath = `${this.#lastSVGPath.slice(0, i)} M ${firstX} ${firstY}`; 30903 this.#lastIndex = 6; 30904 } 30905 if (this.#points.length === 4) { 30906 const secondX = Outline.svgRound(this.#line[10]); 30907 const secondY = Outline.svgRound(this.#line[11]); 30908 this.#lastSVGPath = `${this.#lastSVGPath} L ${secondX} ${secondY}`; 30909 this.#lastIndex = 12; 30910 return this.#lastSVGPath; 30911 } 30912 const buffer = []; 30913 if (this.#lastIndex === 0) { 30914 buffer.push(`M ${firstX} ${firstY}`); 30915 this.#lastIndex = 6; 30916 } 30917 for (let i = this.#lastIndex, ii = this.#line.length; i < ii; i += 6) { 30918 const [c1x, c1y, c2x, c2y, x, y] = this.#line.slice(i, i + 6).map(Outline.svgRound); 30919 buffer.push(`C${c1x} ${c1y} ${c2x} ${c2y} ${x} ${y}`); 30920 } 30921 this.#lastSVGPath += buffer.join(" "); 30922 this.#lastIndex = this.#line.length; 30923 return this.#lastSVGPath; 30924 } 30925 getOutlines(parentWidth, parentHeight, scale, innerMargin) { 30926 const last = this.#lines.at(-1); 30927 last.line = new Float32Array(last.line); 30928 last.points = new Float32Array(last.points); 30929 this.#outlines.build(this.#lines, parentWidth, parentHeight, scale, this.#rotation, this.#thickness, innerMargin); 30930 this.#last = null; 30931 this.#line = null; 30932 this.#lines = null; 30933 this.#lastSVGPath = null; 30934 return this.#outlines; 30935 } 30936 get defaultSVGProperties() { 30937 return { 30938 root: { 30939 viewBox: "0 0 10000 10000" 30940 }, 30941 rootClass: { 30942 draw: true 30943 }, 30944 bbox: [0, 0, 1, 1] 30945 }; 30946 } 30947} 30948class InkDrawOutline extends Outline { 30949 #bbox; 30950 #currentRotation = 0; 30951 #innerMargin; 30952 #lines; 30953 #parentWidth; 30954 #parentHeight; 30955 #parentScale; 30956 #rotation; 30957 #thickness; 30958 build(lines, parentWidth, parentHeight, parentScale, rotation, thickness, innerMargin) { 30959 this.#parentWidth = parentWidth; 30960 this.#parentHeight = parentHeight; 30961 this.#parentScale = parentScale; 30962 this.#rotation = rotation; 30963 this.#thickness = thickness; 30964 this.#innerMargin = innerMargin ?? 0; 30965 this.#lines = lines; 30966 this.#computeBbox(); 30967 } 30968 get thickness() { 30969 return this.#thickness; 30970 } 30971 setLastElement(element) { 30972 this.#lines.push(element); 30973 return { 30974 path: { 30975 d: this.toSVGPath() 30976 } 30977 }; 30978 } 30979 removeLastElement() { 30980 this.#lines.pop(); 30981 return { 30982 path: { 30983 d: this.toSVGPath() 30984 } 30985 }; 30986 } 30987 toSVGPath() { 30988 const buffer = []; 30989 for (const { 30990 line 30991 } of this.#lines) { 30992 buffer.push(`M${Outline.svgRound(line[4])} ${Outline.svgRound(line[5])}`); 30993 if (line.length === 6) { 30994 buffer.push("Z"); 30995 continue; 30996 } 30997 if (line.length === 12 && isNaN(line[6])) { 30998 buffer.push(`L${Outline.svgRound(line[10])} ${Outline.svgRound(line[11])}`); 30999 continue; 31000 } 31001 for (let i = 6, ii = line.length; i < ii; i += 6) { 31002 const [c1x, c1y, c2x, c2y, x, y] = line.subarray(i, i + 6).map(Outline.svgRound); 31003 buffer.push(`C${c1x} ${c1y} ${c2x} ${c2y} ${x} ${y}`); 31004 } 31005 } 31006 return buffer.join(""); 31007 } 31008 serialize([pageX, pageY, pageWidth, pageHeight], isForCopying) { 31009 const serializedLines = []; 31010 const serializedPoints = []; 31011 const [x, y, width, height] = this.#getBBoxWithNoMargin(); 31012 let tx, ty, sx, sy, x1, y1, x2, y2, rescaleFn; 31013 switch (this.#rotation) { 31014 case 0: 31015 rescaleFn = Outline._rescale; 31016 tx = pageX; 31017 ty = pageY + pageHeight; 31018 sx = pageWidth; 31019 sy = -pageHeight; 31020 x1 = pageX + x * pageWidth; 31021 y1 = pageY + (1 - y - height) * pageHeight; 31022 x2 = pageX + (x + width) * pageWidth; 31023 y2 = pageY + (1 - y) * pageHeight; 31024 break; 31025 case 90: 31026 rescaleFn = Outline._rescaleAndSwap; 31027 tx = pageX; 31028 ty = pageY; 31029 sx = pageWidth; 31030 sy = pageHeight; 31031 x1 = pageX + y * pageWidth; 31032 y1 = pageY + x * pageHeight; 31033 x2 = pageX + (y + height) * pageWidth; 31034 y2 = pageY + (x + width) * pageHeight; 31035 break; 31036 case 180: 31037 rescaleFn = Outline._rescale; 31038 tx = pageX + pageWidth; 31039 ty = pageY; 31040 sx = -pageWidth; 31041 sy = pageHeight; 31042 x1 = pageX + (1 - x - width) * pageWidth; 31043 y1 = pageY + y * pageHeight; 31044 x2 = pageX + (1 - x) * pageWidth; 31045 y2 = pageY + (y + height) * pageHeight; 31046 break; 31047 case 270: 31048 rescaleFn = Outline._rescaleAndSwap; 31049 tx = pageX + pageWidth; 31050 ty = pageY + pageHeight; 31051 sx = -pageWidth; 31052 sy = -pageHeight; 31053 x1 = pageX + (1 - y - height) * pageWidth; 31054 y1 = pageY + (1 - x - width) * pageHeight; 31055 x2 = pageX + (1 - y) * pageWidth; 31056 y2 = pageY + (1 - x) * pageHeight; 31057 break; 31058 } 31059 for (const { 31060 line, 31061 points 31062 } of this.#lines) { 31063 serializedLines.push(rescaleFn(line, tx, ty, sx, sy, isForCopying ? new Array(line.length) : null)); 31064 serializedPoints.push(rescaleFn(points, tx, ty, sx, sy, isForCopying ? new Array(points.length) : null)); 31065 } 31066 return { 31067 lines: serializedLines, 31068 points: serializedPoints, 31069 rect: [x1, y1, x2, y2] 31070 }; 31071 } 31072 static deserialize(pageX, pageY, pageWidth, pageHeight, innerMargin, { 31073 paths: { 31074 lines, 31075 points 31076 }, 31077 rotation, 31078 thickness 31079 }) { 31080 const newLines = []; 31081 let tx, ty, sx, sy, rescaleFn; 31082 switch (rotation) { 31083 case 0: 31084 rescaleFn = Outline._rescale; 31085 tx = -pageX / pageWidth; 31086 ty = pageY / pageHeight + 1; 31087 sx = 1 / pageWidth; 31088 sy = -1 / pageHeight; 31089 break; 31090 case 90: 31091 rescaleFn = Outline._rescaleAndSwap; 31092 tx = -pageY / pageHeight; 31093 ty = -pageX / pageWidth; 31094 sx = 1 / pageHeight; 31095 sy = 1 / pageWidth; 31096 break; 31097 case 180: 31098 rescaleFn = Outline._rescale; 31099 tx = pageX / pageWidth + 1; 31100 ty = -pageY / pageHeight; 31101 sx = -1 / pageWidth; 31102 sy = 1 / pageHeight; 31103 break; 31104 case 270: 31105 rescaleFn = Outline._rescaleAndSwap; 31106 tx = pageY / pageHeight + 1; 31107 ty = pageX / pageWidth + 1; 31108 sx = -1 / pageHeight; 31109 sy = -1 / pageWidth; 31110 break; 31111 } 31112 if (!lines) { 31113 lines = []; 31114 for (const point of points) { 31115 const len = point.length; 31116 if (len === 2) { 31117 lines.push(new Float32Array([NaN, NaN, NaN, NaN, point[0], point[1]])); 31118 continue; 31119 } 31120 if (len === 4) { 31121 lines.push(new Float32Array([NaN, NaN, NaN, NaN, point[0], point[1], NaN, NaN, NaN, NaN, point[2], point[3]])); 31122 continue; 31123 } 31124 const line = new Float32Array(3 * (len - 2)); 31125 lines.push(line); 31126 let [x1, y1, x2, y2] = point.subarray(0, 4); 31127 line.set([NaN, NaN, NaN, NaN, x1, y1], 0); 31128 for (let i = 4; i < len; i += 2) { 31129 const x = point[i]; 31130 const y = point[i + 1]; 31131 line.set(Outline.createBezierPoints(x1, y1, x2, y2, x, y), (i - 2) * 3); 31132 [x1, y1, x2, y2] = [x2, y2, x, y]; 31133 } 31134 } 31135 } 31136 for (let i = 0, ii = lines.length; i < ii; i++) { 31137 newLines.push({ 31138 line: rescaleFn(lines[i].map(x => x ?? NaN), tx, ty, sx, sy), 31139 points: rescaleFn(points[i].map(x => x ?? NaN), tx, ty, sx, sy) 31140 }); 31141 } 31142 const outlines = new this.prototype.constructor(); 31143 outlines.build(newLines, pageWidth, pageHeight, 1, rotation, thickness, innerMargin); 31144 return outlines; 31145 } 31146 #getMarginComponents(thickness = this.#thickness) { 31147 const margin = this.#innerMargin + thickness / 2 * this.#parentScale; 31148 return this.#rotation % 180 === 0 ? [margin / this.#parentWidth, margin / this.#parentHeight] : [margin / this.#parentHeight, margin / this.#parentWidth]; 31149 } 31150 #getBBoxWithNoMargin() { 31151 const [x, y, width, height] = this.#bbox; 31152 const [marginX, marginY] = this.#getMarginComponents(0); 31153 return [x + marginX, y + marginY, width - 2 * marginX, height - 2 * marginY]; 31154 } 31155 #computeBbox() { 31156 const bbox = this.#bbox = F32_BBOX_INIT.slice(); 31157 for (const { 31158 line 31159 } of this.#lines) { 31160 if (line.length <= 12) { 31161 for (let i = 4, ii = line.length; i < ii; i += 6) { 31162 Util.pointBoundingBox(line[i], line[i + 1], bbox); 31163 } 31164 continue; 31165 } 31166 let lastX = line[4], 31167 lastY = line[5]; 31168 for (let i = 6, ii = line.length; i < ii; i += 6) { 31169 const [c1x, c1y, c2x, c2y, x, y] = line.subarray(i, i + 6); 31170 Util.bezierBoundingBox(lastX, lastY, c1x, c1y, c2x, c2y, x, y, bbox); 31171 lastX = x; 31172 lastY = y; 31173 } 31174 } 31175 const [marginX, marginY] = this.#getMarginComponents(); 31176 bbox[0] = MathClamp(bbox[0] - marginX, 0, 1); 31177 bbox[1] = MathClamp(bbox[1] - marginY, 0, 1); 31178 bbox[2] = MathClamp(bbox[2] + marginX, 0, 1); 31179 bbox[3] = MathClamp(bbox[3] + marginY, 0, 1); 31180 bbox[2] -= bbox[0]; 31181 bbox[3] -= bbox[1]; 31182 } 31183 get box() { 31184 return this.#bbox; 31185 } 31186 updateProperty(name, value) { 31187 return name === "stroke-width" ? this.#updateThickness(value) : null; 31188 } 31189 #updateThickness(thickness) { 31190 const [oldMarginX, oldMarginY] = this.#getMarginComponents(); 31191 this.#thickness = thickness; 31192 const [newMarginX, newMarginY] = this.#getMarginComponents(); 31193 const [diffMarginX, diffMarginY] = [newMarginX - oldMarginX, newMarginY - oldMarginY]; 31194 const bbox = this.#bbox; 31195 bbox[0] -= diffMarginX; 31196 bbox[1] -= diffMarginY; 31197 bbox[2] += 2 * diffMarginX; 31198 bbox[3] += 2 * diffMarginY; 31199 return bbox; 31200 } 31201 updateParentDimensions([width, height], scale) { 31202 const [oldMarginX, oldMarginY] = this.#getMarginComponents(); 31203 this.#parentWidth = width; 31204 this.#parentHeight = height; 31205 this.#parentScale = scale; 31206 const [newMarginX, newMarginY] = this.#getMarginComponents(); 31207 const diffMarginX = newMarginX - oldMarginX; 31208 const diffMarginY = newMarginY - oldMarginY; 31209 const bbox = this.#bbox; 31210 bbox[0] -= diffMarginX; 31211 bbox[1] -= diffMarginY; 31212 bbox[2] += 2 * diffMarginX; 31213 bbox[3] += 2 * diffMarginY; 31214 return bbox; 31215 } 31216 updateRotation(rotation) { 31217 this.#currentRotation = rotation; 31218 return { 31219 path: { 31220 transform: this.rotationTransform 31221 } 31222 }; 31223 } 31224 get viewBox() { 31225 return this.#bbox.map(Outline.svgRound).join(" "); 31226 } 31227 get defaultProperties() { 31228 const [x, y] = this.#bbox; 31229 return { 31230 root: { 31231 viewBox: this.viewBox 31232 }, 31233 path: { 31234 "transform-origin": `${Outline.svgRound(x)} ${Outline.svgRound(y)}` 31235 } 31236 }; 31237 } 31238 get rotationTransform() { 31239 const [,, width, height] = this.#bbox; 31240 let a = 0, 31241 b = 0, 31242 c = 0, 31243 d = 0, 31244 e = 0, 31245 f = 0; 31246 switch (this.#currentRotation) { 31247 case 90: 31248 b = height / width; 31249 c = -width / height; 31250 e = width; 31251 break; 31252 case 180: 31253 a = -1; 31254 d = -1; 31255 e = width; 31256 f = height; 31257 break; 31258 case 270: 31259 b = -height / width; 31260 c = width / height; 31261 f = height; 31262 break; 31263 default: 31264 return ""; 31265 } 31266 return `matrix(${a} ${b} ${c} ${d} ${Outline.svgRound(e)} ${Outline.svgRound(f)})`; 31267 } 31268 getPathResizingSVGProperties([newX, newY, newWidth, newHeight]) { 31269 const [marginX, marginY] = this.#getMarginComponents(); 31270 const [x, y, width, height] = this.#bbox; 31271 if (Math.abs(width - marginX) <= Outline.PRECISION || Math.abs(height - marginY) <= Outline.PRECISION) { 31272 const tx = newX + newWidth / 2 - (x + width / 2); 31273 const ty = newY + newHeight / 2 - (y + height / 2); 31274 return { 31275 path: { 31276 "transform-origin": `${Outline.svgRound(newX)} ${Outline.svgRound(newY)}`, 31277 transform: `${this.rotationTransform} translate(${tx} ${ty})` 31278 } 31279 }; 31280 } 31281 const s1x = (newWidth - 2 * marginX) / (width - 2 * marginX); 31282 const s1y = (newHeight - 2 * marginY) / (height - 2 * marginY); 31283 const s2x = width / newWidth; 31284 const s2y = height / newHeight; 31285 return { 31286 path: { 31287 "transform-origin": `${Outline.svgRound(x)} ${Outline.svgRound(y)}`, 31288 transform: `${this.rotationTransform} scale(${s2x} ${s2y}) ` + `translate(${Outline.svgRound(marginX)} ${Outline.svgRound(marginY)}) scale(${s1x} ${s1y}) ` + `translate(${Outline.svgRound(-marginX)} ${Outline.svgRound(-marginY)})` 31289 } 31290 }; 31291 } 31292 getPathResizedSVGProperties([newX, newY, newWidth, newHeight]) { 31293 const [marginX, marginY] = this.#getMarginComponents(); 31294 const bbox = this.#bbox; 31295 const [x, y, width, height] = bbox; 31296 bbox[0] = newX; 31297 bbox[1] = newY; 31298 bbox[2] = newWidth; 31299 bbox[3] = newHeight; 31300 if (Math.abs(width - marginX) <= Outline.PRECISION || Math.abs(height - marginY) <= Outline.PRECISION) { 31301 const tx = newX + newWidth / 2 - (x + width / 2); 31302 const ty = newY + newHeight / 2 - (y + height / 2); 31303 for (const { 31304 line, 31305 points 31306 } of this.#lines) { 31307 Outline._translate(line, tx, ty, line); 31308 Outline._translate(points, tx, ty, points); 31309 } 31310 return { 31311 root: {
vendor: 2,598 bytes, lines 31312-31402
31312 viewBox: this.viewBox 31313 }, 31314 path: { 31315 "transform-origin": `${Outline.svgRound(newX)} ${Outline.svgRound(newY)}`, 31316 transform: this.rotationTransform || null, 31317 d: this.toSVGPath() 31318 } 31319 }; 31320 } 31321 const s1x = (newWidth - 2 * marginX) / (width - 2 * marginX); 31322 const s1y = (newHeight - 2 * marginY) / (height - 2 * marginY); 31323 const tx = -s1x * (x + marginX) + newX + marginX; 31324 const ty = -s1y * (y + marginY) + newY + marginY; 31325 if (s1x !== 1 || s1y !== 1 || tx !== 0 || ty !== 0) { 31326 for (const { 31327 line, 31328 points 31329 } of this.#lines) { 31330 Outline._rescale(line, tx, ty, s1x, s1y, line); 31331 Outline._rescale(points, tx, ty, s1x, s1y, points); 31332 } 31333 } 31334 return { 31335 root: { 31336 viewBox: this.viewBox 31337 }, 31338 path: { 31339 "transform-origin": `${Outline.svgRound(newX)} ${Outline.svgRound(newY)}`, 31340 transform: this.rotationTransform || null, 31341 d: this.toSVGPath() 31342 } 31343 }; 31344 } 31345 getPathTranslatedSVGProperties([newX, newY], parentDimensions) { 31346 const [newParentWidth, newParentHeight] = parentDimensions; 31347 const bbox = this.#bbox; 31348 const tx = newX - bbox[0]; 31349 const ty = newY - bbox[1]; 31350 if (this.#parentWidth === newParentWidth && this.#parentHeight === newParentHeight) { 31351 for (const { 31352 line, 31353 points 31354 } of this.#lines) { 31355 Outline._translate(line, tx, ty, line); 31356 Outline._translate(points, tx, ty, points); 31357 } 31358 } else { 31359 const sx = this.#parentWidth / newParentWidth; 31360 const sy = this.#parentHeight / newParentHeight; 31361 this.#parentWidth = newParentWidth; 31362 this.#parentHeight = newParentHeight; 31363 for (const { 31364 line, 31365 points 31366 } of this.#lines) { 31367 Outline._rescale(line, tx, ty, sx, sy, line); 31368 Outline._rescale(points, tx, ty, sx, sy, points); 31369 } 31370 bbox[2] *= sx; 31371 bbox[3] *= sy; 31372 } 31373 bbox[0] = newX; 31374 bbox[1] = newY; 31375 return { 31376 root: { 31377 viewBox: this.viewBox 31378 }, 31379 path: { 31380 d: this.toSVGPath(), 31381 "transform-origin": `${Outline.svgRound(newX)} ${Outline.svgRound(newY)}` 31382 } 31383 }; 31384 } 31385 get defaultSVGProperties() { 31386 const bbox = this.#bbox; 31387 return { 31388 root: { 31389 viewBox: this.viewBox 31390 }, 31391 rootClass: { 31392 draw: true 31393 }, 31394 path: { 31395 d: this.toSVGPath(), 31396 "transform-origin": `${Outline.svgRound(bbox[0])} ${Outline.svgRound(bbox[1])}`, 31397 transform: this.rotationTransform || null 31398 }, 31399 bbox 31400 }; 31401 } 31402}
vendor: 7,465 bytes, lines 31403-31694
31403 31404;// ./src/display/editor/ink.js 31405 31406 31407 31408 31409 31410 31411 31412 31413 31414 31415class InkDrawingOptions extends DrawingOptions { 31416 constructor(viewerParameters) { 31417 super(); 31418 this._viewParameters = viewerParameters; 31419 super.updateProperties({ 31420 fill: "none", 31421 stroke: AnnotationEditor._defaultLineColor, 31422 "stroke-opacity": 1, 31423 "stroke-width": 1, 31424 "stroke-linecap": "round", 31425 "stroke-linejoin": "round", 31426 "stroke-miterlimit": 10 31427 }); 31428 } 31429 updateSVGProperty(name, value) { 31430 if (name === "stroke-width") { 31431 value ??= this["stroke-width"]; 31432 value *= this._viewParameters.realScale; 31433 } 31434 super.updateSVGProperty(name, value); 31435 } 31436 clone() { 31437 const clone = new InkDrawingOptions(this._viewParameters); 31438 clone.updateAll(this); 31439 return clone; 31440 } 31441} 31442class InkEditor extends DrawingEditor { 31443 static _type = "ink"; 31444 static _editorType = AnnotationEditorType.INK; 31445 static _defaultDrawingOptions = null; 31446 constructor(params) { 31447 super({ 31448 ...params, 31449 name: "inkEditor" 31450 }); 31451 this._willKeepAspectRatio = true; 31452 this.defaultL10nId = "pdfjs-editor-ink-editor"; 31453 } 31454 static initialize(l10n, uiManager) { 31455 AnnotationEditor.initialize(l10n, uiManager); 31456 this._defaultDrawingOptions = new InkDrawingOptions(uiManager.viewParameters); 31457 } 31458 static getDefaultDrawingOptions(options) { 31459 const clone = this._defaultDrawingOptions.clone(); 31460 clone.updateProperties(options); 31461 return clone; 31462 } 31463 static get supportMultipleDrawings() { 31464 return true; 31465 } 31466 static get typesMap() { 31467 return shadow(this, "typesMap", new Map([[AnnotationEditorParamsType.INK_THICKNESS, "stroke-width"], [AnnotationEditorParamsType.INK_COLOR, "stroke"], [AnnotationEditorParamsType.INK_OPACITY, "stroke-opacity"]])); 31468 } 31469 static createDrawerInstance({ 31470 x, 31471 y, 31472 box: [,, width, height], 31473 rotation 31474 }) { 31475 return new InkDrawOutliner(x, y, width, height, rotation, this._defaultDrawingOptions["stroke-width"]); 31476 } 31477 static deserializeDraw(pageX, pageY, pageWidth, pageHeight, innerMargin, data) { 31478 return InkDrawOutline.deserialize(pageX, pageY, pageWidth, pageHeight, innerMargin, data); 31479 } 31480 static async deserialize(data, parent, uiManager) { 31481 let initialData = null; 31482 if (data instanceof InkAnnotationElement) { 31483 const { 31484 data: { 31485 inkLists, 31486 rect, 31487 rotation, 31488 id, 31489 color, 31490 opacity, 31491 borderStyle: { 31492 rawWidth: thickness 31493 }, 31494 popupRef, 31495 richText, 31496 contentsObj, 31497 creationDate, 31498 modificationDate 31499 }, 31500 parent: { 31501 page: { 31502 pageNumber 31503 } 31504 } 31505 } = data; 31506 initialData = data = { 31507 annotationType: AnnotationEditorType.INK, 31508 color: Array.from(color), 31509 thickness, 31510 opacity, 31511 paths: { 31512 points: inkLists 31513 }, 31514 boxes: null, 31515 pageIndex: pageNumber - 1, 31516 rect: rect.slice(0), 31517 rotation, 31518 annotationElementId: id, 31519 id, 31520 deleted: false, 31521 popupRef, 31522 richText, 31523 comment: contentsObj?.str || null, 31524 creationDate, 31525 modificationDate 31526 }; 31527 } 31528 const editor = await super.deserialize(data, parent, uiManager); 31529 editor._initialData = initialData; 31530 if (data.comment) { 31531 editor.setCommentData(data); 31532 } 31533 return editor; 31534 } 31535 get toolbarButtons() { 31536 this._colorPicker ||= new BasicColorPicker(this); 31537 return [["colorPicker", this._colorPicker]]; 31538 } 31539 get colorType() { 31540 return AnnotationEditorParamsType.INK_COLOR; 31541 } 31542 get colorAndOpacityType() { 31543 return AnnotationEditorParamsType.INK_COLOR_AND_OPACITY; 31544 } 31545 get opacityType() { 31546 return AnnotationEditorParamsType.INK_OPACITY; 31547 } 31548 updateParams(type, value) { 31549 if (type === AnnotationEditorParamsType.INK_COLOR_AND_OPACITY) { 31550 this._updateColorAndOpacity(value.color, value.opacity); 31551 return; 31552 } 31553 super.updateParams(type, value); 31554 } 31555 static updateDefaultParams(type, value) { 31556 if (type === AnnotationEditorParamsType.INK_COLOR_AND_OPACITY) { 31557 super.updateDefaultParams(AnnotationEditorParamsType.INK_COLOR, value.color); 31558 super.updateDefaultParams(AnnotationEditorParamsType.INK_OPACITY, value.opacity); 31559 return; 31560 } 31561 super.updateDefaultParams(type, value); 31562 } 31563 get color() { 31564 return this._drawingOptions.stroke; 31565 } 31566 get opacity() { 31567 return this._drawingOptions["stroke-opacity"]; 31568 } 31569 onScaleChanging() { 31570 if (!this.parent) { 31571 return; 31572 } 31573 super.onScaleChanging(); 31574 const { 31575 _drawId, 31576 _drawingOptions, 31577 parent 31578 } = this; 31579 _drawingOptions.updateSVGProperty("stroke-width"); 31580 parent.drawLayer.updateProperties(_drawId, _drawingOptions.toSVGProperties()); 31581 } 31582 static onScaleChangingWhenDrawing() { 31583 const parent = this._currentParent; 31584 if (!parent) { 31585 return; 31586 } 31587 super.onScaleChangingWhenDrawing(); 31588 this._defaultDrawingOptions.updateSVGProperty("stroke-width"); 31589 parent.drawLayer.updateProperties(this._currentDrawId, this._defaultDrawingOptions.toSVGProperties()); 31590 } 31591 createDrawingOptions({ 31592 color, 31593 thickness, 31594 opacity 31595 }) { 31596 this._drawingOptions = InkEditor.getDefaultDrawingOptions({ 31597 stroke: Util.makeHexColor(...color), 31598 "stroke-width": thickness, 31599 "stroke-opacity": opacity 31600 }); 31601 } 31602 serialize(isForCopying = false) { 31603 if (this.isEmpty()) { 31604 return null; 31605 } 31606 if (this.deleted) { 31607 return this.serializeDeleted(); 31608 } 31609 const { 31610 lines, 31611 points 31612 } = this.serializeDraw(isForCopying); 31613 const { 31614 _drawingOptions: { 31615 stroke, 31616 "stroke-opacity": opacity, 31617 "stroke-width": thickness 31618 } 31619 } = this; 31620 const serialized = Object.assign(super.serialize(isForCopying), { 31621 color: AnnotationEditor._colorManager.convert(stroke), 31622 opacity, 31623 thickness, 31624 paths: { 31625 lines, 31626 points 31627 } 31628 }); 31629 this.addComment(serialized); 31630 if (isForCopying) { 31631 serialized.isCopy = true; 31632 return serialized; 31633 } 31634 if (this.annotationElementId && !this.#hasElementChanged(serialized)) { 31635 return null; 31636 } 31637 serialized.id = this.annotationElementId; 31638 return serialized; 31639 } 31640 #hasElementChanged(serialized) { 31641 const { 31642 color, 31643 thickness, 31644 opacity, 31645 pageIndex 31646 } = this._initialData; 31647 return this.hasEditedComment || this._hasBeenMoved || this._hasBeenResized || serialized.color.some((c, i) => c !== color[i]) || serialized.thickness !== thickness || serialized.opacity !== opacity || serialized.pageIndex !== pageIndex; 31648 } 31649 renderAnnotationElement(annotation) { 31650 if (this.deleted) { 31651 annotation.hide(); 31652 return null; 31653 } 31654 const { 31655 points, 31656 rect 31657 } = this.serializeDraw(false); 31658 annotation.updateEdited({ 31659 rect, 31660 thickness: this._drawingOptions["stroke-width"], 31661 points, 31662 popup: this.comment 31663 }); 31664 return null; 31665 } 31666} 31667 31668;// ./src/display/editor/drawers/contour.js 31669 31670class ContourDrawOutline extends InkDrawOutline { 31671 toSVGPath() { 31672 let path = super.toSVGPath(); 31673 if (!path.endsWith("Z")) { 31674 path += "Z"; 31675 } 31676 return path; 31677 } 31678} 31679 31680// EXTERNAL MODULE: ./node_modules/core-js/modules/es.uint8-array.from-base64.js 31681var es_uint8_array_from_base64 = __webpack_require__(5213); 31682;// ./src/display/editor/drawers/signaturedraw.js 31683 31684 31685 31686 31687 31688 31689 31690 31691 31692 31693 31694
vendor: 4,991 bytes, lines 31695-31867
31695 31696const BASE_HEADER_LENGTH = 8; 31697const POINTS_PROPERTIES_NUMBER = 3; 31698class SignatureExtractor { 31699 static #PARAMETERS = { 31700 maxDim: 512, 31701 sigmaSFactor: 0.02, 31702 sigmaR: 25, 31703 kernelSize: 16 31704 }; 31705 static #neighborIndexToId(i0, j0, i, j) { 31706 i -= i0; 31707 j -= j0; 31708 if (i === 0) { 31709 return j > 0 ? 0 : 4; 31710 } 31711 if (i === 1) { 31712 return j + 6; 31713 } 31714 return 2 - j; 31715 } 31716 static #neighborIdToIndex = new Int32Array([0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1, 1, 0, 1, 1]); 31717 static #clockwiseNonZero(buf, width, i0, j0, i, j, offset) { 31718 const id = this.#neighborIndexToId(i0, j0, i, j); 31719 for (let k = 0; k < 8; k++) { 31720 const kk = (-k + id - offset + 16) % 8; 31721 const shiftI = this.#neighborIdToIndex[2 * kk]; 31722 const shiftJ = this.#neighborIdToIndex[2 * kk + 1]; 31723 if (buf[(i0 + shiftI) * width + (j0 + shiftJ)] !== 0) { 31724 return kk; 31725 } 31726 } 31727 return -1; 31728 } 31729 static #counterClockwiseNonZero(buf, width, i0, j0, i, j, offset) { 31730 const id = this.#neighborIndexToId(i0, j0, i, j); 31731 for (let k = 0; k < 8; k++) { 31732 const kk = (k + id + offset + 16) % 8; 31733 const shiftI = this.#neighborIdToIndex[2 * kk]; 31734 const shiftJ = this.#neighborIdToIndex[2 * kk + 1]; 31735 if (buf[(i0 + shiftI) * width + (j0 + shiftJ)] !== 0) { 31736 return kk; 31737 } 31738 } 31739 return -1; 31740 } 31741 static #findContours(buf, width, height, threshold) { 31742 const N = buf.length; 31743 const types = new Int32Array(N); 31744 for (let i = 0; i < N; i++) { 31745 types[i] = buf[i] <= threshold ? 1 : 0; 31746 } 31747 for (let i = 1; i < height - 1; i++) { 31748 types[i * width] = types[i * width + width - 1] = 0; 31749 } 31750 for (let i = 0; i < width; i++) { 31751 types[i] = types[width * height - 1 - i] = 0; 31752 } 31753 let nbd = 1; 31754 let lnbd; 31755 const contours = []; 31756 for (let i = 1; i < height - 1; i++) { 31757 lnbd = 1; 31758 for (let j = 1; j < width - 1; j++) { 31759 const ij = i * width + j; 31760 const pix = types[ij]; 31761 if (pix === 0) { 31762 continue; 31763 } 31764 let i2 = i; 31765 let j2 = j; 31766 if (pix === 1 && types[ij - 1] === 0) { 31767 nbd += 1; 31768 j2 -= 1; 31769 } else if (pix >= 1 && types[ij + 1] === 0) { 31770 nbd += 1; 31771 j2 += 1; 31772 if (pix > 1) { 31773 lnbd = pix; 31774 } 31775 } else { 31776 if (pix !== 1) { 31777 lnbd = Math.abs(pix); 31778 } 31779 continue; 31780 } 31781 const points = [j, i]; 31782 const isHole = j2 === j + 1; 31783 const contour = { 31784 isHole, 31785 points, 31786 id: nbd, 31787 parent: 0 31788 }; 31789 contours.push(contour); 31790 let contour0; 31791 for (const c of contours) { 31792 if (c.id === lnbd) { 31793 contour0 = c; 31794 break; 31795 } 31796 } 31797 if (!contour0) { 31798 contour.parent = isHole ? lnbd : 0; 31799 } else if (contour0.isHole) { 31800 contour.parent = isHole ? contour0.parent : lnbd; 31801 } else { 31802 contour.parent = isHole ? lnbd : contour0.parent; 31803 } 31804 const k = this.#clockwiseNonZero(types, width, i, j, i2, j2, 0); 31805 if (k === -1) { 31806 types[ij] = -nbd; 31807 if (types[ij] !== 1) { 31808 lnbd = Math.abs(types[ij]); 31809 } 31810 continue; 31811 } 31812 let shiftI = this.#neighborIdToIndex[2 * k]; 31813 let shiftJ = this.#neighborIdToIndex[2 * k + 1]; 31814 const i1 = i + shiftI; 31815 const j1 = j + shiftJ; 31816 i2 = i1; 31817 j2 = j1; 31818 let i3 = i; 31819 let j3 = j; 31820 while (true) { 31821 const kk = this.#counterClockwiseNonZero(types, width, i3, j3, i2, j2, 1); 31822 shiftI = this.#neighborIdToIndex[2 * kk]; 31823 shiftJ = this.#neighborIdToIndex[2 * kk + 1]; 31824 const i4 = i3 + shiftI; 31825 const j4 = j3 + shiftJ; 31826 points.push(j4, i4); 31827 const ij3 = i3 * width + j3; 31828 if (types[ij3 + 1] === 0) { 31829 types[ij3] = -nbd; 31830 } else if (types[ij3] === 1) { 31831 types[ij3] = nbd; 31832 } 31833 if (i4 === i && j4 === j && i3 === i1 && j3 === j1) { 31834 if (types[ij] !== 1) { 31835 lnbd = Math.abs(types[ij]); 31836 } 31837 break; 31838 } else { 31839 i2 = i3; 31840 j2 = j3; 31841 i3 = i4; 31842 j3 = j4; 31843 } 31844 } 31845 } 31846 } 31847 return contours; 31848 } 31849 static #douglasPeuckerHelper(points, start, end, output) { 31850 if (end - start <= 4) { 31851 for (let i = start; i < end - 2; i += 2) { 31852 output.push(points[i], points[i + 1]); 31853 } 31854 return; 31855 } 31856 const ax = points[start]; 31857 const ay = points[start + 1]; 31858 const abx = points[end - 4] - ax; 31859 const aby = points[end - 3] - ay; 31860 const dist = Math.hypot(abx, aby); 31861 const nabx = abx / dist; 31862 const naby = aby / dist; 31863 const aa = nabx * ay - naby * ax; 31864 const m = aby / abx; 31865 const invS = 1 / dist; 31866 const phi = Math.atan(m); 31867 const cosPhi = Math.cos(phi);
vendor: 23,831 bytes, lines 31868-32681
31868 const sinPhi = Math.sin(phi); 31869 const tmax = invS * (Math.abs(cosPhi) + Math.abs(sinPhi)); 31870 const poly = invS * (1 - tmax + tmax ** 2); 31871 const partialPhi = Math.max(Math.atan(Math.abs(sinPhi + cosPhi) * poly), Math.atan(Math.abs(sinPhi - cosPhi) * poly)); 31872 let dmax = 0; 31873 let index = start; 31874 for (let i = start + 2; i < end - 2; i += 2) { 31875 const d = Math.abs(aa - nabx * points[i + 1] + naby * points[i]); 31876 if (d > dmax) { 31877 index = i; 31878 dmax = d; 31879 } 31880 } 31881 if (dmax > (dist * partialPhi) ** 2) { 31882 this.#douglasPeuckerHelper(points, start, index + 2, output); 31883 this.#douglasPeuckerHelper(points, index, end, output); 31884 } else { 31885 output.push(ax, ay); 31886 } 31887 } 31888 static #douglasPeucker(points) { 31889 const output = []; 31890 const len = points.length; 31891 this.#douglasPeuckerHelper(points, 0, len, output); 31892 output.push(points[len - 2], points[len - 1]); 31893 return output.length <= 4 ? null : output; 31894 } 31895 static #bilateralFilter(buf, width, height, sigmaS, sigmaR, kernelSize) { 31896 const kernel = new Float32Array(kernelSize ** 2); 31897 const sigmaS2 = -2 * sigmaS ** 2; 31898 const halfSize = kernelSize >> 1; 31899 for (let i = 0; i < kernelSize; i++) { 31900 const x = (i - halfSize) ** 2; 31901 for (let j = 0; j < kernelSize; j++) { 31902 kernel[i * kernelSize + j] = Math.exp((x + (j - halfSize) ** 2) / sigmaS2); 31903 } 31904 } 31905 const rangeValues = new Float32Array(256); 31906 const sigmaR2 = -2 * sigmaR ** 2; 31907 for (let i = 0; i < 256; i++) { 31908 rangeValues[i] = Math.exp(i ** 2 / sigmaR2); 31909 } 31910 const N = buf.length; 31911 const out = new Uint8Array(N); 31912 const histogram = new Uint32Array(256); 31913 for (let i = 0; i < height; i++) { 31914 for (let j = 0; j < width; j++) { 31915 const ij = i * width + j; 31916 const center = buf[ij]; 31917 let sum = 0; 31918 let norm = 0; 31919 for (let k = 0; k < kernelSize; k++) { 31920 const y = i + k - halfSize; 31921 if (y < 0 || y >= height) { 31922 continue; 31923 } 31924 for (let l = 0; l < kernelSize; l++) { 31925 const x = j + l - halfSize; 31926 if (x < 0 || x >= width) { 31927 continue; 31928 } 31929 const neighbour = buf[y * width + x]; 31930 const w = kernel[k * kernelSize + l] * rangeValues[Math.abs(neighbour - center)]; 31931 sum += neighbour * w; 31932 norm += w; 31933 } 31934 } 31935 const pix = out[ij] = Math.round(sum / norm); 31936 histogram[pix]++; 31937 } 31938 } 31939 return [out, histogram]; 31940 } 31941 static #getHistogram(buf) { 31942 const histogram = new Uint32Array(256); 31943 for (const g of buf) { 31944 histogram[g]++; 31945 } 31946 return histogram; 31947 } 31948 static #toUint8(buf) { 31949 const N = buf.length; 31950 const out = new Uint8ClampedArray(N >> 2); 31951 let max = -Infinity; 31952 let min = Infinity; 31953 for (let i = 0, ii = out.length; i < ii; i++) { 31954 const pix = out[i] = buf[i << 2]; 31955 max = Math.max(max, pix); 31956 min = Math.min(min, pix); 31957 } 31958 const ratio = 255 / (max - min); 31959 for (let i = 0, ii = out.length; i < ii; i++) { 31960 out[i] = (out[i] - min) * ratio; 31961 } 31962 return out; 31963 } 31964 static #guessThreshold(histogram) { 31965 let i; 31966 let M = -Infinity; 31967 let L = -Infinity; 31968 const min = histogram.findIndex(v => v !== 0); 31969 let pos = min; 31970 let spos = min; 31971 for (i = min; i < 256; i++) { 31972 const v = histogram[i]; 31973 if (v > M) { 31974 if (i - pos > L) { 31975 L = i - pos; 31976 spos = i - 1; 31977 } 31978 M = v; 31979 pos = i; 31980 } 31981 } 31982 for (i = spos - 1; i >= 0; i--) { 31983 if (histogram[i] > histogram[i + 1]) { 31984 break; 31985 } 31986 } 31987 return i; 31988 } 31989 static #getGrayPixels(bitmap) { 31990 const originalBitmap = bitmap; 31991 const { 31992 width, 31993 height 31994 } = bitmap; 31995 const { 31996 maxDim 31997 } = this.#PARAMETERS; 31998 let newWidth = width; 31999 let newHeight = height; 32000 if (width > maxDim || height > maxDim) { 32001 let prevWidth = width; 32002 let prevHeight = height; 32003 let steps = Math.log2(Math.max(width, height) / maxDim); 32004 const isteps = Math.floor(steps); 32005 steps = steps === isteps ? isteps - 1 : isteps; 32006 for (let i = 0; i < steps; i++) { 32007 newWidth = Math.ceil(prevWidth / 2); 32008 newHeight = Math.ceil(prevHeight / 2); 32009 const offscreen = new OffscreenCanvas(newWidth, newHeight); 32010 const ctx = offscreen.getContext("2d"); 32011 ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); 32012 prevWidth = newWidth; 32013 prevHeight = newHeight; 32014 if (bitmap !== originalBitmap) { 32015 bitmap.close(); 32016 } 32017 bitmap = offscreen.transferToImageBitmap(); 32018 } 32019 const ratio = Math.min(maxDim / newWidth, maxDim / newHeight); 32020 newWidth = Math.round(newWidth * ratio); 32021 newHeight = Math.round(newHeight * ratio); 32022 } 32023 const offscreen = new OffscreenCanvas(newWidth, newHeight); 32024 const ctx = offscreen.getContext("2d", { 32025 willReadFrequently: true 32026 }); 32027 ctx.fillStyle = "white"; 32028 ctx.fillRect(0, 0, newWidth, newHeight); 32029 ctx.filter = "grayscale(1)"; 32030 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, newWidth, newHeight); 32031 const grayImage = ctx.getImageData(0, 0, newWidth, newHeight).data; 32032 const uint8Buf = this.#toUint8(grayImage); 32033 return [uint8Buf, newWidth, newHeight]; 32034 } 32035 static extractContoursFromText(text, { 32036 fontFamily, 32037 fontStyle, 32038 fontWeight 32039 }, pageWidth, pageHeight, rotation, innerMargin) { 32040 let canvas = new OffscreenCanvas(1, 1); 32041 let ctx = canvas.getContext("2d", { 32042 alpha: false 32043 }); 32044 const fontSize = 200; 32045 const font = ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`; 32046 const { 32047 actualBoundingBoxLeft, 32048 actualBoundingBoxRight, 32049 actualBoundingBoxAscent, 32050 actualBoundingBoxDescent, 32051 fontBoundingBoxAscent, 32052 fontBoundingBoxDescent, 32053 width 32054 } = ctx.measureText(text); 32055 const SCALE = 1.5; 32056 const canvasWidth = Math.ceil(Math.max(Math.abs(actualBoundingBoxLeft) + Math.abs(actualBoundingBoxRight) || 0, width) * SCALE); 32057 const canvasHeight = Math.ceil(Math.max(Math.abs(actualBoundingBoxAscent) + Math.abs(actualBoundingBoxDescent) || fontSize, Math.abs(fontBoundingBoxAscent) + Math.abs(fontBoundingBoxDescent) || fontSize) * SCALE); 32058 canvas = new OffscreenCanvas(canvasWidth, canvasHeight); 32059 ctx = canvas.getContext("2d", { 32060 alpha: true, 32061 willReadFrequently: true 32062 }); 32063 ctx.font = font; 32064 ctx.filter = "grayscale(1)"; 32065 ctx.fillStyle = "white"; 32066 ctx.fillRect(0, 0, canvasWidth, canvasHeight); 32067 ctx.fillStyle = "black"; 32068 ctx.fillText(text, canvasWidth * (SCALE - 1) / 2, canvasHeight * (3 - SCALE) / 2); 32069 const uint8Buf = this.#toUint8(ctx.getImageData(0, 0, canvasWidth, canvasHeight).data); 32070 const histogram = this.#getHistogram(uint8Buf); 32071 const threshold = this.#guessThreshold(histogram); 32072 const contourList = this.#findContours(uint8Buf, canvasWidth, canvasHeight, threshold); 32073 return this.processDrawnLines({ 32074 lines: { 32075 curves: contourList, 32076 width: canvasWidth, 32077 height: canvasHeight 32078 }, 32079 pageWidth, 32080 pageHeight, 32081 rotation, 32082 innerMargin, 32083 mustSmooth: true, 32084 areContours: true 32085 }); 32086 } 32087 static process(bitmap, pageWidth, pageHeight, rotation, innerMargin) { 32088 const [uint8Buf, width, height] = this.#getGrayPixels(bitmap); 32089 const [buffer, histogram] = this.#bilateralFilter(uint8Buf, width, height, Math.hypot(width, height) * this.#PARAMETERS.sigmaSFactor, this.#PARAMETERS.sigmaR, this.#PARAMETERS.kernelSize); 32090 const threshold = this.#guessThreshold(histogram); 32091 const contourList = this.#findContours(buffer, width, height, threshold); 32092 return this.processDrawnLines({ 32093 lines: { 32094 curves: contourList, 32095 width, 32096 height 32097 }, 32098 pageWidth, 32099 pageHeight, 32100 rotation, 32101 innerMargin, 32102 mustSmooth: true, 32103 areContours: true 32104 }); 32105 } 32106 static processDrawnLines({ 32107 lines, 32108 pageWidth, 32109 pageHeight, 32110 rotation, 32111 innerMargin, 32112 mustSmooth, 32113 areContours 32114 }) { 32115 if (rotation % 180 !== 0) { 32116 [pageWidth, pageHeight] = [pageHeight, pageWidth]; 32117 } 32118 const { 32119 curves, 32120 width, 32121 height 32122 } = lines; 32123 const thickness = lines.thickness ?? 0; 32124 const linesAndPoints = []; 32125 const ratio = Math.min(pageWidth / width, pageHeight / height); 32126 const xScale = ratio / pageWidth; 32127 const yScale = ratio / pageHeight; 32128 const newCurves = []; 32129 for (const { 32130 points 32131 } of curves) { 32132 const reducedPoints = mustSmooth ? this.#douglasPeucker(points) : points; 32133 if (!reducedPoints) { 32134 continue; 32135 } 32136 newCurves.push(reducedPoints); 32137 const len = reducedPoints.length; 32138 const newPoints = new Float32Array(len); 32139 const line = new Float32Array(3 * (len === 2 ? 2 : len - 2)); 32140 linesAndPoints.push({ 32141 line, 32142 points: newPoints 32143 }); 32144 if (len === 2) { 32145 newPoints[0] = reducedPoints[0] * xScale; 32146 newPoints[1] = reducedPoints[1] * yScale; 32147 line.set([NaN, NaN, NaN, NaN, newPoints[0], newPoints[1]], 0); 32148 continue; 32149 } 32150 let [x1, y1, x2, y2] = reducedPoints; 32151 x1 *= xScale; 32152 y1 *= yScale; 32153 x2 *= xScale; 32154 y2 *= yScale; 32155 newPoints.set([x1, y1, x2, y2], 0); 32156 line.set([NaN, NaN, NaN, NaN, x1, y1], 0); 32157 for (let i = 4; i < len; i += 2) { 32158 const x = newPoints[i] = reducedPoints[i] * xScale; 32159 const y = newPoints[i + 1] = reducedPoints[i + 1] * yScale; 32160 line.set(Outline.createBezierPoints(x1, y1, x2, y2, x, y), (i - 2) * 3); 32161 [x1, y1, x2, y2] = [x2, y2, x, y]; 32162 } 32163 } 32164 if (linesAndPoints.length === 0) { 32165 return null; 32166 } 32167 const outline = areContours ? new ContourDrawOutline() : new InkDrawOutline(); 32168 outline.build(linesAndPoints, pageWidth, pageHeight, 1, rotation, areContours ? 0 : thickness, innerMargin); 32169 return { 32170 outline, 32171 newCurves, 32172 areContours, 32173 thickness, 32174 width, 32175 height 32176 }; 32177 } 32178 static async compressSignature({ 32179 outlines, 32180 areContours, 32181 thickness, 32182 width, 32183 height 32184 }) { 32185 let minDiff = Infinity; 32186 let maxDiff = -Infinity; 32187 let outlinesLength = 0; 32188 for (const points of outlines) { 32189 outlinesLength += points.length; 32190 for (let i = 2, ii = points.length; i < ii; i++) { 32191 const dx = points[i] - points[i - 2]; 32192 minDiff = Math.min(minDiff, dx); 32193 maxDiff = Math.max(maxDiff, dx); 32194 } 32195 } 32196 let bufferType; 32197 if (minDiff >= -128 && maxDiff <= 127) { 32198 bufferType = Int8Array; 32199 } else if (minDiff >= -32768 && maxDiff <= 32767) { 32200 bufferType = Int16Array; 32201 } else { 32202 bufferType = Int32Array; 32203 } 32204 const len = outlines.length; 32205 const headerLength = BASE_HEADER_LENGTH + POINTS_PROPERTIES_NUMBER * len; 32206 const header = new Uint32Array(headerLength); 32207 let offset = 0; 32208 header[offset++] = headerLength * Uint32Array.BYTES_PER_ELEMENT + (outlinesLength - 2 * len) * bufferType.BYTES_PER_ELEMENT; 32209 header[offset++] = 0; 32210 header[offset++] = width; 32211 header[offset++] = height; 32212 header[offset++] = areContours ? 0 : 1; 32213 header[offset++] = Math.max(0, Math.floor(thickness ?? 0)); 32214 header[offset++] = len; 32215 header[offset++] = bufferType.BYTES_PER_ELEMENT; 32216 for (const points of outlines) { 32217 header[offset++] = points.length - 2; 32218 header[offset++] = points[0]; 32219 header[offset++] = points[1]; 32220 } 32221 const cs = new CompressionStream("deflate-raw"); 32222 const writer = cs.writable.getWriter(); 32223 await writer.ready; 32224 writer.write(header); 32225 const BufferCtor = bufferType.prototype.constructor; 32226 for (const points of outlines) { 32227 const diffs = new BufferCtor(points.length - 2); 32228 for (let i = 2, ii = points.length; i < ii; i++) { 32229 diffs[i - 2] = points[i] - points[i - 2]; 32230 } 32231 writer.write(diffs); 32232 } 32233 writer.close(); 32234 const bytes = await new Response(cs.readable).bytes(); 32235 return bytes.toBase64(); 32236 } 32237 static async decompressSignature(signatureData) { 32238 try { 32239 const bytes = Uint8Array.fromBase64(signatureData); 32240 const { 32241 readable, 32242 writable 32243 } = new DecompressionStream("deflate-raw"); 32244 const writer = writable.getWriter(); 32245 await writer.ready; 32246 writer.write(bytes).then(async () => { 32247 await writer.ready; 32248 await writer.close(); 32249 }).catch(() => {}); 32250 let data = null; 32251 let offset = 0; 32252 for await (const chunk of readable) { 32253 data ||= new Uint8Array(new Uint32Array(chunk.buffer, 0, 4)[0]); 32254 data.set(chunk, offset); 32255 offset += chunk.length; 32256 } 32257 const header = new Uint32Array(data.buffer, 0, data.length >> 2); 32258 const version = header[1]; 32259 if (version !== 0) { 32260 throw new Error(`Invalid version: ${version}`); 32261 } 32262 const width = header[2]; 32263 const height = header[3]; 32264 const areContours = header[4] === 0; 32265 const thickness = header[5]; 32266 const numberOfDrawings = header[6]; 32267 const bufferType = header[7]; 32268 const outlines = []; 32269 const diffsOffset = (BASE_HEADER_LENGTH + POINTS_PROPERTIES_NUMBER * numberOfDrawings) * Uint32Array.BYTES_PER_ELEMENT; 32270 let diffs; 32271 switch (bufferType) { 32272 case Int8Array.BYTES_PER_ELEMENT: 32273 diffs = new Int8Array(data.buffer, diffsOffset); 32274 break; 32275 case Int16Array.BYTES_PER_ELEMENT: 32276 diffs = new Int16Array(data.buffer, diffsOffset); 32277 break; 32278 case Int32Array.BYTES_PER_ELEMENT: 32279 diffs = new Int32Array(data.buffer, diffsOffset); 32280 break; 32281 } 32282 offset = 0; 32283 for (let i = 0; i < numberOfDrawings; i++) { 32284 const len = header[POINTS_PROPERTIES_NUMBER * i + BASE_HEADER_LENGTH]; 32285 const points = new Float32Array(len + 2); 32286 outlines.push(points); 32287 for (let j = 0; j < POINTS_PROPERTIES_NUMBER - 1; j++) { 32288 points[j] = header[POINTS_PROPERTIES_NUMBER * i + BASE_HEADER_LENGTH + j + 1]; 32289 } 32290 for (let j = 0; j < len; j++) { 32291 points[j + 2] = points[j] + diffs[offset++]; 32292 } 32293 } 32294 return { 32295 areContours, 32296 thickness, 32297 outlines, 32298 width, 32299 height 32300 }; 32301 } catch (e) { 32302 warn(`decompressSignature: ${e}`); 32303 return null; 32304 } 32305 } 32306} 32307 32308;// ./src/display/editor/signature.js 32309 32310 32311 32312 32313 32314 32315 32316 32317 32318 32319 32320 32321class SignatureOptions extends DrawingOptions { 32322 constructor() { 32323 super(); 32324 super.updateProperties({ 32325 fill: AnnotationEditor._defaultLineColor, 32326 "stroke-width": 0 32327 }); 32328 } 32329 clone() { 32330 const clone = new SignatureOptions(); 32331 clone.updateAll(this); 32332 return clone; 32333 } 32334} 32335class DrawnSignatureOptions extends InkDrawingOptions { 32336 constructor(viewerParameters) { 32337 super(viewerParameters); 32338 super.updateProperties({ 32339 stroke: AnnotationEditor._defaultLineColor, 32340 "stroke-width": 1 32341 }); 32342 } 32343 clone() { 32344 const clone = new DrawnSignatureOptions(this._viewParameters); 32345 clone.updateAll(this); 32346 return clone; 32347 } 32348} 32349class SignatureEditor extends DrawingEditor { 32350 #isExtracted = false; 32351 #description = null; 32352 #signatureData = null; 32353 #signatureUUID = null; 32354 static _type = "signature"; 32355 static _editorType = AnnotationEditorType.SIGNATURE; 32356 static _defaultDrawingOptions = null; 32357 constructor(params) { 32358 super({ 32359 ...params, 32360 mustBeCommitted: true, 32361 name: "signatureEditor" 32362 }); 32363 this._willKeepAspectRatio = true; 32364 this.#signatureData = params.signatureData || null; 32365 this.#description = null; 32366 this.defaultL10nId = "pdfjs-editor-signature-editor1"; 32367 } 32368 static initialize(l10n, uiManager) { 32369 AnnotationEditor.initialize(l10n, uiManager); 32370 this._defaultDrawingOptions = new SignatureOptions(); 32371 this._defaultDrawnSignatureOptions = new DrawnSignatureOptions(uiManager.viewParameters); 32372 } 32373 static getDefaultDrawingOptions(options) { 32374 const clone = this._defaultDrawingOptions.clone(); 32375 clone.updateProperties(options); 32376 return clone; 32377 } 32378 static get supportMultipleDrawings() { 32379 return false; 32380 } 32381 static get typesMap() { 32382 return shadow(this, "typesMap", new Map()); 32383 } 32384 static get isDrawer() { 32385 return false; 32386 } 32387 get telemetryFinalData() { 32388 return { 32389 type: "signature", 32390 hasDescription: !!this.#description 32391 }; 32392 } 32393 static computeTelemetryFinalData(data) { 32394 const hasDescriptionStats = data.get("hasDescription"); 32395 return { 32396 hasAltText: hasDescriptionStats.get(true) ?? 0, 32397 hasNoAltText: hasDescriptionStats.get(false) ?? 0 32398 }; 32399 } 32400 get isResizable() { 32401 return true; 32402 } 32403 onScaleChanging() { 32404 if (this._drawId === null) { 32405 return; 32406 } 32407 super.onScaleChanging(); 32408 } 32409 render() { 32410 if (this.div) { 32411 return this.div; 32412 } 32413 let baseX, baseY; 32414 const { 32415 _isCopy 32416 } = this; 32417 if (_isCopy) { 32418 this._isCopy = false; 32419 baseX = this.x; 32420 baseY = this.y; 32421 } 32422 super.render(); 32423 if (this._drawId === null) { 32424 if (this.#signatureData) { 32425 const { 32426 lines, 32427 mustSmooth, 32428 areContours, 32429 description, 32430 uuid, 32431 heightInPage 32432 } = this.#signatureData; 32433 const { 32434 rawDims: { 32435 pageWidth, 32436 pageHeight 32437 }, 32438 rotation 32439 } = this.parent.viewport; 32440 const outline = SignatureExtractor.processDrawnLines({ 32441 lines, 32442 pageWidth, 32443 pageHeight, 32444 rotation, 32445 innerMargin: SignatureEditor._INNER_MARGIN, 32446 mustSmooth, 32447 areContours 32448 }); 32449 this.addSignature(outline, heightInPage, description, uuid); 32450 } else { 32451 this.div.setAttribute("data-l10n-args", JSON.stringify({ 32452 description: "" 32453 })); 32454 this.div.hidden = true; 32455 this._uiManager.getSignature(this); 32456 } 32457 } else { 32458 this.div.setAttribute("data-l10n-args", JSON.stringify({ 32459 description: this.#description || "" 32460 })); 32461 } 32462 if (_isCopy) { 32463 this._isCopy = true; 32464 this._moveAfterPaste(baseX, baseY); 32465 } 32466 return this.div; 32467 } 32468 setUuid(uuid) { 32469 this.#signatureUUID = uuid; 32470 this.addEditToolbar(); 32471 } 32472 getUuid() { 32473 return this.#signatureUUID; 32474 } 32475 get description() { 32476 return this.#description; 32477 } 32478 set description(description) { 32479 this.#description = description; 32480 if (!this.div) { 32481 return; 32482 } 32483 this.div.setAttribute("data-l10n-args", JSON.stringify({ 32484 description 32485 })); 32486 super.addEditToolbar().then(toolbar => { 32487 toolbar?.updateEditSignatureButton(description); 32488 }); 32489 } 32490 getSignaturePreview() { 32491 const { 32492 newCurves, 32493 areContours, 32494 thickness, 32495 width, 32496 height 32497 } = this.#signatureData; 32498 const maxDim = Math.max(width, height); 32499 const outlineData = SignatureExtractor.processDrawnLines({ 32500 lines: { 32501 curves: newCurves.map(points => ({ 32502 points 32503 })), 32504 thickness, 32505 width, 32506 height 32507 }, 32508 pageWidth: maxDim, 32509 pageHeight: maxDim, 32510 rotation: 0, 32511 innerMargin: 0, 32512 mustSmooth: false, 32513 areContours 32514 }); 32515 return { 32516 areContours, 32517 outline: outlineData.outline 32518 }; 32519 } 32520 get toolbarButtons() { 32521 return this._uiManager.signatureManager ? [["editSignature", this._uiManager.signatureManager]] : super.toolbarButtons; 32522 } 32523 addSignature(data, heightInPage, description, uuid) { 32524 const { 32525 x: savedX, 32526 y: savedY 32527 } = this; 32528 const { 32529 outline 32530 } = this.#signatureData = data; 32531 this.#isExtracted = outline instanceof ContourDrawOutline; 32532 this.description = description; 32533 let drawingOptions; 32534 if (this.#isExtracted) { 32535 drawingOptions = SignatureEditor.getDefaultDrawingOptions(); 32536 } else { 32537 drawingOptions = SignatureEditor._defaultDrawnSignatureOptions.clone(); 32538 drawingOptions.updateProperties({ 32539 "stroke-width": outline.thickness 32540 }); 32541 } 32542 this._addOutlines({ 32543 drawOutlines: outline, 32544 drawingOptions 32545 }); 32546 const [, pageHeight] = this.pageDimensions; 32547 let newHeight = heightInPage / pageHeight; 32548 newHeight = newHeight >= 1 ? 0.5 : newHeight; 32549 this.width *= newHeight / this.height; 32550 if (this.width >= 1) { 32551 newHeight *= 0.9 / this.width; 32552 this.width = 0.9; 32553 } 32554 this.height = newHeight; 32555 this.setDims(); 32556 this.x = savedX; 32557 this.y = savedY; 32558 this.center(); 32559 this._onResized(); 32560 this.onScaleChanging(); 32561 this.rotate(); 32562 this._uiManager.addToAnnotationStorage(this); 32563 this.setUuid(uuid); 32564 this._reportTelemetry({ 32565 action: "pdfjs.signature.inserted", 32566 data: { 32567 hasBeenSaved: !!uuid, 32568 hasDescription: !!description 32569 } 32570 }); 32571 this.div.hidden = false; 32572 } 32573 getFromImage(bitmap) { 32574 const { 32575 rawDims: { 32576 pageWidth, 32577 pageHeight 32578 }, 32579 rotation 32580 } = this.parent.viewport; 32581 return SignatureExtractor.process(bitmap, pageWidth, pageHeight, rotation, SignatureEditor._INNER_MARGIN); 32582 } 32583 getFromText(text, fontInfo) { 32584 const { 32585 rawDims: { 32586 pageWidth, 32587 pageHeight 32588 }, 32589 rotation 32590 } = this.parent.viewport; 32591 return SignatureExtractor.extractContoursFromText(text, fontInfo, pageWidth, pageHeight, rotation, SignatureEditor._INNER_MARGIN); 32592 } 32593 getDrawnSignature(curves) { 32594 const { 32595 rawDims: { 32596 pageWidth, 32597 pageHeight 32598 }, 32599 rotation 32600 } = this.parent.viewport; 32601 return SignatureExtractor.processDrawnLines({ 32602 lines: curves, 32603 pageWidth, 32604 pageHeight, 32605 rotation, 32606 innerMargin: SignatureEditor._INNER_MARGIN, 32607 mustSmooth: false, 32608 areContours: false 32609 }); 32610 } 32611 createDrawingOptions({ 32612 areContours, 32613 thickness 32614 }) { 32615 if (areContours) { 32616 this._drawingOptions = SignatureEditor.getDefaultDrawingOptions(); 32617 } else { 32618 this._drawingOptions = SignatureEditor._defaultDrawnSignatureOptions.clone(); 32619 this._drawingOptions.updateProperties({ 32620 "stroke-width": thickness 32621 }); 32622 } 32623 } 32624 serialize(isForCopying = false) { 32625 if (this.isEmpty()) { 32626 return null; 32627 } 32628 const { 32629 lines, 32630 points 32631 } = this.serializeDraw(isForCopying); 32632 const { 32633 _drawingOptions: { 32634 "stroke-width": thickness 32635 } 32636 } = this; 32637 const serialized = Object.assign(super.serialize(isForCopying), { 32638 isSignature: true, 32639 areContours: this.#isExtracted, 32640 color: [0, 0, 0], 32641 thickness: this.#isExtracted ? 0 : thickness 32642 }); 32643 this.addComment(serialized); 32644 if (isForCopying) { 32645 serialized.paths = { 32646 lines, 32647 points 32648 }; 32649 serialized.uuid = this.#signatureUUID; 32650 serialized.isCopy = true; 32651 } else { 32652 serialized.lines = lines; 32653 } 32654 if (this.#description) { 32655 serialized.accessibilityData = { 32656 type: "Figure", 32657 alt: this.#description 32658 }; 32659 } 32660 return serialized; 32661 } 32662 static deserializeDraw(pageX, pageY, pageWidth, pageHeight, innerMargin, data) { 32663 if (data.areContours) { 32664 return ContourDrawOutline.deserialize(pageX, pageY, pageWidth, pageHeight, innerMargin, data); 32665 } 32666 return InkDrawOutline.deserialize(pageX, pageY, pageWidth, pageHeight, innerMargin, data); 32667 } 32668 static async deserialize(data, parent, uiManager) { 32669 const editor = await super.deserialize(data, parent, uiManager); 32670 editor.#isExtracted = data.areContours; 32671 editor.description = data.accessibilityData?.alt || ""; 32672 editor.#signatureUUID = data.uuid; 32673 return editor; 32674 } 32675} 32676 32677;// ./src/display/editor/stamp.js 32678 32679 32680 32681
32682
vendor: 20,695 bytes, lines 32683-33383
32683 32684 32685 32686 32687 32688class StampEditor extends AnnotationEditor { 32689 #bitmap = null; 32690 #bitmapId = null; 32691 #bitmapPromise = null; 32692 #bitmapUrl = null; 32693 #bitmapFile = null; 32694 #bitmapFileName = ""; 32695 #canvas = null; 32696 #missingCanvas = false; 32697 #resizeTimeoutId = null; 32698 #isSvg = false; 32699 #hasBeenAddedInUndoStack = false; 32700 static _type = "stamp"; 32701 static _editorType = AnnotationEditorType.STAMP; 32702 constructor(params) { 32703 super({ 32704 ...params, 32705 name: "stampEditor" 32706 }); 32707 this.#bitmapUrl = params.bitmapUrl; 32708 this.#bitmapFile = params.bitmapFile; 32709 this.defaultL10nId = "pdfjs-editor-stamp-editor"; 32710 } 32711 static initialize(l10n, uiManager) { 32712 AnnotationEditor.initialize(l10n, uiManager); 32713 } 32714 static isHandlingMimeForPasting(mime) { 32715 return SupportedImageMimeTypes.includes(mime); 32716 } 32717 static paste(item, parent) { 32718 parent.pasteEditor({ 32719 mode: AnnotationEditorType.STAMP 32720 }, { 32721 bitmapFile: item.getAsFile() 32722 }); 32723 } 32724 altTextFinish() { 32725 if (this._uiManager.useNewAltTextFlow) { 32726 this.div.hidden = false; 32727 } 32728 super.altTextFinish(); 32729 } 32730 get telemetryFinalData() { 32731 return { 32732 type: "stamp", 32733 hasAltText: !!this.altTextData?.altText 32734 }; 32735 } 32736 static computeTelemetryFinalData(data) { 32737 const hasAltTextStats = data.get("hasAltText"); 32738 return { 32739 hasAltText: hasAltTextStats.get(true) ?? 0, 32740 hasNoAltText: hasAltTextStats.get(false) ?? 0 32741 }; 32742 } 32743 #getBitmapFetched(data, fromId = false) { 32744 if (!data) { 32745 this.remove(); 32746 return; 32747 } 32748 this.#bitmap = data.bitmap; 32749 if (!fromId) { 32750 this.#bitmapId = data.id; 32751 this.#isSvg = data.isSvg; 32752 } 32753 if (data.file) { 32754 this.#bitmapFileName = data.file.name; 32755 } 32756 this.#createCanvas(); 32757 } 32758 #getBitmapDone() { 32759 this.#bitmapPromise = null; 32760 this._uiManager.enableWaiting(false); 32761 if (!this.#canvas) { 32762 return; 32763 } 32764 if (this._uiManager.useNewAltTextWhenAddingImage && this._uiManager.useNewAltTextFlow && this.#bitmap) { 32765 this.addEditToolbar().then(() => { 32766 this._editToolbar.hide(); 32767 this._uiManager.editAltText(this, true); 32768 }); 32769 return; 32770 } 32771 if (!this._uiManager.useNewAltTextWhenAddingImage && this._uiManager.useNewAltTextFlow && this.#bitmap) { 32772 this._reportTelemetry({ 32773 action: "pdfjs.image.image_added", 32774 data: { 32775 alt_text_modal: false, 32776 alt_text_type: "empty" 32777 } 32778 }); 32779 try { 32780 this.mlGuessAltText(); 32781 } catch {} 32782 } 32783 this.div.focus(); 32784 } 32785 async mlGuessAltText(imageData = null, updateAltTextData = true) { 32786 if (this.hasAltTextData()) { 32787 return null; 32788 } 32789 const { 32790 mlManager 32791 } = this._uiManager; 32792 if (!mlManager) { 32793 throw new Error("No ML."); 32794 } 32795 if (!(await mlManager.isEnabledFor("altText"))) { 32796 throw new Error("ML isn't enabled for alt text."); 32797 } 32798 const { 32799 data, 32800 width, 32801 height 32802 } = imageData || this.copyCanvas(null, null, true).imageData; 32803 const response = await mlManager.guess({ 32804 name: "altText", 32805 request: { 32806 data, 32807 width, 32808 height, 32809 channels: data.length / (width * height) 32810 } 32811 }); 32812 if (!response) { 32813 throw new Error("No response from the AI service."); 32814 } 32815 if (response.error) { 32816 throw new Error("Error from the AI service."); 32817 } 32818 if (response.cancel) { 32819 return null; 32820 } 32821 if (!response.output) { 32822 throw new Error("No valid response from the AI service."); 32823 } 32824 const altText = response.output; 32825 await this.setGuessedAltText(altText); 32826 if (updateAltTextData && !this.hasAltTextData()) { 32827 this.altTextData = { 32828 alt: altText, 32829 decorative: false 32830 }; 32831 } 32832 return altText; 32833 } 32834 #getBitmap() { 32835 if (this.#bitmapId) { 32836 this._uiManager.enableWaiting(true); 32837 this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => this.#getBitmapFetched(data, true)).finally(() => this.#getBitmapDone()); 32838 return; 32839 } 32840 if (this.#bitmapUrl) { 32841 const url = this.#bitmapUrl; 32842 this.#bitmapUrl = null; 32843 this._uiManager.enableWaiting(true); 32844 this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 32845 return; 32846 } 32847 if (this.#bitmapFile) { 32848 const file = this.#bitmapFile; 32849 this.#bitmapFile = null; 32850 this._uiManager.enableWaiting(true); 32851 this.#bitmapPromise = this._uiManager.imageManager.getFromFile(file).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); 32852 return; 32853 } 32854 const input = document.createElement("input"); 32855 input.type = "file"; 32856 input.accept = SupportedImageMimeTypes.join(","); 32857 const signal = this._uiManager._signal; 32858 this.#bitmapPromise = new Promise(resolve => { 32859 input.addEventListener("change", async () => { 32860 if (!input.files || input.files.length === 0) { 32861 this.remove(); 32862 } else { 32863 this._uiManager.enableWaiting(true); 32864 const data = await this._uiManager.imageManager.getFromFile(input.files[0]); 32865 this._reportTelemetry({ 32866 action: "pdfjs.image.image_selected", 32867 data: { 32868 alt_text_modal: this._uiManager.useNewAltTextFlow 32869 } 32870 }); 32871 this.#getBitmapFetched(data); 32872 } 32873 resolve(); 32874 }, { 32875 signal 32876 }); 32877 input.addEventListener("cancel", () => { 32878 this.remove(); 32879 resolve(); 32880 }, { 32881 signal 32882 }); 32883 }).finally(() => this.#getBitmapDone()); 32884 input.click(); 32885 } 32886 remove() { 32887 if (this.#bitmapId) { 32888 this.#bitmap = null; 32889 this._uiManager.imageManager.deleteId(this.#bitmapId); 32890 this.#canvas?.remove(); 32891 this.#canvas = null; 32892 if (this.#resizeTimeoutId) { 32893 clearTimeout(this.#resizeTimeoutId); 32894 this.#resizeTimeoutId = null; 32895 } 32896 } 32897 super.remove(); 32898 } 32899 rebuild() { 32900 if (!this.parent) { 32901 if (this.#bitmapId) { 32902 this.#getBitmap(); 32903 } 32904 return; 32905 } 32906 super.rebuild(); 32907 if (this.div === null) { 32908 return; 32909 } 32910 if (this.#bitmapId && this.#canvas === null) { 32911 this.#getBitmap(); 32912 } 32913 if (!this.isAttachedToDOM) { 32914 this.parent.add(this); 32915 } 32916 } 32917 onceAdded(focus) { 32918 this._isDraggable = true; 32919 if (focus) { 32920 this.div.focus(); 32921 } 32922 } 32923 isEmpty() { 32924 return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile || this.#bitmapId || this.#missingCanvas); 32925 } 32926 get toolbarButtons() { 32927 return [["altText", this.createAltText()]]; 32928 } 32929 get isResizable() { 32930 return true; 32931 } 32932 render() { 32933 if (this.div) { 32934 return this.div; 32935 } 32936 let baseX, baseY; 32937 if (this._isCopy) { 32938 baseX = this.x; 32939 baseY = this.y; 32940 } 32941 super.render(); 32942 this.div.hidden = true; 32943 this.createAltText(); 32944 if (!this.#missingCanvas) { 32945 if (this.#bitmap) { 32946 this.#createCanvas(); 32947 } else { 32948 this.#getBitmap(); 32949 } 32950 } 32951 if (this._isCopy) { 32952 this._moveAfterPaste(baseX, baseY); 32953 } 32954 this._uiManager.addShouldRescale(this); 32955 return this.div; 32956 } 32957 setCanvas(annotationElementId, canvas) { 32958 const { 32959 id: bitmapId, 32960 bitmap 32961 } = this._uiManager.imageManager.getFromCanvas(annotationElementId, canvas); 32962 canvas.remove(); 32963 if (bitmapId && this._uiManager.imageManager.isValidId(bitmapId)) { 32964 this.#bitmapId = bitmapId; 32965 if (bitmap) { 32966 this.#bitmap = bitmap; 32967 } 32968 this.#missingCanvas = false; 32969 this.#createCanvas(); 32970 } 32971 } 32972 _onResized() { 32973 this.onScaleChanging(); 32974 } 32975 onScaleChanging() { 32976 if (!this.parent) { 32977 return; 32978 } 32979 if (this.#resizeTimeoutId !== null) { 32980 clearTimeout(this.#resizeTimeoutId); 32981 } 32982 const TIME_TO_WAIT = 200; 32983 this.#resizeTimeoutId = setTimeout(() => { 32984 this.#resizeTimeoutId = null; 32985 this.#drawBitmap(); 32986 }, TIME_TO_WAIT); 32987 } 32988 #createCanvas() { 32989 const { 32990 div 32991 } = this; 32992 let { 32993 width, 32994 height 32995 } = this.#bitmap; 32996 const [pageWidth, pageHeight] = this.pageDimensions; 32997 const MAX_RATIO = 0.75; 32998 if (this.width) { 32999 width = this.width * pageWidth; 33000 height = this.height * pageHeight; 33001 } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) { 33002 const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height); 33003 width *= factor; 33004 height *= factor; 33005 } 33006 this._uiManager.enableWaiting(false); 33007 const canvas = this.#canvas = document.createElement("canvas"); 33008 canvas.setAttribute("role", "img"); 33009 this.addContainer(canvas); 33010 this.width = width / pageWidth; 33011 this.height = height / pageHeight; 33012 this.setDims(); 33013 if (this._initialOptions?.isCentered) { 33014 this.center(); 33015 } else { 33016 this.fixAndSetPosition(); 33017 } 33018 this._initialOptions = null; 33019 if (!this._uiManager.useNewAltTextWhenAddingImage || !this._uiManager.useNewAltTextFlow || this.annotationElementId) { 33020 div.hidden = false; 33021 } 33022 this.#drawBitmap(); 33023 if (!this.#hasBeenAddedInUndoStack) { 33024 this.parent.addUndoableEditor(this); 33025 this.#hasBeenAddedInUndoStack = true; 33026 } 33027 this._reportTelemetry({ 33028 action: "inserted_image" 33029 }); 33030 if (this.#bitmapFileName) { 33031 this.div.setAttribute("aria-description", this.#bitmapFileName); 33032 } 33033 if (!this.annotationElementId) { 33034 this._uiManager.a11yAlert(AnnotationEditor._l10nAlert.stamp); 33035 } 33036 } 33037 copyCanvas(maxDataDimension, maxPreviewDimension, createImageData = false) { 33038 maxDataDimension ||= 224; 33039 const { 33040 width: bitmapWidth, 33041 height: bitmapHeight 33042 } = this.#bitmap; 33043 const outputScale = new OutputScale(); 33044 let bitmap = this.#bitmap; 33045 let width = bitmapWidth, 33046 height = bitmapHeight; 33047 let canvas = null; 33048 if (maxPreviewDimension) { 33049 if (bitmapWidth > maxPreviewDimension || bitmapHeight > maxPreviewDimension) { 33050 const ratio = Math.min(maxPreviewDimension / bitmapWidth, maxPreviewDimension / bitmapHeight); 33051 width = Math.floor(bitmapWidth * ratio); 33052 height = Math.floor(bitmapHeight * ratio); 33053 } 33054 canvas = document.createElement("canvas"); 33055 const scaledWidth = canvas.width = Math.ceil(width * outputScale.sx); 33056 const scaledHeight = canvas.height = Math.ceil(height * outputScale.sy); 33057 if (!this.#isSvg) { 33058 bitmap = this.#scaleBitmap(scaledWidth, scaledHeight); 33059 } 33060 const ctx = canvas.getContext("2d"); 33061 ctx.filter = this._uiManager.hcmFilter; 33062 let white = "white", 33063 black = "#cfcfd8"; 33064 if (this._uiManager.hcmFilter !== "none") { 33065 black = "black"; 33066 } else if (ColorScheme.isDarkMode) { 33067 white = "#8f8f9d"; 33068 black = "#42414d"; 33069 } 33070 const boxDim = 15; 33071 const boxDimWidth = boxDim * outputScale.sx; 33072 const boxDimHeight = boxDim * outputScale.sy; 33073 const pattern = new OffscreenCanvas(boxDimWidth * 2, boxDimHeight * 2); 33074 const patternCtx = pattern.getContext("2d"); 33075 patternCtx.fillStyle = white; 33076 patternCtx.fillRect(0, 0, boxDimWidth * 2, boxDimHeight * 2); 33077 patternCtx.fillStyle = black; 33078 patternCtx.fillRect(0, 0, boxDimWidth, boxDimHeight); 33079 patternCtx.fillRect(boxDimWidth, boxDimHeight, boxDimWidth, boxDimHeight); 33080 ctx.fillStyle = ctx.createPattern(pattern, "repeat"); 33081 ctx.fillRect(0, 0, scaledWidth, scaledHeight); 33082 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight); 33083 } 33084 let imageData = null; 33085 if (createImageData) { 33086 let dataWidth, dataHeight; 33087 if (outputScale.symmetric && bitmap.width < maxDataDimension && bitmap.height < maxDataDimension) { 33088 dataWidth = bitmap.width; 33089 dataHeight = bitmap.height; 33090 } else { 33091 bitmap = this.#bitmap; 33092 if (bitmapWidth > maxDataDimension || bitmapHeight > maxDataDimension) { 33093 const ratio = Math.min(maxDataDimension / bitmapWidth, maxDataDimension / bitmapHeight); 33094 dataWidth = Math.floor(bitmapWidth * ratio); 33095 dataHeight = Math.floor(bitmapHeight * ratio); 33096 if (!this.#isSvg) { 33097 bitmap = this.#scaleBitmap(dataWidth, dataHeight); 33098 } 33099 } 33100 } 33101 const offscreen = new OffscreenCanvas(dataWidth, dataHeight); 33102 const offscreenCtx = offscreen.getContext("2d", { 33103 willReadFrequently: true 33104 }); 33105 offscreenCtx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, dataWidth, dataHeight); 33106 imageData = { 33107 width: dataWidth, 33108 height: dataHeight, 33109 data: offscreenCtx.getImageData(0, 0, dataWidth, dataHeight).data 33110 }; 33111 } 33112 return { 33113 canvas, 33114 width, 33115 height, 33116 imageData 33117 }; 33118 } 33119 #scaleBitmap(width, height) { 33120 const { 33121 width: bitmapWidth, 33122 height: bitmapHeight 33123 } = this.#bitmap; 33124 let newWidth = bitmapWidth; 33125 let newHeight = bitmapHeight; 33126 let bitmap = this.#bitmap; 33127 while (newWidth > 2 * width || newHeight > 2 * height) { 33128 const prevWidth = newWidth; 33129 const prevHeight = newHeight; 33130 if (newWidth > 2 * width) { 33131 newWidth = Math.ceil(newWidth / 2); 33132 } 33133 if (newHeight > 2 * height) { 33134 newHeight = Math.ceil(newHeight / 2); 33135 } 33136 const offscreen = new OffscreenCanvas(newWidth, newHeight); 33137 const ctx = offscreen.getContext("2d"); 33138 ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); 33139 bitmap = offscreen.transferToImageBitmap(); 33140 } 33141 return bitmap; 33142 } 33143 #drawBitmap() { 33144 const [parentWidth, parentHeight] = this.parentDimensions; 33145 const { 33146 width, 33147 height 33148 } = this; 33149 const outputScale = new OutputScale(); 33150 const scaledWidth = Math.ceil(width * parentWidth * outputScale.sx); 33151 const scaledHeight = Math.ceil(height * parentHeight * outputScale.sy); 33152 const canvas = this.#canvas; 33153 if (!canvas || canvas.width === scaledWidth && canvas.height === scaledHeight) { 33154 return; 33155 } 33156 canvas.width = scaledWidth; 33157 canvas.height = scaledHeight; 33158 const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(scaledWidth, scaledHeight); 33159 const ctx = canvas.getContext("2d"); 33160 ctx.filter = this._uiManager.hcmFilter; 33161 ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight); 33162 } 33163 #serializeBitmap(toUrl) { 33164 if (toUrl) { 33165 if (this.#isSvg) { 33166 const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId); 33167 if (url) { 33168 return url; 33169 } 33170 } 33171 const canvas = document.createElement("canvas"); 33172 ({ 33173 width: canvas.width, 33174 height: canvas.height 33175 } = this.#bitmap); 33176 const ctx = canvas.getContext("2d"); 33177 ctx.drawImage(this.#bitmap, 0, 0); 33178 return canvas.toDataURL(); 33179 } 33180 if (this.#isSvg) { 33181 const [pageWidth, pageHeight] = this.pageDimensions; 33182 const width = Math.round(this.width * pageWidth * PixelsPerInch.PDF_TO_CSS_UNITS); 33183 const height = Math.round(this.height * pageHeight * PixelsPerInch.PDF_TO_CSS_UNITS); 33184 const offscreen = new OffscreenCanvas(width, height); 33185 const ctx = offscreen.getContext("2d"); 33186 ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height); 33187 return offscreen.transferToImageBitmap(); 33188 } 33189 return structuredClone(this.#bitmap); 33190 } 33191 static async deserialize(data, parent, uiManager) { 33192 let initialData = null; 33193 let missingCanvas = false; 33194 if (data instanceof StampAnnotationElement) { 33195 const { 33196 data: { 33197 rect, 33198 rotation, 33199 id, 33200 structParent, 33201 popupRef, 33202 richText, 33203 contentsObj, 33204 creationDate, 33205 modificationDate 33206 }, 33207 container, 33208 parent: { 33209 page: { 33210 pageNumber 33211 } 33212 }, 33213 canvas 33214 } = data; 33215 let bitmapId, bitmap; 33216 if (canvas) { 33217 delete data.canvas; 33218 ({ 33219 id: bitmapId, 33220 bitmap 33221 } = uiManager.imageManager.getFromCanvas(container.id, canvas)); 33222 canvas.remove(); 33223 } else { 33224 missingCanvas = true; 33225 data._hasNoCanvas = true; 33226 } 33227 const altText = (await parent._structTree.getAriaAttributes(`${AnnotationPrefix}${id}`))?.get("aria-label") || ""; 33228 initialData = data = { 33229 annotationType: AnnotationEditorType.STAMP, 33230 bitmapId, 33231 bitmap, 33232 pageIndex: pageNumber - 1, 33233 rect: rect.slice(0), 33234 rotation, 33235 annotationElementId: id, 33236 id, 33237 deleted: false, 33238 accessibilityData: { 33239 decorative: false, 33240 altText 33241 }, 33242 isSvg: false, 33243 structParent, 33244 popupRef, 33245 richText, 33246 comment: contentsObj?.str || null, 33247 creationDate, 33248 modificationDate 33249 }; 33250 } 33251 const editor = await super.deserialize(data, parent, uiManager); 33252 const { 33253 rect, 33254 bitmap, 33255 bitmapUrl, 33256 bitmapId, 33257 isSvg, 33258 accessibilityData 33259 } = data; 33260 if (missingCanvas) { 33261 uiManager.addMissingCanvas(data.id, editor); 33262 editor.#missingCanvas = true; 33263 } else if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) { 33264 editor.#bitmapId = bitmapId; 33265 if (bitmap) { 33266 editor.#bitmap = bitmap; 33267 } 33268 } else { 33269 editor.#bitmapUrl = bitmapUrl; 33270 } 33271 editor.#isSvg = isSvg; 33272 const [parentWidth, parentHeight] = editor.pageDimensions; 33273 editor.width = (rect[2] - rect[0]) / parentWidth; 33274 editor.height = (rect[3] - rect[1]) / parentHeight; 33275 if (accessibilityData) { 33276 editor.altTextData = accessibilityData; 33277 } 33278 editor._initialData = initialData; 33279 if (data.comment) { 33280 editor.setCommentData(data); 33281 } 33282 editor.#hasBeenAddedInUndoStack = !!initialData; 33283 return editor; 33284 } 33285 serialize(isForCopying = false, context = null) { 33286 if (this.isEmpty()) { 33287 return null; 33288 } 33289 if (this.deleted) { 33290 return this.serializeDeleted(); 33291 } 33292 const serialized = Object.assign(super.serialize(isForCopying), { 33293 bitmapId: this.#bitmapId, 33294 isSvg: this.#isSvg 33295 }); 33296 this.addComment(serialized); 33297 if (isForCopying) { 33298 serialized.bitmapUrl = this.#serializeBitmap(true); 33299 serialized.accessibilityData = this.serializeAltText(true); 33300 serialized.isCopy = true; 33301 return serialized; 33302 } 33303 const { 33304 decorative, 33305 altText 33306 } = this.serializeAltText(false); 33307 if (!decorative && altText) { 33308 serialized.accessibilityData = { 33309 type: "Figure", 33310 alt: altText 33311 }; 33312 } 33313 if (this.annotationElementId) { 33314 const changes = this.#hasElementChanged(serialized); 33315 if (changes.isSame) { 33316 return null; 33317 } 33318 if (changes.isSameAltText) { 33319 delete serialized.accessibilityData; 33320 } else { 33321 serialized.accessibilityData.structParent = this._initialData.structParent ?? -1; 33322 } 33323 serialized.id = this.annotationElementId; 33324 delete serialized.bitmapId; 33325 return serialized; 33326 } 33327 if (context === null) { 33328 return serialized; 33329 } 33330 context.stamps ||= new Map(); 33331 const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null; 33332 if (!context.stamps.has(this.#bitmapId)) { 33333 context.stamps.set(this.#bitmapId, { 33334 area, 33335 serialized 33336 }); 33337 serialized.bitmap = this.#serializeBitmap(false); 33338 } else if (this.#isSvg) { 33339 const prevData = context.stamps.get(this.#bitmapId); 33340 if (area > prevData.area) { 33341 prevData.area = area; 33342 prevData.serialized.bitmap.close(); 33343 prevData.serialized.bitmap = this.#serializeBitmap(false); 33344 } 33345 } 33346 return serialized; 33347 } 33348 #hasElementChanged(serialized) { 33349 const { 33350 pageIndex, 33351 accessibilityData: { 33352 altText 33353 } 33354 } = this._initialData; 33355 const isSamePageIndex = serialized.pageIndex === pageIndex; 33356 const isSameAltText = (serialized.accessibilityData?.alt || "") === altText; 33357 return { 33358 isSame: !this.hasEditedComment && !this._hasBeenMoved && !this._hasBeenResized && isSamePageIndex && isSameAltText, 33359 isSameAltText 33360 }; 33361 } 33362 renderAnnotationElement(annotation) { 33363 if (this.deleted) { 33364 annotation.hide(); 33365 return null; 33366 } 33367 annotation.updateEdited({ 33368 rect: this.getPDFRect(), 33369 popup: this.comment 33370 }); 33371 return null; 33372 } 33373} 33374 33375;// ./src/display/editor/annotation_editor_layer.js 33376 33377 33378 33379 33380 33381 33382 33383
33384
vendor: 21,544 bytes, lines 33385-34126
33385 33386 33387 33388 33389 33390 33391 33392 33393 33394class AnnotationEditorLayer { 33395 #accessibilityManager; 33396 #allowClick = false; 33397 #annotationLayer = null; 33398 #clickAC = null; 33399 #editorFocusTimeoutId = null; 33400 #editors = new Map(); 33401 #hadPointerDown = false; 33402 #isDisabling = false; 33403 #isEnabling = false; 33404 #drawingAC = null; 33405 #focusedElement = null; 33406 #textLayer = null; 33407 #textSelectionAC = null; 33408 #textLayerDblClickAC = null; 33409 #lastPointerDownTimestamp = -1; 33410 #uiManager; 33411 static _initialized = false; 33412 static #editorTypes = new Map([FreeTextEditor, InkEditor, StampEditor, HighlightEditor, SignatureEditor].map(type => [type._editorType, type])); 33413 constructor({ 33414 uiManager, 33415 pageIndex, 33416 div, 33417 structTreeLayer, 33418 accessibilityManager, 33419 annotationLayer, 33420 drawLayer, 33421 textLayer, 33422 viewport, 33423 l10n 33424 }) { 33425 const editorTypes = [...AnnotationEditorLayer.#editorTypes.values()]; 33426 if (!AnnotationEditorLayer._initialized) { 33427 AnnotationEditorLayer._initialized = true; 33428 for (const editorType of editorTypes) { 33429 editorType.initialize(l10n, uiManager); 33430 } 33431 } 33432 uiManager.registerEditorTypes(editorTypes); 33433 this.#uiManager = uiManager; 33434 this.pageIndex = pageIndex; 33435 this.div = div; 33436 this.#accessibilityManager = accessibilityManager; 33437 this.#annotationLayer = annotationLayer; 33438 this.viewport = viewport; 33439 this.#textLayer = textLayer; 33440 this.drawLayer = drawLayer; 33441 this._structTree = structTreeLayer; 33442 this.#uiManager.addLayer(this); 33443 } 33444 get isEmpty() { 33445 return this.#editors.size === 0; 33446 } 33447 get isInvisible() { 33448 return this.isEmpty && this.#uiManager.getMode() === AnnotationEditorType.NONE; 33449 } 33450 updateToolbar(options) { 33451 this.#uiManager.updateToolbar(options); 33452 } 33453 updateMode(mode = this.#uiManager.getMode()) { 33454 this.#cleanup(); 33455 switch (mode) { 33456 case AnnotationEditorType.NONE: 33457 this.div.classList.toggle("nonEditing", true); 33458 this.disableTextSelection(); 33459 this.togglePointerEvents(false); 33460 this.toggleAnnotationLayerPointerEvents(true); 33461 this.disableClick(); 33462 return; 33463 case AnnotationEditorType.INK: 33464 this.disableTextSelection(); 33465 this.togglePointerEvents(true); 33466 this.enableClick(); 33467 break; 33468 case AnnotationEditorType.HIGHLIGHT: 33469 this.enableTextSelection(); 33470 this.togglePointerEvents(false); 33471 this.disableClick(); 33472 break; 33473 default: 33474 this.disableTextSelection(); 33475 this.togglePointerEvents(true); 33476 this.enableClick(); 33477 } 33478 this.toggleAnnotationLayerPointerEvents(false); 33479 const { 33480 classList 33481 } = this.div; 33482 classList.toggle("nonEditing", false); 33483 if (mode === AnnotationEditorType.POPUP) { 33484 classList.toggle("commentEditing", true); 33485 } else { 33486 classList.toggle("commentEditing", false); 33487 for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { 33488 classList.toggle(`${editorType._type}Editing`, mode === editorType._editorType); 33489 } 33490 } 33491 this.div.hidden = false; 33492 } 33493 hasTextLayer(textLayer) { 33494 return textLayer === this.#textLayer?.div; 33495 } 33496 setEditingState(isEditing) { 33497 this.#uiManager.setEditingState(isEditing); 33498 } 33499 addCommands(params) { 33500 this.#uiManager.addCommands(params); 33501 } 33502 cleanUndoStack(type) { 33503 this.#uiManager.cleanUndoStack(type); 33504 } 33505 toggleDrawing(enabled = false) { 33506 this.div.classList.toggle("drawing", !enabled); 33507 } 33508 togglePointerEvents(enabled = false) { 33509 this.div.classList.toggle("disabled", !enabled); 33510 } 33511 toggleAnnotationLayerPointerEvents(enabled = false) { 33512 this.#annotationLayer?.togglePointerEvents(enabled); 33513 } 33514 get #allEditorsIterator() { 33515 return this.#editors.size !== 0 ? this.#editors.values() : this.#uiManager.getEditors(this.pageIndex); 33516 } 33517 async enable() { 33518 this.#isEnabling = true; 33519 this.div.tabIndex = 0; 33520 this.togglePointerEvents(true); 33521 this.div.classList.toggle("nonEditing", false); 33522 this.#textLayerDblClickAC?.abort(); 33523 this.#textLayerDblClickAC = null; 33524 const annotationElementIds = new Set(); 33525 for (const editor of this.#allEditorsIterator) { 33526 editor.enableEditing(); 33527 editor.show(true); 33528 if (editor.annotationElementId) { 33529 this.#uiManager.removeChangedExistingAnnotation(editor); 33530 annotationElementIds.add(editor.annotationElementId); 33531 } 33532 } 33533 const annotationLayer = this.#annotationLayer; 33534 if (annotationLayer) { 33535 for (const editable of annotationLayer.getEditableAnnotations()) { 33536 editable.hide(); 33537 if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) { 33538 continue; 33539 } 33540 if (annotationElementIds.has(editable.data.id)) { 33541 continue; 33542 } 33543 const editor = await this.deserialize(editable); 33544 if (!editor) { 33545 continue; 33546 } 33547 this.addOrRebuild(editor); 33548 editor.enableEditing(); 33549 } 33550 } 33551 this.#isEnabling = false; 33552 this.#uiManager._eventBus.dispatch("editorsrendered", { 33553 source: this, 33554 pageNumber: this.pageIndex + 1 33555 }); 33556 } 33557 disable() { 33558 this.#isDisabling = true; 33559 this.div.tabIndex = -1; 33560 this.togglePointerEvents(false); 33561 this.div.classList.toggle("nonEditing", true); 33562 if (this.#textLayer && !this.#textLayerDblClickAC) { 33563 this.#textLayerDblClickAC = new AbortController(); 33564 const signal = this.#uiManager.combinedSignal(this.#textLayerDblClickAC); 33565 this.#textLayer.div.addEventListener("pointerdown", e => { 33566 const DBL_CLICK_THRESHOLD = 500; 33567 const { 33568 clientX, 33569 clientY, 33570 timeStamp 33571 } = e; 33572 const lastPointerDownTimestamp = this.#lastPointerDownTimestamp; 33573 if (timeStamp - lastPointerDownTimestamp > DBL_CLICK_THRESHOLD) { 33574 this.#lastPointerDownTimestamp = timeStamp; 33575 return; 33576 } 33577 this.#lastPointerDownTimestamp = -1; 33578 const { 33579 classList 33580 } = this.div; 33581 classList.toggle("getElements", true); 33582 const elements = document.elementsFromPoint(clientX, clientY); 33583 classList.toggle("getElements", false); 33584 if (!this.div.contains(elements[0])) { 33585 return; 33586 } 33587 let id; 33588 const regex = new RegExp(`^${AnnotationEditorPrefix}[0-9]+$`); 33589 for (const element of elements) { 33590 if (regex.test(element.id)) { 33591 id = element.id; 33592 break; 33593 } 33594 } 33595 if (!id) { 33596 return; 33597 } 33598 const editor = this.#editors.get(id); 33599 if (editor?.annotationElementId === null) { 33600 stopEvent(e); 33601 editor.dblclick(e); 33602 } 33603 }, { 33604 signal, 33605 capture: true 33606 }); 33607 } 33608 const annotationLayer = this.#annotationLayer; 33609 const needFakeAnnotation = []; 33610 if (annotationLayer) { 33611 const changedAnnotations = new Map(); 33612 const resetAnnotations = new Map(); 33613 for (const editor of this.#allEditorsIterator) { 33614 editor.disableEditing(); 33615 if (!editor.annotationElementId) { 33616 needFakeAnnotation.push(editor); 33617 continue; 33618 } 33619 if (editor.serialize() !== null) { 33620 changedAnnotations.set(editor.annotationElementId, editor); 33621 continue; 33622 } else { 33623 resetAnnotations.set(editor.annotationElementId, editor); 33624 } 33625 this.getEditableAnnotation(editor.annotationElementId)?.show(); 33626 editor.remove(); 33627 } 33628 for (const editable of annotationLayer.getEditableAnnotations()) { 33629 const { 33630 id 33631 } = editable.data; 33632 if (this.#uiManager.isDeletedAnnotationElement(id)) { 33633 editable.updateEdited({ 33634 deleted: true 33635 }); 33636 continue; 33637 } 33638 let editor = resetAnnotations.get(id); 33639 if (editor) { 33640 editor.resetAnnotationElement(editable); 33641 editor.show(false); 33642 editable.show(); 33643 continue; 33644 } 33645 editor = changedAnnotations.get(id); 33646 if (editor) { 33647 this.#uiManager.addChangedExistingAnnotation(editor); 33648 if (editor.renderAnnotationElement(editable)) { 33649 editor.show(false); 33650 } 33651 } 33652 editable.show(); 33653 } 33654 } 33655 this.#cleanup(); 33656 if (this.isEmpty) { 33657 this.div.hidden = true; 33658 } 33659 const { 33660 classList 33661 } = this.div; 33662 for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { 33663 classList.remove(`${editorType._type}Editing`); 33664 } 33665 this.disableTextSelection(); 33666 this.toggleAnnotationLayerPointerEvents(true); 33667 annotationLayer?.updateFakeAnnotations(needFakeAnnotation); 33668 this.#isDisabling = false; 33669 } 33670 getEditableAnnotation(id) { 33671 return this.#annotationLayer?.getEditableAnnotation(id) || null; 33672 } 33673 setActiveEditor(editor) { 33674 const currentActive = this.#uiManager.getActive(); 33675 if (currentActive === editor) { 33676 return; 33677 } 33678 this.#uiManager.setActiveEditor(editor); 33679 } 33680 enableTextSelection() { 33681 this.div.tabIndex = -1; 33682 if (this.#textLayer?.div && !this.#textSelectionAC) { 33683 this.#textSelectionAC = new AbortController(); 33684 const signal = this.#uiManager.combinedSignal(this.#textSelectionAC); 33685 this.#textLayer.div.addEventListener("pointerdown", this.#textLayerPointerDown.bind(this), { 33686 signal 33687 }); 33688 this.#textLayer.div.classList.add("highlighting"); 33689 } 33690 } 33691 disableTextSelection() { 33692 this.div.tabIndex = 0; 33693 if (this.#textLayer?.div && this.#textSelectionAC) { 33694 this.#textSelectionAC.abort(); 33695 this.#textSelectionAC = null; 33696 this.#textLayer.div.classList.remove("highlighting"); 33697 } 33698 } 33699 #textLayerPointerDown(event) { 33700 this.#uiManager.unselectAll(); 33701 const { 33702 target 33703 } = event; 33704 if (target === this.#textLayer.div || (target.getAttribute("role") === "img" || target.classList.contains("endOfContent") || target.classList.contains("textLayerImages") || target.classList.contains("textLayerImagePlaceholder")) && this.#textLayer.div.contains(target)) { 33705 const { 33706 isMac 33707 } = FeatureTest.platform; 33708 if (event.button !== 0 || event.ctrlKey && isMac) { 33709 return; 33710 } 33711 this.#uiManager.showAllEditors("highlight", true, true); 33712 HighlightEditor.startDrawing(this, this.#uiManager, this.#uiManager.direction === "ltr", event); 33713 event.preventDefault(); 33714 } 33715 } 33716 enableClick() { 33717 if (this.#clickAC) { 33718 return; 33719 } 33720 this.#clickAC = new AbortController(); 33721 const signal = this.#uiManager.combinedSignal(this.#clickAC); 33722 this.div.addEventListener("pointerdown", this.pointerdown.bind(this), { 33723 signal 33724 }); 33725 const pointerup = this.pointerup.bind(this); 33726 this.div.addEventListener("pointerup", pointerup, { 33727 signal 33728 }); 33729 this.div.addEventListener("pointercancel", pointerup, { 33730 signal 33731 }); 33732 } 33733 disableClick() { 33734 this.#clickAC?.abort(); 33735 this.#clickAC = null; 33736 } 33737 attach(editor) { 33738 this.#editors.set(editor.id, editor); 33739 const { 33740 annotationElementId 33741 } = editor; 33742 if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) { 33743 this.#uiManager.removeDeletedAnnotationElement(editor); 33744 } 33745 } 33746 detach(editor) { 33747 this.#editors.delete(editor.id); 33748 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 33749 if (!this.#isDisabling && editor.annotationElementId) { 33750 this.#uiManager.addDeletedAnnotationElement(editor); 33751 } 33752 } 33753 remove(editor) { 33754 this.detach(editor); 33755 this.#uiManager.removeEditor(editor); 33756 editor.div.remove(); 33757 editor.isAttachedToDOM = false; 33758 } 33759 changeParent(editor) { 33760 if (editor.parent === this) { 33761 return; 33762 } 33763 if (editor.parent && editor.annotationElementId) { 33764 this.#uiManager.addDeletedAnnotationElement(editor); 33765 AnnotationEditor.deleteAnnotationElement(editor); 33766 editor.annotationElementId = null; 33767 } 33768 this.attach(editor); 33769 editor.parent?.detach(editor); 33770 editor.setParent(this); 33771 if (editor.div && editor.isAttachedToDOM) { 33772 editor.div.remove(); 33773 this.div.append(editor.div); 33774 } 33775 } 33776 add(editor) { 33777 if (editor.parent === this && editor.isAttachedToDOM) { 33778 return; 33779 } 33780 this.changeParent(editor); 33781 this.#uiManager.addEditor(editor); 33782 this.attach(editor); 33783 if (!editor.isAttachedToDOM) { 33784 const div = editor.render(); 33785 this.div.append(div); 33786 editor.isAttachedToDOM = true; 33787 } 33788 editor.fixAndSetPosition(); 33789 editor.onceAdded(!this.#isEnabling); 33790 this.#uiManager.addToAnnotationStorage(editor); 33791 editor._reportTelemetry(editor.telemetryInitialData); 33792 } 33793 moveEditorInDOM(editor) { 33794 if (!editor.isAttachedToDOM) { 33795 return; 33796 } 33797 const { 33798 activeElement 33799 } = document; 33800 if (editor.div.contains(activeElement) && !this.#editorFocusTimeoutId) { 33801 editor._focusEventsAllowed = false; 33802 this.#editorFocusTimeoutId = setTimeout(() => { 33803 this.#editorFocusTimeoutId = null; 33804 if (!editor.div.contains(document.activeElement)) { 33805 editor.div.addEventListener("focusin", () => { 33806 editor._focusEventsAllowed = true; 33807 }, { 33808 once: true, 33809 signal: this.#uiManager._signal 33810 }); 33811 activeElement.focus(); 33812 } else { 33813 editor._focusEventsAllowed = true; 33814 } 33815 }, 0); 33816 } 33817 editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true); 33818 } 33819 addOrRebuild(editor) { 33820 if (editor.needsToBeRebuilt()) { 33821 editor.parent ||= this; 33822 editor.rebuild(); 33823 editor.show(); 33824 } else { 33825 this.add(editor); 33826 } 33827 } 33828 addUndoableEditor(editor) { 33829 const cmd = () => editor._uiManager.rebuild(editor); 33830 const undo = () => { 33831 editor.remove(); 33832 }; 33833 this.addCommands({ 33834 cmd, 33835 undo, 33836 mustExec: false 33837 }); 33838 } 33839 getEditorByUID(uid) { 33840 for (const editor of this.#editors.values()) { 33841 if (editor.uid === uid) { 33842 return editor; 33843 } 33844 } 33845 return null; 33846 } 33847 get #currentEditorType() { 33848 return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode()); 33849 } 33850 combinedSignal(ac) { 33851 return this.#uiManager.combinedSignal(ac); 33852 } 33853 #createNewEditor(params) { 33854 const editorType = this.#currentEditorType; 33855 return editorType ? new editorType.prototype.constructor(params) : null; 33856 } 33857 canCreateNewEmptyEditor() { 33858 return this.#currentEditorType?.canCreateNewEmptyEditor(); 33859 } 33860 async pasteEditor(options, params) { 33861 this.updateToolbar(options); 33862 await this.#uiManager.updateMode(options.mode); 33863 const { 33864 offsetX, 33865 offsetY 33866 } = this.#getCenterPoint(); 33867 const id = this.#uiManager.getId(); 33868 const editor = this.#createNewEditor({ 33869 parent: this, 33870 id, 33871 x: offsetX, 33872 y: offsetY, 33873 uiManager: this.#uiManager, 33874 isCentered: true, 33875 ...params 33876 }); 33877 if (editor) { 33878 this.add(editor); 33879 } 33880 } 33881 async deserialize(data) { 33882 return (await AnnotationEditorLayer.#editorTypes.get(data.annotationType ?? data.annotationEditorType)?.deserialize(data, this, this.#uiManager)) || null; 33883 } 33884 createAndAddNewEditor(event, isCentered, data = {}) { 33885 const id = this.#uiManager.getId(); 33886 const editor = this.#createNewEditor({ 33887 parent: this, 33888 id, 33889 x: event.offsetX, 33890 y: event.offsetY, 33891 uiManager: this.#uiManager, 33892 isCentered, 33893 ...data 33894 }); 33895 if (editor) { 33896 this.add(editor); 33897 } 33898 return editor; 33899 } 33900 get boundingClientRect() { 33901 return this.div.getBoundingClientRect(); 33902 } 33903 #getCenterPoint() { 33904 const { 33905 x, 33906 y, 33907 width, 33908 height 33909 } = this.boundingClientRect; 33910 const tlX = Math.max(0, x); 33911 const tlY = Math.max(0, y); 33912 const brX = Math.min(window.innerWidth, x + width); 33913 const brY = Math.min(window.innerHeight, y + height); 33914 const centerX = (tlX + brX) / 2 - x; 33915 const centerY = (tlY + brY) / 2 - y; 33916 const [offsetX, offsetY] = this.viewport.rotation % 180 === 0 ? [centerX, centerY] : [centerY, centerX]; 33917 return { 33918 offsetX, 33919 offsetY 33920 }; 33921 } 33922 addNewEditor(data = {}) { 33923 this.createAndAddNewEditor(this.#getCenterPoint(), true, data); 33924 } 33925 setSelected(editor) { 33926 this.#uiManager.setSelected(editor); 33927 } 33928 toggleSelected(editor) { 33929 this.#uiManager.toggleSelected(editor); 33930 } 33931 unselect(editor) { 33932 this.#uiManager.unselect(editor); 33933 } 33934 pointerup(event) { 33935 const { 33936 isMac 33937 } = FeatureTest.platform; 33938 if (event.button !== 0 || event.ctrlKey && isMac) { 33939 return; 33940 } 33941 if (event.target !== this.div) { 33942 return; 33943 } 33944 if (!this.#hadPointerDown) { 33945 return; 33946 } 33947 this.#hadPointerDown = false; 33948 if (this.#currentEditorType?.isDrawer && this.#currentEditorType.supportMultipleDrawings) { 33949 return; 33950 } 33951 if (!this.#allowClick) { 33952 this.#allowClick = true; 33953 return; 33954 } 33955 const currentMode = this.#uiManager.getMode(); 33956 if (currentMode === AnnotationEditorType.STAMP || currentMode === AnnotationEditorType.POPUP || currentMode === AnnotationEditorType.SIGNATURE) { 33957 this.#uiManager.unselectAll(); 33958 return; 33959 } 33960 this.createAndAddNewEditor(event, false); 33961 } 33962 pointerdown(event) { 33963 if (this.#uiManager.getMode() === AnnotationEditorType.HIGHLIGHT) { 33964 this.enableTextSelection(); 33965 } 33966 if (this.#hadPointerDown) { 33967 this.#hadPointerDown = false; 33968 return; 33969 } 33970 const { 33971 isMac 33972 } = FeatureTest.platform; 33973 if (event.button !== 0 || event.ctrlKey && isMac) { 33974 return; 33975 } 33976 if (event.target !== this.div) { 33977 return; 33978 } 33979 this.#hadPointerDown = true; 33980 if (this.#currentEditorType?.isDrawer) { 33981 this.startDrawingSession(event); 33982 return; 33983 } 33984 const editor = this.#uiManager.getActive(); 33985 this.#allowClick = !editor || editor.isEmpty(); 33986 } 33987 startDrawingSession(event) { 33988 this.div.focus({ 33989 preventScroll: true 33990 }); 33991 if (this.#drawingAC) { 33992 this.#currentEditorType.startDrawing(this, this.#uiManager, false, event); 33993 return; 33994 } 33995 this.#uiManager.setCurrentDrawingSession(this); 33996 this.#drawingAC = new AbortController(); 33997 const signal = this.#uiManager.combinedSignal(this.#drawingAC); 33998 this.div.addEventListener("blur", ({ 33999 relatedTarget 34000 }) => { 34001 if (relatedTarget && !this.div.contains(relatedTarget)) { 34002 this.#focusedElement = null; 34003 this.commitOrRemove(); 34004 } 34005 }, { 34006 signal 34007 }); 34008 this.#currentEditorType.startDrawing(this, this.#uiManager, false, event); 34009 } 34010 pause(on) { 34011 if (on) { 34012 const { 34013 activeElement 34014 } = document; 34015 if (this.div.contains(activeElement)) { 34016 this.#focusedElement = activeElement; 34017 } 34018 return; 34019 } 34020 if (this.#focusedElement) { 34021 setTimeout(() => { 34022 this.#focusedElement?.focus(); 34023 this.#focusedElement = null; 34024 }, 0); 34025 } 34026 } 34027 endDrawingSession(isAborted = false) { 34028 if (!this.#drawingAC) { 34029 return null; 34030 } 34031 this.#uiManager.setCurrentDrawingSession(null); 34032 this.#drawingAC.abort(); 34033 this.#drawingAC = null; 34034 this.#focusedElement = null; 34035 return this.#currentEditorType.endDrawing(isAborted); 34036 } 34037 findNewParent(editor, x, y) { 34038 const layer = this.#uiManager.findParent(x, y); 34039 if (layer === null || layer === this) { 34040 return false; 34041 } 34042 layer.changeParent(editor); 34043 return true; 34044 } 34045 commitOrRemove() { 34046 if (this.#drawingAC) { 34047 this.endDrawingSession(); 34048 return true; 34049 } 34050 return false; 34051 } 34052 onScaleChanging() { 34053 if (!this.#drawingAC) { 34054 return; 34055 } 34056 this.#currentEditorType.onScaleChangingWhenDrawing(this); 34057 } 34058 destroy() { 34059 this.commitOrRemove(); 34060 if (this.#uiManager.getActive()?.parent === this) { 34061 this.#uiManager.commitOrRemove(); 34062 this.#uiManager.setActiveEditor(null); 34063 } 34064 if (this.#editorFocusTimeoutId) { 34065 clearTimeout(this.#editorFocusTimeoutId); 34066 this.#editorFocusTimeoutId = null; 34067 } 34068 for (const editor of this.#editors.values()) { 34069 this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); 34070 editor.setParent(null); 34071 editor.isAttachedToDOM = false; 34072 editor.div.remove(); 34073 } 34074 this.div = null; 34075 this.#editors.clear(); 34076 this.#uiManager.removeLayer(this); 34077 } 34078 #cleanup() { 34079 for (const editor of this.#editors.values()) { 34080 if (editor.isEmpty()) { 34081 editor.remove(); 34082 } 34083 } 34084 } 34085 async render({ 34086 viewport 34087 }) { 34088 this.viewport = viewport; 34089 setLayerDimensions(this.div, viewport); 34090 for (const editor of this.#uiManager.getEditors(this.pageIndex)) { 34091 this.add(editor); 34092 editor.rebuild(); 34093 } 34094 await this.#uiManager.findClonesForPage(this); 34095 this.div.hidden = this.isEmpty; 34096 this.updateMode(); 34097 } 34098 update({ 34099 viewport 34100 }) { 34101 this.#uiManager.commitOrRemove(); 34102 this.#cleanup(); 34103 const oldRotation = this.viewport.rotation; 34104 const rotation = viewport.rotation; 34105 this.viewport = viewport; 34106 setLayerDimensions(this.div, { 34107 rotation 34108 }); 34109 if (oldRotation !== rotation) { 34110 for (const editor of this.#editors.values()) { 34111 editor.rotate(rotation); 34112 } 34113 } 34114 } 34115 get pageDimensions() { 34116 const { 34117 pageWidth, 34118 pageHeight 34119 } = this.viewport.rawDims; 34120 return [pageWidth, pageHeight]; 34121 } 34122 get scale() { 34123 return this.#uiManager.viewParameters.realScale; 34124 } 34125} 34126
34127// EXTERNAL MODULE: ./node_modules/core-js/modules/es.iterator.to-array.js 34128var es_iterator_to_array = __webpack_require__(1806); 34129;// ./src/display/draw_layer.js 34130 34131 34132 34133 34134 34135 34136 34137 34138 34139 34140 34141 34142 34143 34144
vendor: 25,094 bytes, lines 34145-34918
34145 34146 34147 34148function compareTextLayers(a, b) { 34149 if (a === b) { 34150 return 0; 34151 } 34152 return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1; 34153} 34154function getTextLayer(node) { 34155 if (!node) { 34156 return null; 34157 } 34158 if (node.nodeType === Node.ELEMENT_NODE) { 34159 return node.closest(".textLayer"); 34160 } 34161 return node.parentElement?.closest(".textLayer") || null; 34162} 34163function isPointBefore(nodeA, offsetA, nodeB, offsetB) { 34164 if (nodeA === nodeB) { 34165 return offsetA <= offsetB; 34166 } 34167 const relation = nodeA.compareDocumentPosition(nodeB); 34168 if (relation & Node.DOCUMENT_POSITION_FOLLOWING) { 34169 return true; 34170 } 34171 if (relation & Node.DOCUMENT_POSITION_PRECEDING) { 34172 return false; 34173 } 34174 return null; 34175} 34176function normalizeEdgeBoundary(container, offset, textLayer) { 34177 if (container.nodeType !== Node.ELEMENT_NODE || !container.classList.contains("textLayer") || offset !== container.childNodes.length) { 34178 return { 34179 container, 34180 offset 34181 }; 34182 } 34183 let lastNode = container.lastChild; 34184 if (lastNode?.nodeType === Node.ELEMENT_NODE && lastNode.classList.contains("endOfContent")) { 34185 lastNode = lastNode.previousSibling; 34186 } 34187 if (!lastNode || !textLayer.contains(lastNode)) { 34188 return null; 34189 } 34190 if (lastNode.nodeType === Node.TEXT_NODE) { 34191 return { 34192 container: lastNode, 34193 offset: lastNode.textContent.length 34194 }; 34195 } 34196 return { 34197 container: lastNode, 34198 offset: lastNode.childNodes.length 34199 }; 34200} 34201class DrawLayer { 34202 #parent = null; 34203 #mapping = new Map(); 34204 #textLayer = null; 34205 #filterFactory = null; 34206 #pageColors = null; 34207 #textLayerObserver = null; 34208 #toUpdate = new Map(); 34209 static #id = 0; 34210 static #selectionId = 0; 34211 static #selectionChangeAC = null; 34212 static #selections = new Set(); 34213 static #isSelecting = false; 34214 static #textLayerSet = new Set(); 34215 static #textLayers = new WeakMap(); 34216 constructor({ 34217 filterFactory = null, 34218 pageColors = null, 34219 pageIndex, 34220 textLayer = null 34221 }) { 34222 this.pageIndex = pageIndex; 34223 this.#filterFactory = filterFactory; 34224 this.#pageColors = pageColors; 34225 if (textLayer) { 34226 const previousData = DrawLayer.#textLayers.get(textLayer); 34227 if (previousData?.selectionDiv) { 34228 previousData.selectionDiv.remove(); 34229 DrawLayer.#selections.delete(previousData.selectionDiv); 34230 } 34231 DrawLayer.#textLayers.set(textLayer, { 34232 drawLayer: this 34233 }); 34234 DrawLayer.#textLayerSet.add(textLayer); 34235 this.#textLayer = textLayer; 34236 this.#textLayerObserver = new MutationObserver(records => { 34237 if (!this.#parent || !this.#textLayer?.isConnected || !DrawLayer.#hasSelection()) { 34238 return; 34239 } 34240 for (const { 34241 addedNodes 34242 } of records) { 34243 for (const node of addedNodes) { 34244 if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains("endOfContent")) { 34245 DrawLayer.#selectionChange(); 34246 return; 34247 } 34248 } 34249 } 34250 }); 34251 this.#textLayerObserver.observe(textLayer, { 34252 childList: true 34253 }); 34254 if (DrawLayer.#selectionChangeAC === null) { 34255 DrawLayer.#selectionChangeAC = new AbortController(); 34256 const { 34257 signal 34258 } = DrawLayer.#selectionChangeAC; 34259 document.addEventListener("selectionchange", DrawLayer.#selectionChange.bind(DrawLayer), { 34260 signal 34261 }); 34262 document.addEventListener("pointerdown", () => { 34263 DrawLayer.#isSelecting = true; 34264 }, { 34265 signal 34266 }); 34267 document.addEventListener("pointerup", () => { 34268 DrawLayer.#isSelecting = false; 34269 }, { 34270 signal 34271 }); 34272 window.addEventListener("blur", () => { 34273 DrawLayer.#isSelecting = false; 34274 }, { 34275 signal 34276 }); 34277 } 34278 } 34279 } 34280 setParent(parent) { 34281 if (!this.#parent) { 34282 this.#parent = parent; 34283 if (this.#textLayer?.isConnected && DrawLayer.#hasSelection()) { 34284 DrawLayer.#selectionChange(); 34285 } 34286 return; 34287 } 34288 if (this.#parent !== parent) { 34289 if (this.#mapping.size > 0) { 34290 for (const root of this.#mapping.values()) { 34291 root.remove(); 34292 parent.append(root); 34293 } 34294 } 34295 this.#parent = parent; 34296 } 34297 } 34298 static #cleanupTextLayerSelection(textLayer) { 34299 const textLayerData = this.#textLayers.get(textLayer); 34300 if (!textLayerData?.selectionDiv) { 34301 return; 34302 } 34303 textLayerData.selectionDiv.remove(); 34304 this.#selections.delete(textLayerData.selectionDiv); 34305 textLayerData.selectionDiv = null; 34306 textLayerData.path = null; 34307 } 34308 static #hasSelection() { 34309 const selection = document.getSelection(); 34310 return !!selection && !selection.isCollapsed; 34311 } 34312 static #getOrderedTextLayers() { 34313 return this.#textLayerSet.keys().filter(textLayer => textLayer.isConnected).toArray().sort(compareTextLayers); 34314 } 34315 static #selectionChange() { 34316 const selection = document.getSelection(); 34317 if (!selection || selection.isCollapsed) { 34318 for (const root of this.#selections) { 34319 root.remove(); 34320 } 34321 this.#selections.clear(); 34322 return; 34323 } 34324 const rotators = new WeakMap(); 34325 const orderedTextLayers = this.#getOrderedTextLayers(); 34326 const ranges = []; 34327 for (let i = 0, ii = selection.rangeCount; i < ii; i++) { 34328 const range = selection.getRangeAt(i); 34329 if (range.collapsed) { 34330 continue; 34331 } 34332 let { 34333 startContainer, 34334 startOffset, 34335 endContainer, 34336 endOffset 34337 } = range; 34338 let startTextLayer = getTextLayer(startContainer); 34339 let endTextLayer = getTextLayer(endContainer); 34340 const startMissing = startTextLayer === null; 34341 const endMissing = endTextLayer === null; 34342 if (this.#isSelecting && startMissing !== endMissing) { 34343 return; 34344 } 34345 if (selection.rangeCount === 1) { 34346 const { 34347 anchorNode, 34348 anchorOffset, 34349 focusNode, 34350 focusOffset 34351 } = selection; 34352 const anchorLayer = getTextLayer(anchorNode); 34353 const focusLayer = getTextLayer(focusNode); 34354 const anchorBeforeFocus = isPointBefore(anchorNode, anchorOffset, focusNode, focusOffset); 34355 if (anchorLayer && focusLayer && anchorBeforeFocus !== null) { 34356 if (anchorBeforeFocus) { 34357 startContainer = anchorNode; 34358 startOffset = anchorOffset; 34359 startTextLayer = anchorLayer; 34360 endContainer = focusNode; 34361 endOffset = focusOffset; 34362 endTextLayer = focusLayer; 34363 } else { 34364 startContainer = focusNode; 34365 startOffset = focusOffset; 34366 startTextLayer = focusLayer; 34367 endContainer = anchorNode; 34368 endOffset = anchorOffset; 34369 endTextLayer = anchorLayer; 34370 } 34371 } 34372 } 34373 const activeTextLayers = orderedTextLayers.filter(textLayer => range.intersectsNode(textLayer)); 34374 if (activeTextLayers.length === 0) { 34375 continue; 34376 } 34377 let boundarySubstituted = false; 34378 if (!startTextLayer) { 34379 startTextLayer = activeTextLayers[0]; 34380 startContainer = startTextLayer; 34381 startOffset = 0; 34382 boundarySubstituted = true; 34383 } 34384 if (!endTextLayer) { 34385 endTextLayer = activeTextLayers.at(-1); 34386 endContainer = endTextLayer; 34387 endOffset = endTextLayer.childNodes.length; 34388 boundarySubstituted = true; 34389 } 34390 if (endContainer.nodeType === Node.ELEMENT_NODE) { 34391 if (endContainer.classList.contains("endOfContent")) { 34392 const previousNode = endContainer.previousSibling; 34393 if (!previousNode) { 34394 continue; 34395 } 34396 endContainer = previousNode; 34397 endOffset = previousNode.nodeType === Node.TEXT_NODE ? previousNode.textContent.length : previousNode.childNodes.length; 34398 } else if (endContainer.classList.contains("textLayer") && endContainer.childNodes.length === endOffset) { 34399 const normalizedEnd = normalizeEdgeBoundary(endContainer, endOffset, endTextLayer); 34400 if (!normalizedEnd) { 34401 continue; 34402 } 34403 endContainer = normalizedEnd.container; 34404 endOffset = normalizedEnd.offset; 34405 } 34406 } 34407 if (startContainer.nodeType === Node.ELEMENT_NODE) { 34408 const normalizedStart = normalizeEdgeBoundary(startContainer, startOffset, startTextLayer); 34409 if (!normalizedStart) { 34410 continue; 34411 } 34412 startContainer = normalizedStart.container; 34413 startOffset = normalizedStart.offset; 34414 } 34415 if (startTextLayer === endTextLayer && !boundarySubstituted && activeTextLayers.includes(startTextLayer)) { 34416 ranges.push([range, startTextLayer]); 34417 continue; 34418 } 34419 for (const textLayer of activeTextLayers) { 34420 const firstNode = textLayer.firstChild; 34421 if (!firstNode) { 34422 continue; 34423 } 34424 const subRange = document.createRange(); 34425 if (textLayer === startTextLayer) { 34426 subRange.setStart(startContainer, startOffset); 34427 } else { 34428 subRange.setStartBefore(firstNode); 34429 } 34430 if (textLayer === endTextLayer) { 34431 subRange.setEnd(endContainer, endOffset); 34432 } else { 34433 const lastNode = textLayer.lastChild; 34434 if (!lastNode) { 34435 continue; 34436 } 34437 if (lastNode.nodeType === Node.ELEMENT_NODE && lastNode.classList.contains("endOfContent")) { 34438 const lastTextNode = lastNode.previousSibling; 34439 if (!lastTextNode) { 34440 continue; 34441 } 34442 subRange.setEndAfter(lastTextNode); 34443 } else { 34444 subRange.setEndAfter(lastNode); 34445 } 34446 } 34447 if (!subRange.collapsed) { 34448 ranges.push([subRange, textLayer]); 34449 } 34450 } 34451 } 34452 const selectedTextLayers = new Set(ranges.map(range => range[1])); 34453 for (const textLayer of this.#textLayerSet) { 34454 if (!selectedTextLayers.has(textLayer)) { 34455 this.#cleanupTextLayerSelection(textLayer); 34456 } 34457 } 34458 for (const [range, textLayer] of ranges) { 34459 const textLayerData = DrawLayer.#textLayers.get(textLayer); 34460 if (!textLayerData) { 34461 continue; 34462 } 34463 let rotator = rotators.get(textLayer); 34464 if (!rotator) { 34465 const clientRect = textLayer.getBoundingClientRect(); 34466 rotator = (x, y, w, h) => ({ 34467 x: (x - clientRect.x) / clientRect.width, 34468 y: (y - clientRect.y) / clientRect.height, 34469 width: w / clientRect.width, 34470 height: h / clientRect.height 34471 }); 34472 rotators.set(textLayer, rotator); 34473 } 34474 const boxes = []; 34475 for (let { 34476 x, 34477 y, 34478 width, 34479 height 34480 } of range.getClientRects()) { 34481 if (width === 0 || height === 0) { 34482 continue; 34483 } 34484 ({ 34485 x, 34486 y, 34487 width, 34488 height 34489 } = rotator(x, y, width, height)); 34490 if (width === 1 && height === 1) { 34491 continue; 34492 } 34493 boxes.push(`M${x} ${y} h${width} v${height} h-${width} Z`); 34494 } 34495 if (boxes.length === 0) { 34496 continue; 34497 } 34498 const drawLayer = textLayerData.drawLayer; 34499 let div = textLayerData.selectionDiv; 34500 let path = textLayerData.path; 34501 if (!div) { 34502 const clipPathId = `clip_selection_${DrawLayer.#selectionId++}`; 34503 div = document.createElement("div"); 34504 div.className = "selection"; 34505 div.style.clipPath = `url(#${clipPathId})`; 34506 const selectionStyle = drawLayer.#filterFactory?.createSelectionStyle(drawLayer.#pageColors); 34507 if (selectionStyle) { 34508 for (const [name, value] of Object.entries(selectionStyle)) { 34509 div.style.setProperty(name, value); 34510 } 34511 } 34512 const svg = DrawLayer._svgFactory.create(1, 1, true); 34513 svg.setAttribute("aria-hidden", "true"); 34514 svg.setAttribute("width", "100%"); 34515 svg.setAttribute("height", "100%"); 34516 const clipPath = DrawLayer._svgFactory.createElement("clipPath"); 34517 clipPath.setAttribute("id", clipPathId); 34518 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 34519 path = DrawLayer._svgFactory.createElement("path"); 34520 clipPath.append(path); 34521 svg.append(clipPath); 34522 div.append(svg); 34523 textLayerData.path = path; 34524 textLayerData.selectionDiv = div; 34525 } 34526 if (drawLayer.#parent && div.parentNode !== drawLayer.#parent) { 34527 drawLayer.#parent.append(div); 34528 this.#selections.add(div); 34529 } 34530 path.setAttribute("d", boxes.join(" ")); 34531 } 34532 } 34533 static get _svgFactory() { 34534 return shadow(this, "_svgFactory", new DOMSVGFactory()); 34535 } 34536 static #setBox(element, [x, y, width, height]) { 34537 const { 34538 style 34539 } = element; 34540 style.top = `${100 * y}%`; 34541 style.left = `${100 * x}%`; 34542 style.width = `${100 * width}%`; 34543 style.height = `${100 * height}%`; 34544 } 34545 #createSVG() { 34546 const svg = DrawLayer._svgFactory.create(1, 1, true); 34547 this.#parent.append(svg); 34548 svg.setAttribute("aria-hidden", "true"); 34549 return svg; 34550 } 34551 #createClipPath(defs, pathId) { 34552 const clipPath = DrawLayer._svgFactory.createElement("clipPath"); 34553 defs.append(clipPath); 34554 const clipPathId = `clip_${pathId}`; 34555 clipPath.setAttribute("id", clipPathId); 34556 clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); 34557 const clipPathUse = DrawLayer._svgFactory.createElement("use"); 34558 clipPath.append(clipPathUse); 34559 clipPathUse.setAttribute("href", `#${pathId}`); 34560 clipPathUse.classList.add("clip"); 34561 return clipPathId; 34562 } 34563 #updateProperties(element, properties) { 34564 for (const [key, value] of Object.entries(properties)) { 34565 if (value === null) { 34566 element.removeAttribute(key); 34567 } else { 34568 element.setAttribute(key, value); 34569 } 34570 } 34571 } 34572 draw(properties, isPathUpdatable = false, hasClip = false) { 34573 const id = DrawLayer.#id++; 34574 const root = this.#createSVG(); 34575 const defs = DrawLayer._svgFactory.createElement("defs"); 34576 root.append(defs); 34577 const path = DrawLayer._svgFactory.createElement("path"); 34578 defs.append(path); 34579 const pathId = `path_${id}`; 34580 path.setAttribute("id", pathId); 34581 path.setAttribute("vector-effect", "non-scaling-stroke"); 34582 if (isPathUpdatable) { 34583 this.#toUpdate.set(id, path); 34584 } 34585 const clipPathId = hasClip ? this.#createClipPath(defs, pathId) : null; 34586 const use = DrawLayer._svgFactory.createElement("use"); 34587 root.append(use); 34588 use.setAttribute("href", `#${pathId}`); 34589 this.updateProperties(root, properties); 34590 this.#mapping.set(id, root); 34591 return { 34592 id, 34593 clipPathId: `url(#${clipPathId})` 34594 }; 34595 } 34596 drawOutline(properties, mustRemoveSelfIntersections) { 34597 const id = DrawLayer.#id++; 34598 const root = this.#createSVG(); 34599 const defs = DrawLayer._svgFactory.createElement("defs"); 34600 root.append(defs); 34601 const path = DrawLayer._svgFactory.createElement("path"); 34602 defs.append(path); 34603 const pathId = `path_${id}`; 34604 path.setAttribute("id", pathId); 34605 path.setAttribute("vector-effect", "non-scaling-stroke"); 34606 let maskId; 34607 if (mustRemoveSelfIntersections) { 34608 const mask = DrawLayer._svgFactory.createElement("mask"); 34609 defs.append(mask); 34610 maskId = `mask_${id}`; 34611 mask.setAttribute("id", maskId); 34612 mask.setAttribute("maskUnits", "objectBoundingBox"); 34613 const rect = DrawLayer._svgFactory.createElement("rect"); 34614 mask.append(rect); 34615 rect.setAttribute("width", "1"); 34616 rect.setAttribute("height", "1"); 34617 rect.setAttribute("fill", "white"); 34618 const use = DrawLayer._svgFactory.createElement("use"); 34619 mask.append(use); 34620 use.setAttribute("href", `#${pathId}`); 34621 use.setAttribute("stroke", "none"); 34622 use.setAttribute("fill", "black"); 34623 use.setAttribute("fill-rule", "nonzero"); 34624 use.classList.add("mask"); 34625 } 34626 const use1 = DrawLayer._svgFactory.createElement("use"); 34627 root.append(use1); 34628 use1.setAttribute("href", `#${pathId}`); 34629 if (maskId) { 34630 use1.setAttribute("mask", `url(#${maskId})`); 34631 } 34632 const use2 = use1.cloneNode(); 34633 root.append(use2); 34634 use1.classList.add("mainOutline"); 34635 use2.classList.add("secondaryOutline"); 34636 this.updateProperties(root, properties); 34637 this.#mapping.set(id, root); 34638 return id; 34639 } 34640 finalizeDraw(id, properties) { 34641 this.#toUpdate.delete(id); 34642 this.updateProperties(id, properties); 34643 } 34644 updateProperties(elementOrId, properties) { 34645 if (!properties) { 34646 return; 34647 } 34648 const { 34649 root, 34650 bbox, 34651 rootClass, 34652 path 34653 } = properties; 34654 const element = typeof elementOrId === "number" ? this.#mapping.get(elementOrId) : elementOrId; 34655 if (!element) { 34656 return; 34657 } 34658 if (root) { 34659 this.#updateProperties(element, root); 34660 } 34661 if (bbox) { 34662 DrawLayer.#setBox(element, bbox); 34663 } 34664 if (rootClass) { 34665 const { 34666 classList 34667 } = element; 34668 for (const [className, value] of Object.entries(rootClass)) { 34669 classList.toggle(className, value); 34670 } 34671 } 34672 if (path) { 34673 const defs = element.firstElementChild; 34674 const pathElement = defs.firstElementChild; 34675 this.#updateProperties(pathElement, path); 34676 } 34677 } 34678 updateParent(id, layer) { 34679 if (layer === this) { 34680 return; 34681 } 34682 const root = this.#mapping.get(id); 34683 if (!root) { 34684 return; 34685 } 34686 layer.#parent.append(root); 34687 this.#mapping.delete(id); 34688 layer.#mapping.set(id, root); 34689 } 34690 remove(id) { 34691 this.#toUpdate.delete(id); 34692 if (this.#parent === null) { 34693 return; 34694 } 34695 this.#mapping.get(id).remove(); 34696 this.#mapping.delete(id); 34697 } 34698 destroy() { 34699 this.#parent = null; 34700 for (const root of this.#mapping.values()) { 34701 root.remove(); 34702 } 34703 this.#mapping.clear(); 34704 this.#toUpdate.clear(); 34705 this.#textLayerObserver?.disconnect(); 34706 this.#textLayerObserver = null; 34707 if (this.#textLayer) { 34708 const data = DrawLayer.#textLayers.get(this.#textLayer); 34709 if (data?.drawLayer === this) { 34710 DrawLayer.#cleanupTextLayerSelection(this.#textLayer); 34711 DrawLayer.#textLayers.delete(this.#textLayer); 34712 DrawLayer.#textLayerSet.delete(this.#textLayer); 34713 if (DrawLayer.#textLayerSet.size === 0) { 34714 DrawLayer.#selectionChangeAC?.abort(); 34715 DrawLayer.#selectionChangeAC = null; 34716 DrawLayer.#isSelecting = false; 34717 } 34718 } 34719 this.#textLayer = null; 34720 } 34721 } 34722} 34723 34724;// ./src/display/text_layer_images.js 34725 34726 34727 34728function percentage(value) { 34729 return `${(value * 100).toFixed(2)}%`; 34730} 34731class TextLayerImages { 34732 #coordinates = []; 34733 #coordinatesByElement = new Map(); 34734 #getPageCanvas = null; 34735 #minSize = 0; 34736 #pageWidth = 0; 34737 #pageHeight = 0; 34738 static #activeImage = null; 34739 constructor(minSize, coordinates, viewport, getPageCanvas) { 34740 this.#minSize = minSize; 34741 this.#coordinates = coordinates; 34742 this.#pageWidth = viewport.rawDims.pageWidth; 34743 this.#pageHeight = viewport.rawDims.pageHeight; 34744 this.#getPageCanvas = getPageCanvas; 34745 } 34746 render() { 34747 const container = document.createElement("div"); 34748 container.className = "textLayerImages"; 34749 for (let i = 0; i < this.#coordinates.length; i += 6) { 34750 const el = this.#createImagePlaceholder(this.#coordinates.subarray(i, i + 6)); 34751 if (el) { 34752 container.append(el); 34753 } 34754 } 34755 container.addEventListener("contextmenu", event => { 34756 if (!(event.target instanceof HTMLCanvasElement)) { 34757 return; 34758 } 34759 const imgElement = event.target; 34760 const coords = this.#coordinatesByElement.get(imgElement); 34761 if (!coords) { 34762 return; 34763 } 34764 const activeImage = TextLayerImages.#activeImage?.deref(); 34765 if (activeImage === imgElement) { 34766 return; 34767 } 34768 if (activeImage) { 34769 activeImage.width = 0; 34770 activeImage.height = 0; 34771 } 34772 TextLayerImages.#activeImage = new WeakRef(imgElement); 34773 const { 34774 inverseTransform, 34775 x1, 34776 y1, 34777 width, 34778 height 34779 } = coords; 34780 const pageCanvas = this.#getPageCanvas(); 34781 const imageX1 = Math.ceil(x1 * pageCanvas.width); 34782 const imageY1 = Math.ceil(y1 * pageCanvas.height); 34783 const imageX2 = Math.floor((x1 + width / this.#pageWidth) * pageCanvas.width); 34784 const imageY2 = Math.floor((y1 + height / this.#pageHeight) * pageCanvas.height); 34785 imgElement.width = imageX2 - imageX1; 34786 imgElement.height = imageY2 - imageY1; 34787 const ctx = imgElement.getContext("2d"); 34788 ctx.setTransform(...inverseTransform); 34789 ctx.translate(-imageX1, -imageY1); 34790 ctx.drawImage(pageCanvas, 0, 0); 34791 }); 34792 return container; 34793 } 34794 #createImagePlaceholder([x1, y1, x2, y2, x3, y3]) { 34795 const width = Math.hypot((x3 - x1) * this.#pageWidth, (y3 - y1) * this.#pageHeight); 34796 const height = Math.hypot((x2 - x1) * this.#pageWidth, (y2 - y1) * this.#pageHeight); 34797 if (width < this.#minSize || height < this.#minSize) { 34798 return null; 34799 } 34800 const transform = [(x3 - x1) * this.#pageWidth / width, (y3 - y1) * this.#pageHeight / width, (x2 - x1) * this.#pageWidth / height, (y2 - y1) * this.#pageHeight / height, 0, 0]; 34801 const inverseTransform = Util.inverseTransform(transform); 34802 const imgElement = document.createElement("canvas"); 34803 imgElement.className = "textLayerImagePlaceholder"; 34804 imgElement.width = 0; 34805 imgElement.height = 0; 34806 Object.assign(imgElement.style, { 34807 opacity: 0, 34808 position: "absolute", 34809 left: percentage(x1), 34810 top: percentage(y1), 34811 width: percentage(width / this.#pageWidth), 34812 height: percentage(height / this.#pageHeight), 34813 transformOrigin: "0% 0%", 34814 transform: `matrix(${transform.join(",")})` 34815 }); 34816 this.#coordinatesByElement.set(imgElement, { 34817 inverseTransform, 34818 width, 34819 height, 34820 x1, 34821 y1 34822 }); 34823 return imgElement; 34824 } 34825} 34826 34827;// ./src/pdf.js 34828 34829 34830 34831 34832 34833 34834 34835 34836 34837 34838 34839 34840 34841 34842 34843 34844 34845 34846{ 34847 globalThis._pdfjsTestingUtils = { 34848 HighlightOutliner: HighlightOutliner 34849 }; 34850} 34851globalThis.pdfjsLib = { 34852 AbortException: AbortException, 34853 AnnotationEditorLayer: AnnotationEditorLayer, 34854 AnnotationEditorParamsType: AnnotationEditorParamsType, 34855 AnnotationEditorType: AnnotationEditorType, 34856 AnnotationEditorUIManager: AnnotationEditorUIManager, 34857 AnnotationLayer: AnnotationLayer, 34858 AnnotationMode: AnnotationMode, 34859 AnnotationType: AnnotationType, 34860 applyOpacity: applyOpacity, 34861 build: build, 34862 ColorPicker: ColorPicker, 34863 createValidAbsoluteUrl: createValidAbsoluteUrl, 34864 CSSConstants: CSSConstants, 34865 DOMSVGFactory: DOMSVGFactory, 34866 DrawLayer: DrawLayer, 34867 FeatureTest: FeatureTest, 34868 fetchData: fetchData, 34869 findContrastColor: findContrastColor, 34870 getDocument: getDocument, 34871 getFilenameFromUrl: getFilenameFromUrl, 34872 getPdfFilenameFromUrl: getPdfFilenameFromUrl, 34873 getRGB: getRGB, 34874 getRGBA: getRGBA, 34875 getUuid: getUuid, 34876 GlobalWorkerOptions: GlobalWorkerOptions, 34877 ImageKind: ImageKind, 34878 InvalidPDFException: InvalidPDFException, 34879 isDataScheme: isDataScheme, 34880 isPdfFile: isPdfFile, 34881 isValidExplicitDest: isValidExplicitDest, 34882 makeArr: makeArr, 34883 makeMap: makeMap, 34884 makeObj: makeObj, 34885 makeSet: makeSet, 34886 MathClamp: MathClamp, 34887 noContextMenu: noContextMenu, 34888 normalizeUnicode: normalizeUnicode, 34889 OPS: OPS, 34890 OutputScale: OutputScale, 34891 PasswordException: PasswordException, 34892 PasswordResponses: PasswordResponses, 34893 PDFDataRangeTransport: PDFDataRangeTransport, 34894 PDFDateString: PDFDateString, 34895 PDFWorker: PDFWorker, 34896 PermissionFlag: PermissionFlag, 34897 PixelsPerInch: PixelsPerInch, 34898 RenderingCancelledException: RenderingCancelledException, 34899 renderRichText: renderRichText, 34900 ResponseException: ResponseException, 34901 setLayerDimensions: setLayerDimensions, 34902 shadow: shadow, 34903 SignatureExtractor: SignatureExtractor, 34904 stopEvent: stopEvent, 34905 SupportedImageMimeTypes: SupportedImageMimeTypes, 34906 TextLayer: TextLayer, 34907 TextLayerImages: TextLayerImages, 34908 TouchManager: TouchManager, 34909 updateUrlHash: updateUrlHash, 34910 Util: Util, 34911 VerbosityLevel: VerbosityLevel, 34912 version: version, 34913 XfaLayer: XfaLayer 34914}; 34915 34916export { AbortException, AnnotationEditorLayer, AnnotationEditorParamsType, AnnotationEditorType, AnnotationEditorUIManager, AnnotationLayer, AnnotationMode, AnnotationType, CSSConstants, ColorPicker, DOMSVGFactory, DrawLayer, FeatureTest, GlobalWorkerOptions, ImageKind, InvalidPDFException, MathClamp, OPS, OutputScale, PDFDataRangeTransport, PDFDateString, PDFWorker, PasswordException, PasswordResponses, PermissionFlag, PixelsPerInch, RenderingCancelledException, ResponseException, SignatureExtractor, SupportedImageMimeTypes, TextLayer, TextLayerImages, TouchManager, Util, VerbosityLevel, XfaLayer, applyOpacity, build, createValidAbsoluteUrl, fetchData, findContrastColor, getDocument, getFilenameFromUrl, getPdfFilenameFromUrl, getRGB, getRGBA, getUuid, isDataScheme, isPdfFile, isValidExplicitDest, makeArr, makeMap, makeObj, makeSet, noContextMenu, normalizeUnicode, renderRichText, setLayerDimensions, shadow, stopEvent, updateUrlHash, version }; 34917 34918//# sourceMappingURL=pdf.mjs.map
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.