Fix File
•
/
home
/
sportsfe...
/
httpdocs
/
wp-conte...
/
plugins
/
embedpre...
/
assets
/
pdf
/
build
•
File:
script.js
•
Content:
} render() { this.container.classList.add("fileAttachmentAnnotation"); const { container, data } = this; let trigger; if (data.hasAppearance || data.fillAlpha === 0) { trigger = document.createElement("div"); } else { trigger = document.createElement("img"); trigger.src = `${this.imageResourcesPath}annotation-${/paperclip/i.test(data.name) ? "paperclip" : "pushpin"}.svg`; if (data.fillAlpha && data.fillAlpha < 1) { trigger.style = `filter: opacity(${Math.round(data.fillAlpha * 100)}%);`; } } trigger.addEventListener("dblclick", this.#download.bind(this)); this.#trigger = trigger; const { isMac } = util_FeatureTest.platform; container.addEventListener("keydown", evt => { if (evt.key === "Enter" && (isMac ? evt.metaKey : evt.ctrlKey)) { this.#download(); } }); if (!data.popupRef && this.hasPopupData) { this._createPopup(); } else { trigger.classList.add("popupTriggerArea"); } container.append(trigger); return container; } getElementsToTriggerPopup() { return this.#trigger; } addHighlightArea() { this.container.classList.add("highlightArea"); } #download() { this.downloadManager?.openOrDownloadData(this.content, this.filename); } } class AnnotationLayer { #accessibilityManager = null; #annotationCanvasMap = null; #editableAnnotations = new Map(); constructor({ div, accessibilityManager, annotationCanvasMap, annotationEditorUIManager, page, viewport }) { this.div = div; this.#accessibilityManager = accessibilityManager; this.#annotationCanvasMap = annotationCanvasMap; this.page = page; this.viewport = viewport; this.zIndex = 0; this._annotationEditorUIManager = annotationEditorUIManager; } #appendElement(element, id) { const contentElement = element.firstChild || element; contentElement.id = `${AnnotationPrefix}${id}`; this.div.append(element); this.#accessibilityManager?.moveElementInDOM(this.div, element, contentElement, false); } async render(params) { const { annotations } = params; const layer = this.div; setLayerDimensions(layer, this.viewport); const popupToElements = new Map(); const elementParams = { data: null, layer, linkService: params.linkService, downloadManager: params.downloadManager, imageResourcesPath: params.imageResourcesPath || "", renderForms: params.renderForms !== false, svgFactory: new DOMSVGFactory(), annotationStorage: params.annotationStorage || new AnnotationStorage(), enableScripting: params.enableScripting === true, hasJSActions: params.hasJSActions, fieldObjects: params.fieldObjects, parent: this, elements: null }; for (const data of annotations) { if (data.noHTML) { continue; } const isPopupAnnotation = data.annotationType === AnnotationType.POPUP; if (!isPopupAnnotation) { const { width, height } = getRectDims(data.rect); if (width <= 0 || height <= 0) { continue; } } else { const elements = popupToElements.get(data.id); if (!elements) { continue; } elementParams.elements = elements; } elementParams.data = data; const element = AnnotationElementFactory.create(elementParams); if (!element.isRenderable) { continue; } if (!isPopupAnnotation && data.popupRef) { const elements = popupToElements.get(data.popupRef); if (!elements) { popupToElements.set(data.popupRef, [element]); } else { elements.push(element); } } const rendered = element.render(); if (data.hidden) { rendered.style.visibility = "hidden"; } this.#appendElement(rendered, data.id); if (element.annotationEditorType > 0) { this.#editableAnnotations.set(element.data.id, element); this._annotationEditorUIManager?.renderAnnotationElement(element); } } this.#setAnnotationCanvasMap(); } update({ viewport }) { const layer = this.div; this.viewport = viewport; setLayerDimensions(layer, { rotation: viewport.rotation }); this.#setAnnotationCanvasMap(); layer.hidden = false; } #setAnnotationCanvasMap() { if (!this.#annotationCanvasMap) { return; } const layer = this.div; for (const [id, canvas] of this.#annotationCanvasMap) { const element = layer.querySelector(`[data-annotation-id="${id}"]`); if (!element) { continue; } canvas.className = "annotationContent"; const { firstChild } = element; if (!firstChild) { element.append(canvas); } else if (firstChild.nodeName === "CANVAS") { firstChild.replaceWith(canvas); } else if (!firstChild.classList.contains("annotationContent")) { firstChild.before(canvas); } else { firstChild.after(canvas); } } this.#annotationCanvasMap.clear(); } getEditableAnnotations() { return Array.from(this.#editableAnnotations.values()); } getEditableAnnotation(id) { return this.#editableAnnotations.get(id); } } ;// CONCATENATED MODULE: ./src/display/editor/freetext.js const EOL_PATTERN = /\r\n?|\n/g; class FreeTextEditor extends AnnotationEditor { #boundEditorDivBlur = this.editorDivBlur.bind(this); #boundEditorDivFocus = this.editorDivFocus.bind(this); #boundEditorDivInput = this.editorDivInput.bind(this); #boundEditorDivKeydown = this.editorDivKeydown.bind(this); #boundEditorDivPaste = this.editorDivPaste.bind(this); #color; #content = ""; #editorDivId = `${this.id}-editor`; #fontSize; #initialData = null; static _freeTextDefaultContent = ""; static _internalPadding = 0; static _defaultColor = null; static _defaultFontSize = 10; static get _keyboardManager() { const proto = FreeTextEditor.prototype; const arrowChecker = self => self.isEmpty(); const small = AnnotationEditorUIManager.TRANSLATE_SMALL; const big = AnnotationEditorUIManager.TRANSLATE_BIG; return shadow(this, "_keyboardManager", new KeyboardManager([[["ctrl+s", "mac+meta+s", "ctrl+p", "mac+meta+p"], proto.commitOrRemove, { bubbles: true }], [["ctrl+Enter", "mac+meta+Enter", "Escape", "mac+Escape"], proto.commitOrRemove], [["ArrowLeft", "mac+ArrowLeft"], proto._translateEmpty, { args: [-small, 0], checker: arrowChecker }], [["ctrl+ArrowLeft", "mac+shift+ArrowLeft"], proto._translateEmpty, { args: [-big, 0], checker: arrowChecker }], [["ArrowRight", "mac+ArrowRight"], proto._translateEmpty, { args: [small, 0], checker: arrowChecker }], [["ctrl+ArrowRight", "mac+shift+ArrowRight"], proto._translateEmpty, { args: [big, 0], checker: arrowChecker }], [["ArrowUp", "mac+ArrowUp"], proto._translateEmpty, { args: [0, -small], checker: arrowChecker }], [["ctrl+ArrowUp", "mac+shift+ArrowUp"], proto._translateEmpty, { args: [0, -big], checker: arrowChecker }], [["ArrowDown", "mac+ArrowDown"], proto._translateEmpty, { args: [0, small], checker: arrowChecker }], [["ctrl+ArrowDown", "mac+shift+ArrowDown"], proto._translateEmpty, { args: [0, big], checker: arrowChecker }]])); } static _type = "freetext"; static _editorType = AnnotationEditorType.FREETEXT; constructor(params) { super({ ...params, name: "freeTextEditor" }); this.#color = params.color || FreeTextEditor._defaultColor || AnnotationEditor._defaultLineColor; this.#fontSize = params.fontSize || FreeTextEditor._defaultFontSize; } static initialize(l10n, uiManager) { AnnotationEditor.initialize(l10n, uiManager, { strings: ["pdfjs-free-text-default-content"] }); const style = getComputedStyle(document.documentElement); this._internalPadding = parseFloat(style.getPropertyValue("--freetext-padding")); } static updateDefaultParams(type, value) { switch (type) { case AnnotationEditorParamsType.FREETEXT_SIZE: FreeTextEditor._defaultFontSize = value; break; case AnnotationEditorParamsType.FREETEXT_COLOR: FreeTextEditor._defaultColor = value; break; } } updateParams(type, value) { switch (type) { case AnnotationEditorParamsType.FREETEXT_SIZE: this.#updateFontSize(value); break; case AnnotationEditorParamsType.FREETEXT_COLOR: this.#updateColor(value); break; } } static get defaultPropertiesToUpdate() { return [[AnnotationEditorParamsType.FREETEXT_SIZE, FreeTextEditor._defaultFontSize], [AnnotationEditorParamsType.FREETEXT_COLOR, FreeTextEditor._defaultColor || AnnotationEditor._defaultLineColor]]; } get propertiesToUpdate() { return [[AnnotationEditorParamsType.FREETEXT_SIZE, this.#fontSize], [AnnotationEditorParamsType.FREETEXT_COLOR, this.#color]]; } #updateFontSize(fontSize) { const setFontsize = size => { this.editorDiv.style.fontSize = `calc(${size}px * var(--scale-factor))`; this.translate(0, -(size - this.#fontSize) * this.parentScale); this.#fontSize = size; this.#setEditorDimensions(); }; const savedFontsize = this.#fontSize; this.addCommands({ cmd: setFontsize.bind(this, fontSize), undo: setFontsize.bind(this, savedFontsize), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.FREETEXT_SIZE, overwriteIfSameType: true, keepUndo: true }); } #updateColor(color) { const setColor = col => { this.#color = this.editorDiv.style.color = col; }; const savedColor = this.#color; this.addCommands({ cmd: setColor.bind(this, color), undo: setColor.bind(this, savedColor), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.FREETEXT_COLOR, overwriteIfSameType: true, keepUndo: true }); } _translateEmpty(x, y) { this._uiManager.translateSelectedEditors(x, y, true); } getInitialTranslation() { const scale = this.parentScale; return [-FreeTextEditor._internalPadding * scale, -(FreeTextEditor._internalPadding + this.#fontSize) * scale]; } rebuild() { if (!this.parent) { return; } super.rebuild(); if (this.div === null) { return; } if (!this.isAttachedToDOM) { this.parent.add(this); } } enableEditMode() { if (this.isInEditMode()) { return; } this.parent.setEditingState(false); this.parent.updateToolbar(AnnotationEditorType.FREETEXT); super.enableEditMode(); this.overlayDiv.classList.remove("enabled"); this.editorDiv.contentEditable = true; this._isDraggable = false; this.div.removeAttribute("aria-activedescendant"); this.editorDiv.addEventListener("keydown", this.#boundEditorDivKeydown); this.editorDiv.addEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.addEventListener("blur", this.#boundEditorDivBlur); this.editorDiv.addEventListener("input", this.#boundEditorDivInput); this.editorDiv.addEventListener("paste", this.#boundEditorDivPaste); } disableEditMode() { if (!this.isInEditMode()) { return; } this.parent.setEditingState(true); super.disableEditMode(); this.overlayDiv.classList.add("enabled"); this.editorDiv.contentEditable = false; this.div.setAttribute("aria-activedescendant", this.#editorDivId); this._isDraggable = true; this.editorDiv.removeEventListener("keydown", this.#boundEditorDivKeydown); this.editorDiv.removeEventListener("focus", this.#boundEditorDivFocus); this.editorDiv.removeEventListener("blur", this.#boundEditorDivBlur); this.editorDiv.removeEventListener("input", this.#boundEditorDivInput); this.editorDiv.removeEventListener("paste", this.#boundEditorDivPaste); this.div.focus({ preventScroll: true }); this.isEditing = false; this.parent.div.classList.add("freetextEditing"); } focusin(event) { if (!this._focusEventsAllowed) { return; } super.focusin(event); if (event.target !== this.editorDiv) { this.editorDiv.focus(); } } onceAdded() { if (this.width) { return; } this.enableEditMode(); this.editorDiv.focus(); if (this._initialOptions?.isCentered) { this.center(); } this._initialOptions = null; } isEmpty() { return !this.editorDiv || this.editorDiv.innerText.trim() === ""; } remove() { this.isEditing = false; if (this.parent) { this.parent.setEditingState(true); this.parent.div.classList.add("freetextEditing"); } super.remove(); } #extractText() { const buffer = []; this.editorDiv.normalize(); for (const child of this.editorDiv.childNodes) { buffer.push(FreeTextEditor.#getNodeContent(child)); } return buffer.join("\n"); } #setEditorDimensions() { const [parentWidth, parentHeight] = this.parentDimensions; let rect; if (this.isAttachedToDOM) { rect = this.div.getBoundingClientRect(); } else { const { currentLayer, div } = this; const savedDisplay = div.style.display; const savedVisibility = div.classList.contains("hidden"); div.classList.remove("hidden"); div.style.display = "hidden"; currentLayer.div.append(this.div); rect = div.getBoundingClientRect(); div.remove(); div.style.display = savedDisplay; div.classList.toggle("hidden", savedVisibility); } if (this.rotation % 180 === this.parentRotation % 180) { this.width = rect.width / parentWidth; this.height = rect.height / parentHeight; } else { this.width = rect.height / parentWidth; this.height = rect.width / parentHeight; } this.fixAndSetPosition(); } commit() { if (!this.isInEditMode()) { return; } super.commit(); this.disableEditMode(); const savedText = this.#content; const newText = this.#content = this.#extractText().trimEnd(); if (savedText === newText) { return; } const setText = text => { this.#content = text; if (!text) { this.remove(); return; } this.#setContent(); this._uiManager.rebuild(this); this.#setEditorDimensions(); }; this.addCommands({ cmd: () => { setText(newText); }, undo: () => { setText(savedText); }, mustExec: false }); this.#setEditorDimensions(); } shouldGetKeyboardEvents() { return this.isInEditMode(); } enterInEditMode() { this.enableEditMode(); this.editorDiv.focus(); } dblclick(event) { this.enterInEditMode(); } keydown(event) { if (event.target === this.div && event.key === "Enter") { this.enterInEditMode(); event.preventDefault(); } } editorDivKeydown(event) { FreeTextEditor._keyboardManager.exec(this, event); } editorDivFocus(event) { this.isEditing = true; } editorDivBlur(event) { this.isEditing = false; } editorDivInput(event) { this.parent.div.classList.toggle("freetextEditing", this.isEmpty()); } disableEditing() { this.editorDiv.setAttribute("role", "comment"); this.editorDiv.removeAttribute("aria-multiline"); } enableEditing() { this.editorDiv.setAttribute("role", "textbox"); this.editorDiv.setAttribute("aria-multiline", true); } render() { if (this.div) { return this.div; } let baseX, baseY; if (this.width) { baseX = this.x; baseY = this.y; } super.render(); this.editorDiv = document.createElement("div"); this.editorDiv.className = "internal"; this.editorDiv.setAttribute("id", this.#editorDivId); this.editorDiv.setAttribute("data-l10n-id", "pdfjs-free-text"); this.enableEditing(); AnnotationEditor._l10nPromise.get("pdfjs-free-text-default-content").then(msg => this.editorDiv?.setAttribute("default-content", msg)); this.editorDiv.contentEditable = true; const { style } = this.editorDiv; style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; style.color = this.#color; this.div.append(this.editorDiv); this.overlayDiv = document.createElement("div"); this.overlayDiv.classList.add("overlay", "enabled"); this.div.append(this.overlayDiv); bindEvents(this, this.div, ["dblclick", "keydown"]); if (this.width) { const [parentWidth, parentHeight] = this.parentDimensions; if (this.annotationElementId) { const { position } = this.#initialData; let [tx, ty] = this.getInitialTranslation(); [tx, ty] = this.pageTranslationToScreen(tx, ty); const [pageWidth, pageHeight] = this.pageDimensions; const [pageX, pageY] = this.pageTranslation; let posX, posY; switch (this.rotation) { case 0: posX = baseX + (position[0] - pageX) / pageWidth; posY = baseY + this.height - (position[1] - pageY) / pageHeight; break; case 90: posX = baseX + (position[0] - pageX) / pageWidth; posY = baseY - (position[1] - pageY) / pageHeight; [tx, ty] = [ty, -tx]; break; case 180: posX = baseX - this.width + (position[0] - pageX) / pageWidth; posY = baseY - (position[1] - pageY) / pageHeight; [tx, ty] = [-tx, -ty]; break; case 270: posX = baseX + (position[0] - pageX - this.height * pageHeight) / pageWidth; posY = baseY + (position[1] - pageY - this.width * pageWidth) / pageHeight; [tx, ty] = [-ty, tx]; break; } this.setAt(posX * parentWidth, posY * parentHeight, tx, ty); } else { this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); } this.#setContent(); this._isDraggable = true; this.editorDiv.contentEditable = false; } else { this._isDraggable = false; this.editorDiv.contentEditable = true; } return this.div; } static #getNodeContent(node) { return (node.nodeType === Node.TEXT_NODE ? node.nodeValue : node.innerText).replaceAll(EOL_PATTERN, ""); } editorDivPaste(event) { const clipboardData = event.clipboardData || window.clipboardData; const { types } = clipboardData; if (types.length === 1 && types[0] === "text/plain") { return; } event.preventDefault(); const paste = FreeTextEditor.#deserializeContent(clipboardData.getData("text") || "").replaceAll(EOL_PATTERN, "\n"); if (!paste) { return; } const selection = window.getSelection(); if (!selection.rangeCount) { return; } this.editorDiv.normalize(); selection.deleteFromDocument(); const range = selection.getRangeAt(0); if (!paste.includes("\n")) { range.insertNode(document.createTextNode(paste)); this.editorDiv.normalize(); selection.collapseToStart(); return; } const { startContainer, startOffset } = range; const bufferBefore = []; const bufferAfter = []; if (startContainer.nodeType === Node.TEXT_NODE) { const parent = startContainer.parentElement; bufferAfter.push(startContainer.nodeValue.slice(startOffset).replaceAll(EOL_PATTERN, "")); if (parent !== this.editorDiv) { let buffer = bufferBefore; for (const child of this.editorDiv.childNodes) { if (child === parent) { buffer = bufferAfter; continue; } buffer.push(FreeTextEditor.#getNodeContent(child)); } } bufferBefore.push(startContainer.nodeValue.slice(0, startOffset).replaceAll(EOL_PATTERN, "")); } else if (startContainer === this.editorDiv) { let buffer = bufferBefore; let i = 0; for (const child of this.editorDiv.childNodes) { if (i++ === startOffset) { buffer = bufferAfter; } buffer.push(FreeTextEditor.#getNodeContent(child)); } } this.#content = `${bufferBefore.join("\n")}${paste}${bufferAfter.join("\n")}`; this.#setContent(); const newRange = new Range(); let beforeLength = bufferBefore.reduce((acc, line) => acc + line.length, 0); for (const { firstChild } of this.editorDiv.childNodes) { if (firstChild.nodeType === Node.TEXT_NODE) { const length = firstChild.nodeValue.length; if (beforeLength <= length) { newRange.setStart(firstChild, beforeLength); newRange.setEnd(firstChild, beforeLength); break; } beforeLength -= length; } } selection.removeAllRanges(); selection.addRange(newRange); } #setContent() { this.editorDiv.replaceChildren(); if (!this.#content) { return; } for (const line of this.#content.split("\n")) { const div = document.createElement("div"); div.append(line ? document.createTextNode(line) : document.createElement("br")); this.editorDiv.append(div); } } #serializeContent() { return this.#content.replaceAll("\xa0", " "); } static #deserializeContent(content) { return content.replaceAll(" ", "\xa0"); } get contentDiv() { return this.editorDiv; } static deserialize(data, parent, uiManager) { let initialData = null; if (data instanceof FreeTextAnnotationElement) { const { data: { defaultAppearanceData: { fontSize, fontColor }, rect, rotation, id }, textContent, textPosition, parent: { page: { pageNumber } } } = data; if (!textContent || textContent.length === 0) { return null; } initialData = data = { annotationType: AnnotationEditorType.FREETEXT, color: Array.from(fontColor), fontSize, value: textContent.join("\n"), position: textPosition, pageIndex: pageNumber - 1, rect: rect.slice(0), rotation, id, deleted: false }; } const editor = super.deserialize(data, parent, uiManager); editor.#fontSize = data.fontSize; editor.#color = Util.makeHexColor(...data.color); editor.#content = FreeTextEditor.#deserializeContent(data.value); editor.annotationElementId = data.id || null; editor.#initialData = initialData; return editor; } serialize(isForCopying = false) { if (this.isEmpty()) { return null; } if (this.deleted) { return { pageIndex: this.pageIndex, id: this.annotationElementId, deleted: true }; } const padding = FreeTextEditor._internalPadding * this.parentScale; const rect = this.getRect(padding, padding); const color = AnnotationEditor._colorManager.convert(this.isAttachedToDOM ? getComputedStyle(this.editorDiv).color : this.#color); const serialized = { annotationType: AnnotationEditorType.FREETEXT, color, fontSize: this.#fontSize, value: this.#serializeContent(), pageIndex: this.pageIndex, rect, rotation: this.rotation, structTreeParentId: this._structTreeParentId }; if (isForCopying) { return serialized; } if (this.annotationElementId && !this.#hasElementChanged(serialized)) { return null; } serialized.id = this.annotationElementId; return serialized; } #hasElementChanged(serialized) { const { value, fontSize, color, pageIndex } = this.#initialData; return this._hasBeenMoved || serialized.value !== value || serialized.fontSize !== fontSize || serialized.color.some((c, i) => c !== color[i]) || serialized.pageIndex !== pageIndex; } renderAnnotationElement(annotation) { const content = super.renderAnnotationElement(annotation); if (this.deleted) { return content; } const { style } = content; style.fontSize = `calc(${this.#fontSize}px * var(--scale-factor))`; style.color = this.#color; content.replaceChildren(); for (const line of this.#content.split("\n")) { const div = document.createElement("div"); div.append(line ? document.createTextNode(line) : document.createElement("br")); content.append(div); } const padding = FreeTextEditor._internalPadding * this.parentScale; annotation.updateEdited({ rect: this.getRect(padding, padding), popupContent: this.#content }); return content; } resetAnnotationElement(annotation) { super.resetAnnotationElement(annotation); annotation.resetEdited(); } } ;// CONCATENATED MODULE: ./src/display/editor/outliner.js class Outliner { #box; #verticalEdges = []; #intervals = []; constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) { let minX = Infinity; let maxX = -Infinity; let minY = Infinity; let maxY = -Infinity; const NUMBER_OF_DIGITS = 4; const EPSILON = 10 ** -NUMBER_OF_DIGITS; for (const { x, y, width, height } of boxes) { const x1 = Math.floor((x - borderWidth) / EPSILON) * EPSILON; const x2 = Math.ceil((x + width + borderWidth) / EPSILON) * EPSILON; const y1 = Math.floor((y - borderWidth) / EPSILON) * EPSILON; const y2 = Math.ceil((y + height + borderWidth) / EPSILON) * EPSILON; const left = [x1, y1, y2, true]; const right = [x2, y1, y2, false]; this.#verticalEdges.push(left, right); minX = Math.min(minX, x1); maxX = Math.max(maxX, x2); minY = Math.min(minY, y1); maxY = Math.max(maxY, y2); } const bboxWidth = maxX - minX + 2 * innerMargin; const bboxHeight = maxY - minY + 2 * innerMargin; const shiftedMinX = minX - innerMargin; const shiftedMinY = minY - innerMargin; const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2); const lastPoint = [lastEdge[0], lastEdge[2]]; for (const edge of this.#verticalEdges) { const [x, y1, y2] = edge; edge[0] = (x - shiftedMinX) / bboxWidth; edge[1] = (y1 - shiftedMinY) / bboxHeight; edge[2] = (y2 - shiftedMinY) / bboxHeight; } this.#box = { x: shiftedMinX, y: shiftedMinY, width: bboxWidth, height: bboxHeight, lastPoint }; } getOutlines() { this.#verticalEdges.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]); const outlineVerticalEdges = []; for (const edge of this.#verticalEdges) { if (edge[3]) { outlineVerticalEdges.push(...this.#breakEdge(edge)); this.#insert(edge); } else { this.#remove(edge); outlineVerticalEdges.push(...this.#breakEdge(edge)); } } return this.#getOutlines(outlineVerticalEdges); } #getOutlines(outlineVerticalEdges) { const edges = []; const allEdges = new Set(); for (const edge of outlineVerticalEdges) { const [x, y1, y2] = edge; edges.push([x, y1, edge], [x, y2, edge]); } edges.sort((a, b) => a[1] - b[1] || a[0] - b[0]); for (let i = 0, ii = edges.length; i < ii; i += 2) { const edge1 = edges[i][2]; const edge2 = edges[i + 1][2]; edge1.push(edge2); edge2.push(edge1); allEdges.add(edge1); allEdges.add(edge2); } const outlines = []; let outline; while (allEdges.size > 0) { const edge = allEdges.values().next().value; let [x, y1, y2, edge1, edge2] = edge; allEdges.delete(edge); let lastPointX = x; let lastPointY = y1; outline = [x, y2]; outlines.push(outline); while (true) { let e; if (allEdges.has(edge1)) { e = edge1; } else if (allEdges.has(edge2)) { e = edge2; } else { break; } allEdges.delete(e); [x, y1, y2, edge1, edge2] = e; if (lastPointX !== x) { outline.push(lastPointX, lastPointY, x, lastPointY === y1 ? y1 : y2); lastPointX = x; } lastPointY = lastPointY === y1 ? y2 : y1; } outline.push(lastPointX, lastPointY); } return new HighlightOutline(outlines, this.#box); } #binarySearch(y) { const array = this.#intervals; let start = 0; let end = array.length - 1; while (start <= end) { const middle = start + end >> 1; const y1 = array[middle][0]; if (y1 === y) { return middle; } if (y1 < y) { start = middle + 1; } else { end = middle - 1; } } return end + 1; } #insert([, y1, y2]) { const index = this.#binarySearch(y1); this.#intervals.splice(index, 0, [y1, y2]); } #remove([, y1, y2]) { const index = this.#binarySearch(y1); for (let i = index; i < this.#intervals.length; i++) { const [start, end] = this.#intervals[i]; if (start !== y1) { break; } if (start === y1 && end === y2) { this.#intervals.splice(i, 1); return; } } for (let i = index - 1; i >= 0; i--) { const [start, end] = this.#intervals[i]; if (start !== y1) { break; } if (start === y1 && end === y2) { this.#intervals.splice(i, 1); return; } } } #breakEdge(edge) { const [x, y1, y2] = edge; const results = [[x, y1, y2]]; const index = this.#binarySearch(y2); for (let i = 0; i < index; i++) { const [start, end] = this.#intervals[i]; for (let j = 0, jj = results.length; j < jj; j++) { const [, y3, y4] = results[j]; if (end <= y3 || y4 <= start) { continue; } if (y3 >= start) { if (y4 > end) { results[j][1] = end; } else { if (jj === 1) { return []; } results.splice(j, 1); j--; jj--; } continue; } results[j][2] = start; if (y4 > end) { results.push([x, end, y4]); } } } return results; } } class Outline { toSVGPath() { throw new Error("Abstract method `toSVGPath` must be implemented."); } get box() { throw new Error("Abstract getter `box` must be implemented."); } serialize(_bbox, _rotation) { throw new Error("Abstract method `serialize` must be implemented."); } get free() { return this instanceof FreeHighlightOutline; } } class HighlightOutline extends Outline { #box; #outlines; constructor(outlines, box) { super(); this.#outlines = outlines; this.#box = box; } toSVGPath() { const buffer = []; for (const polygon of this.#outlines) { let [prevX, prevY] = polygon; buffer.push(`M${prevX} ${prevY}`); for (let i = 2; i < polygon.length; i += 2) { const x = polygon[i]; const y = polygon[i + 1]; if (x === prevX) { buffer.push(`V${y}`); prevY = y; } else if (y === prevY) { buffer.push(`H${x}`); prevX = x; } } buffer.push("Z"); } return buffer.join(" "); } serialize([blX, blY, trX, trY], _rotation) { const outlines = []; const width = trX - blX; const height = trY - blY; for (const outline of this.#outlines) { const points = new Array(outline.length); for (let i = 0; i < outline.length; i += 2) { points[i] = blX + outline[i] * width; points[i + 1] = trY - outline[i + 1] * height; } outlines.push(points); } return outlines; } get box() { return this.#box; } } class FreeOutliner { #box; #bottom = []; #innerMargin; #isLTR; #top = []; #last = new Float64Array(18); #lastX; #lastY; #min; #min_dist; #scaleFactor; #thickness; #points = []; static #MIN_DIST = 8; static #MIN_DIFF = 2; static #MIN = FreeOutliner.#MIN_DIST + FreeOutliner.#MIN_DIFF; constructor({ x, y }, box, scaleFactor, thickness, isLTR, innerMargin = 0) { this.#box = box; this.#thickness = thickness * scaleFactor; this.#isLTR = isLTR; this.#last.set([NaN, NaN, NaN, NaN, x, y], 6); this.#innerMargin = innerMargin; this.#min_dist = FreeOutliner.#MIN_DIST * scaleFactor; this.#min = FreeOutliner.#MIN * scaleFactor; this.#scaleFactor = scaleFactor; this.#points.push(x, y); } get free() { return true; } isEmpty() { return isNaN(this.#last[8]); } #getLastCoords() { const lastTop = this.#last.subarray(4, 6); const lastBottom = this.#last.subarray(16, 18); const [x, y, width, height] = this.#box; 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]; } add({ x, y }) { this.#lastX = x; this.#lastY = y; const [layerX, layerY, layerWidth, layerHeight] = this.#box; let [x1, y1, x2, y2] = this.#last.subarray(8, 12); const diffX = x - x2; const diffY = y - y2; const d = Math.hypot(diffX, diffY); if (d < this.#min) { return false; } const diffD = d - this.#min_dist; const K = diffD / d; const shiftX = K * diffX; const shiftY = K * diffY; let x0 = x1; let y0 = y1; x1 = x2; y1 = y2; x2 += shiftX; y2 += shiftY; this.#points?.push(x, y); const nX = -shiftY / diffD; const nY = shiftX / diffD; const thX = nX * this.#thickness; const thY = nY * this.#thickness; this.#last.set(this.#last.subarray(2, 8), 0); this.#last.set([x2 + thX, y2 + thY], 4); this.#last.set(this.#last.subarray(14, 18), 12); this.#last.set([x2 - thX, y2 - thY], 16); if (isNaN(this.#last[6])) { if (this.#top.length === 0) { this.#last.set([x1 + thX, y1 + thY], 2); this.#top.push(NaN, NaN, NaN, NaN, (x1 + thX - layerX) / layerWidth, (y1 + thY - layerY) / layerHeight); this.#last.set([x1 - thX, y1 - thY], 14); this.#bottom.push(NaN, NaN, NaN, NaN, (x1 - thX - layerX) / layerWidth, (y1 - thY - layerY) / layerHeight); } this.#last.set([x0, y0, x1, y1, x2, y2], 6); return !this.isEmpty(); } this.#last.set([x0, y0, x1, y1, x2, y2], 6); const angle = Math.abs(Math.atan2(y0 - y1, x0 - x1) - Math.atan2(shiftY, shiftX)); if (angle < Math.PI / 2) { [x1, y1, x2, y2] = this.#last.subarray(2, 6); this.#top.push(NaN, NaN, NaN, NaN, ((x1 + x2) / 2 - layerX) / layerWidth, ((y1 + y2) / 2 - layerY) / layerHeight); [x1, y1, x0, y0] = this.#last.subarray(14, 18); this.#bottom.push(NaN, NaN, NaN, NaN, ((x0 + x1) / 2 - layerX) / layerWidth, ((y0 + y1) / 2 - layerY) / layerHeight); return true; } [x0, y0, x1, y1, x2, y2] = this.#last.subarray(0, 6); 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); [x2, y2, x1, y1, x0, y0] = this.#last.subarray(12, 18); 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); return true; } toSVGPath() { if (this.isEmpty()) { return ""; } const top = this.#top; const bottom = this.#bottom; const lastTop = this.#last.subarray(4, 6); const lastBottom = this.#last.subarray(16, 18); const [x, y, width, height] = this.#box; const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); if (isNaN(this.#last[6]) && !this.isEmpty()) { 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`; } const buffer = []; buffer.push(`M${top[4]} ${top[5]}`); for (let i = 6; i < top.length; i += 6) { if (isNaN(top[i])) { buffer.push(`L${top[i + 4]} ${top[i + 5]}`); } else { buffer.push(`C${top[i]} ${top[i + 1]} ${top[i + 2]} ${top[i + 3]} ${top[i + 4]} ${top[i + 5]}`); } } 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}`); for (let i = bottom.length - 6; i >= 6; i -= 6) { if (isNaN(bottom[i])) { buffer.push(`L${bottom[i + 4]} ${bottom[i + 5]}`); } else { buffer.push(`C${bottom[i]} ${bottom[i + 1]} ${bottom[i + 2]} ${bottom[i + 3]} ${bottom[i + 4]} ${bottom[i + 5]}`); } } buffer.push(`L${bottom[4]} ${bottom[5]} Z`); return buffer.join(" "); } getOutlines() { const top = this.#top; const bottom = this.#bottom; const last = this.#last; const lastTop = last.subarray(4, 6); const lastBottom = last.subarray(16, 18); const [layerX, layerY, layerWidth, layerHeight] = this.#box; const points = new Float64Array((this.#points?.length ?? 0) + 2); for (let i = 0, ii = points.length - 2; i < ii; i += 2) { points[i] = (this.#points[i] - layerX) / layerWidth; points[i + 1] = (this.#points[i + 1] - layerY) / layerHeight; } points[points.length - 2] = (this.#lastX - layerX) / layerWidth; points[points.length - 1] = (this.#lastY - layerY) / layerHeight; const [lastTopX, lastTopY, lastBottomX, lastBottomY] = this.#getLastCoords(); if (isNaN(last[6]) && !this.isEmpty()) { const outline = new Float64Array(36); 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); return new FreeHighlightOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR); } const outline = new Float64Array(this.#top.length + 24 + this.#bottom.length); let N = top.length; for (let i = 0; i < N; i += 2) { if (isNaN(top[i])) { outline[i] = outline[i + 1] = NaN; continue; } outline[i] = top[i]; outline[i + 1] = top[i + 1]; } 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], N); N += 24; for (let i = bottom.length - 6; i >= 6; i -= 6) { for (let j = 0; j < 6; j += 2) { if (isNaN(bottom[i + j])) { outline[N] = outline[N + 1] = NaN; N += 2; continue; } outline[N] = bottom[i + j]; outline[N + 1] = bottom[i + j + 1]; N += 2; } } outline.set([NaN, NaN, NaN, NaN, bottom[4], bottom[5]], N); return new FreeHighlightOutline(outline, points, this.#box, this.#scaleFactor, this.#innerMargin, this.#isLTR); } } class FreeHighlightOutline extends Outline { #box; #bbox = null; #innerMargin; #isLTR; #points; #scaleFactor; #outline; constructor(outline, points, box, scaleFactor, innerMargin, isLTR) { super(); this.#outline = outline; this.#points = points; this.#box = box; this.#scaleFactor = scaleFactor; this.#innerMargin = innerMargin; this.#isLTR = isLTR; this.#computeMinMax(isLTR); const { x, y, width, height } = this.#bbox; for (let i = 0, ii = outline.length; i < ii; i += 2) { outline[i] = (outline[i] - x) / width; outline[i + 1] = (outline[i + 1] - y) / height; } for (let i = 0, ii = points.length; i < ii; i += 2) { points[i] = (points[i] - x) / width; points[i + 1] = (points[i + 1] - y) / height; } } toSVGPath() { const buffer = [`M${this.#outline[4]} ${this.#outline[5]}`]; for (let i = 6, ii = this.#outline.length; i < ii; i += 6) { if (isNaN(this.#outline[i])) { buffer.push(`L${this.#outline[i + 4]} ${this.#outline[i + 5]}`); continue; } 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]}`); } buffer.push("Z"); return buffer.join(" "); } serialize([blX, blY, trX, trY], rotation) { const width = trX - blX; const height = trY - blY; let outline; let points; switch (rotation) { case 0: outline = this.#rescale(this.#outline, blX, trY, width, -height); points = this.#rescale(this.#points, blX, trY, width, -height); break; case 90: outline = this.#rescaleAndSwap(this.#outline, blX, blY, width, height); points = this.#rescaleAndSwap(this.#points, blX, blY, width, height); break; case 180: outline = this.#rescale(this.#outline, trX, blY, -width, height); points = this.#rescale(this.#points, trX, blY, -width, height); break; case 270: outline = this.#rescaleAndSwap(this.#outline, trX, trY, -width, -height); points = this.#rescaleAndSwap(this.#points, trX, trY, -width, -height); break; } return { outline: Array.from(outline), points: [Array.from(points)] }; } #rescale(src, tx, ty, sx, sy) { const dest = new Float64Array(src.length); for (let i = 0, ii = src.length; i < ii; i += 2) { dest[i] = tx + src[i] * sx; dest[i + 1] = ty + src[i + 1] * sy; } return dest; } #rescaleAndSwap(src, tx, ty, sx, sy) { const dest = new Float64Array(src.length); for (let i = 0, ii = src.length; i < ii; i += 2) { dest[i] = tx + src[i + 1] * sx; dest[i + 1] = ty + src[i] * sy; } return dest; } #computeMinMax(isLTR) { const outline = this.#outline; let lastX = outline[4]; let lastY = outline[5]; let minX = lastX; let minY = lastY; let maxX = lastX; let maxY = lastY; let lastPointX = lastX; let lastPointY = lastY; const ltrCallback = isLTR ? Math.max : Math.min; for (let i = 6, ii = outline.length; i < ii; i += 6) { if (isNaN(outline[i])) { minX = Math.min(minX, outline[i + 4]); minY = Math.min(minY, outline[i + 5]); maxX = Math.max(maxX, outline[i + 4]); maxY = Math.max(maxY, outline[i + 5]); if (lastPointY < outline[i + 5]) { lastPointX = outline[i + 4]; lastPointY = outline[i + 5]; } else if (lastPointY === outline[i + 5]) { lastPointX = ltrCallback(lastPointX, outline[i + 4]); } } else { const bbox = Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6)); minX = Math.min(minX, bbox[0]); minY = Math.min(minY, bbox[1]); maxX = Math.max(maxX, bbox[2]); maxY = Math.max(maxY, bbox[3]); if (lastPointY < bbox[3]) { lastPointX = bbox[2]; lastPointY = bbox[3]; } else if (lastPointY === bbox[3]) { lastPointX = ltrCallback(lastPointX, bbox[2]); } } lastX = outline[i + 4]; lastY = outline[i + 5]; } const x = minX - this.#innerMargin, y = minY - this.#innerMargin, width = maxX - minX + 2 * this.#innerMargin, height = maxY - minY + 2 * this.#innerMargin; this.#bbox = { x, y, width, height, lastPoint: [lastPointX, lastPointY] }; } get box() { return this.#bbox; } getNewOutline(thickness, innerMargin) { const { x, y, width, height } = this.#bbox; const [layerX, layerY, layerWidth, layerHeight] = this.#box; const sx = width * layerWidth; const sy = height * layerHeight; const tx = x * layerWidth + layerX; const ty = y * layerHeight + layerY; const outliner = new FreeOutliner({ x: this.#points[0] * sx + tx, y: this.#points[1] * sy + ty }, this.#box, this.#scaleFactor, thickness, this.#isLTR, innerMargin ?? this.#innerMargin); for (let i = 2; i < this.#points.length; i += 2) { outliner.add({ x: this.#points[i] * sx + tx, y: this.#points[i + 1] * sy + ty }); } return outliner.getOutlines(); } } ;// CONCATENATED MODULE: ./src/display/editor/color_picker.js class ColorPicker { #boundKeyDown = this.#keyDown.bind(this); #boundPointerDown = this.#pointerDown.bind(this); #button = null; #buttonSwatch = null; #defaultColor; #dropdown = null; #dropdownWasFromKeyboard = false; #isMainColorPicker = false; #editor = null; #eventBus; #uiManager = null; #type; static get _keyboardManager() { return shadow(this, "_keyboardManager", new KeyboardManager([[["Escape", "mac+Escape"], ColorPicker.prototype._hideDropdownFromKeyboard], [[" ", "mac+ "], ColorPicker.prototype._colorSelectFromKeyboard], [["ArrowDown", "ArrowRight", "mac+ArrowDown", "mac+ArrowRight"], ColorPicker.prototype._moveToNext], [["ArrowUp", "ArrowLeft", "mac+ArrowUp", "mac+ArrowLeft"], ColorPicker.prototype._moveToPrevious], [["Home", "mac+Home"], ColorPicker.prototype._moveToBeginning], [["End", "mac+End"], ColorPicker.prototype._moveToEnd]])); } constructor({ editor = null, uiManager = null }) { if (editor) { this.#isMainColorPicker = false; this.#type = AnnotationEditorParamsType.HIGHLIGHT_COLOR; this.#editor = editor; } else { this.#isMainColorPicker = true; this.#type = AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR; } this.#uiManager = editor?._uiManager || uiManager; this.#eventBus = this.#uiManager._eventBus; this.#defaultColor = editor?.color || this.#uiManager?.highlightColors.values().next().value || "#FFFF98"; } renderButton() { const button = this.#button = document.createElement("button"); button.className = "colorPicker"; button.tabIndex = "0"; button.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-button"); button.setAttribute("aria-haspopup", true); button.addEventListener("click", this.#openDropdown.bind(this)); button.addEventListener("keydown", this.#boundKeyDown); const swatch = this.#buttonSwatch = document.createElement("span"); swatch.className = "swatch"; swatch.setAttribute("aria-hidden", true); swatch.style.backgroundColor = this.#defaultColor; button.append(swatch); return button; } renderMainDropdown() { const dropdown = this.#dropdown = this.#getDropdownRoot(); dropdown.setAttribute("aria-orientation", "horizontal"); dropdown.setAttribute("aria-labelledby", "highlightColorPickerLabel"); return dropdown; } #getDropdownRoot() { const div = document.createElement("div"); div.addEventListener("contextmenu", noContextMenu); div.className = "dropdown"; div.role = "listbox"; div.setAttribute("aria-multiselectable", false); div.setAttribute("aria-orientation", "vertical"); div.setAttribute("data-l10n-id", "pdfjs-editor-colorpicker-dropdown"); for (const [name, color] of this.#uiManager.highlightColors) { const button = document.createElement("button"); button.tabIndex = "0"; button.role = "option"; button.setAttribute("data-color", color); button.title = name; button.setAttribute("data-l10n-id", `pdfjs-editor-colorpicker-${name}`); const swatch = document.createElement("span"); button.append(swatch); swatch.className = "swatch"; swatch.style.backgroundColor = color; button.setAttribute("aria-selected", color === this.#defaultColor); button.addEventListener("click", this.#colorSelect.bind(this, color)); div.append(button); } div.addEventListener("keydown", this.#boundKeyDown); return div; } #colorSelect(color, event) { event.stopPropagation(); this.#eventBus.dispatch("switchannotationeditorparams", { source: this, type: this.#type, value: color }); } _colorSelectFromKeyboard(event) { if (event.target === this.#button) { this.#openDropdown(event); return; } const color = event.target.getAttribute("data-color"); if (!color) { return; } this.#colorSelect(color, event); } _moveToNext(event) { if (!this.#isDropdownVisible) { this.#openDropdown(event); return; } if (event.target === this.#button) { this.#dropdown.firstChild?.focus(); return; } event.target.nextSibling?.focus(); } _moveToPrevious(event) { if (event.target === this.#dropdown?.firstChild || event.target === this.#button) { if (this.#isDropdownVisible) { this._hideDropdownFromKeyboard(); } return; } if (!this.#isDropdownVisible) { this.#openDropdown(event); } event.target.previousSibling?.focus(); } _moveToBeginning(event) { if (!this.#isDropdownVisible) { this.#openDropdown(event); return; } this.#dropdown.firstChild?.focus(); } _moveToEnd(event) { if (!this.#isDropdownVisible) { this.#openDropdown(event); return; } this.#dropdown.lastChild?.focus(); } #keyDown(event) { ColorPicker._keyboardManager.exec(this, event); } #openDropdown(event) { if (this.#isDropdownVisible) { this.hideDropdown(); return; } this.#dropdownWasFromKeyboard = event.detail === 0; window.addEventListener("pointerdown", this.#boundPointerDown); if (this.#dropdown) { this.#dropdown.classList.remove("hidden"); return; } const root = this.#dropdown = this.#getDropdownRoot(); this.#button.append(root); } #pointerDown(event) { if (this.#dropdown?.contains(event.target)) { return; } this.hideDropdown(); } hideDropdown() { this.#dropdown?.classList.add("hidden"); window.removeEventListener("pointerdown", this.#boundPointerDown); } get #isDropdownVisible() { return this.#dropdown && !this.#dropdown.classList.contains("hidden"); } _hideDropdownFromKeyboard() { if (this.#isMainColorPicker) { return; } if (!this.#isDropdownVisible) { this.#editor?.unselect(); return; } this.hideDropdown(); this.#button.focus({ preventScroll: true, focusVisible: this.#dropdownWasFromKeyboard }); } updateColor(color) { if (this.#buttonSwatch) { this.#buttonSwatch.style.backgroundColor = color; } if (!this.#dropdown) { return; } const i = this.#uiManager.highlightColors.values(); for (const child of this.#dropdown.children) { child.setAttribute("aria-selected", i.next().value === color); } } destroy() { this.#button?.remove(); this.#button = null; this.#buttonSwatch = null; this.#dropdown?.remove(); this.#dropdown = null; } } ;// CONCATENATED MODULE: ./src/display/editor/highlight.js class HighlightEditor extends AnnotationEditor { #anchorNode = null; #anchorOffset = 0; #boxes; #clipPathId = null; #colorPicker = null; #focusOutlines = null; #focusNode = null; #focusOffset = 0; #highlightDiv = null; #highlightOutlines = null; #id = null; #isFreeHighlight = false; #boundKeydown = this.#keydown.bind(this); #lastPoint = null; #opacity; #outlineId = null; #text = ""; #thickness; #methodOfCreation = ""; static _defaultColor = null; static _defaultOpacity = 1; static _defaultThickness = 12; static _l10nPromise; static _type = "highlight"; static _editorType = AnnotationEditorType.HIGHLIGHT; static _freeHighlightId = -1; static _freeHighlight = null; static _freeHighlightClipId = ""; static get _keyboardManager() { const proto = HighlightEditor.prototype; return shadow(this, "_keyboardManager", new KeyboardManager([[["ArrowLeft", "mac+ArrowLeft"], proto._moveCaret, { args: [0] }], [["ArrowRight", "mac+ArrowRight"], proto._moveCaret, { args: [1] }], [["ArrowUp", "mac+ArrowUp"], proto._moveCaret, { args: [2] }], [["ArrowDown", "mac+ArrowDown"], proto._moveCaret, { args: [3] }]])); } constructor(params) { super({ ...params, name: "highlightEditor" }); this.color = params.color || HighlightEditor._defaultColor; this.#thickness = params.thickness || HighlightEditor._defaultThickness; this.#opacity = params.opacity || HighlightEditor._defaultOpacity; this.#boxes = params.boxes || null; this.#methodOfCreation = params.methodOfCreation || ""; this.#text = params.text || ""; this._isDraggable = false; if (params.highlightId > -1) { this.#isFreeHighlight = true; this.#createFreeOutlines(params); this.#addToDrawLayer(); } else { this.#anchorNode = params.anchorNode; this.#anchorOffset = params.anchorOffset; this.#focusNode = params.focusNode; this.#focusOffset = params.focusOffset; this.#createOutlines(); this.#addToDrawLayer(); this.rotate(this.rotation); } } get telemetryInitialData() { return { action: "added", type: this.#isFreeHighlight ? "free_highlight" : "highlight", color: this._uiManager.highlightColorNames.get(this.color), thickness: this.#thickness, methodOfCreation: this.#methodOfCreation }; } get telemetryFinalData() { return { type: "highlight", color: this._uiManager.highlightColorNames.get(this.color) }; } static computeTelemetryFinalData(data) { return { numberOfColors: data.get("color").size }; } #createOutlines() { const outliner = new Outliner(this.#boxes, 0.001); this.#highlightOutlines = outliner.getOutlines(); ({ x: this.x, y: this.y, width: this.width, height: this.height } = this.#highlightOutlines.box); const outlinerForOutline = new Outliner(this.#boxes, 0.0025, 0.001, this._uiManager.direction === "ltr"); this.#focusOutlines = outlinerForOutline.getOutlines(); const { lastPoint } = this.#focusOutlines.box; this.#lastPoint = [(lastPoint[0] - this.x) / this.width, (lastPoint[1] - this.y) / this.height]; } #createFreeOutlines({ highlightOutlines, highlightId, clipPathId }) { this.#highlightOutlines = highlightOutlines; const extraThickness = 1.5; this.#focusOutlines = highlightOutlines.getNewOutline(this.#thickness / 2 + extraThickness, 0.0025); if (highlightId >= 0) { this.#id = highlightId; this.#clipPathId = clipPathId; this.parent.drawLayer.finalizeLine(highlightId, highlightOutlines); this.#outlineId = this.parent.drawLayer.highlightOutline(this.#focusOutlines); } else if (this.parent) { const angle = this.parent.viewport.rotation; this.parent.drawLayer.updateLine(this.#id, highlightOutlines); this.parent.drawLayer.updateBox(this.#id, HighlightEditor.#rotateBbox(this.#highlightOutlines.box, (angle - this.rotation + 360) % 360)); this.parent.drawLayer.updateLine(this.#outlineId, this.#focusOutlines); this.parent.drawLayer.updateBox(this.#outlineId, HighlightEditor.#rotateBbox(this.#focusOutlines.box, angle)); } const { x, y, width, height } = highlightOutlines.box; switch (this.rotation) { case 0: this.x = x; this.y = y; this.width = width; this.height = height; break; case 90: { const [pageWidth, pageHeight] = this.parentDimensions; this.x = y; this.y = 1 - x; this.width = width * pageHeight / pageWidth; this.height = height * pageWidth / pageHeight; break; } case 180: this.x = 1 - x; this.y = 1 - y; this.width = width; this.height = height; break; case 270: { const [pageWidth, pageHeight] = this.parentDimensions; this.x = 1 - y; this.y = x; this.width = width * pageHeight / pageWidth; this.height = height * pageWidth / pageHeight; break; } } const { lastPoint } = this.#focusOutlines.box; this.#lastPoint = [(lastPoint[0] - x) / width, (lastPoint[1] - y) / height]; } static initialize(l10n, uiManager) { AnnotationEditor.initialize(l10n, uiManager); HighlightEditor._defaultColor ||= uiManager.highlightColors?.values().next().value || "#fff066"; } static updateDefaultParams(type, value) { switch (type) { case AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR: HighlightEditor._defaultColor = value; break; case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS: HighlightEditor._defaultThickness = value; break; } } translateInPage(x, y) {} get toolbarPosition() { return this.#lastPoint; } updateParams(type, value) { switch (type) { case AnnotationEditorParamsType.HIGHLIGHT_COLOR: this.#updateColor(value); break; case AnnotationEditorParamsType.HIGHLIGHT_THICKNESS: this.#updateThickness(value); break; } } static get defaultPropertiesToUpdate() { return [[AnnotationEditorParamsType.HIGHLIGHT_DEFAULT_COLOR, HighlightEditor._defaultColor], [AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, HighlightEditor._defaultThickness]]; } get propertiesToUpdate() { return [[AnnotationEditorParamsType.HIGHLIGHT_COLOR, this.color || HighlightEditor._defaultColor], [AnnotationEditorParamsType.HIGHLIGHT_THICKNESS, this.#thickness || HighlightEditor._defaultThickness], [AnnotationEditorParamsType.HIGHLIGHT_FREE, this.#isFreeHighlight]]; } #updateColor(color) { const setColor = col => { this.color = col; this.parent?.drawLayer.changeColor(this.#id, col); this.#colorPicker?.updateColor(col); }; const savedColor = this.color; this.addCommands({ cmd: setColor.bind(this, color), undo: setColor.bind(this, savedColor), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.HIGHLIGHT_COLOR, overwriteIfSameType: true, keepUndo: true }); this._reportTelemetry({ action: "color_changed", color: this._uiManager.highlightColorNames.get(color) }, true); } #updateThickness(thickness) { const savedThickness = this.#thickness; const setThickness = th => { this.#thickness = th; this.#changeThickness(th); }; this.addCommands({ cmd: setThickness.bind(this, thickness), undo: setThickness.bind(this, savedThickness), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.INK_THICKNESS, overwriteIfSameType: true, keepUndo: true }); this._reportTelemetry({ action: "thickness_changed", thickness }, true); } async addEditToolbar() { const toolbar = await super.addEditToolbar(); if (!toolbar) { return null; } if (this._uiManager.highlightColors) { this.#colorPicker = new ColorPicker({ editor: this }); toolbar.addColorPicker(this.#colorPicker); } return toolbar; } disableEditing() { super.disableEditing(); this.div.classList.toggle("disabled", true); } enableEditing() { super.enableEditing(); this.div.classList.toggle("disabled", false); } fixAndSetPosition() { return super.fixAndSetPosition(this.#getRotation()); } getBaseTranslation() { return [0, 0]; } getRect(tx, ty) { return super.getRect(tx, ty, this.#getRotation()); } onceAdded() { this.parent.addUndoableEditor(this); this.div.focus(); } remove() { this.#cleanDrawLayer(); this._reportTelemetry({ action: "deleted" }); super.remove(); } rebuild() { if (!this.parent) { return; } super.rebuild(); if (this.div === null) { return; } this.#addToDrawLayer(); if (!this.isAttachedToDOM) { this.parent.add(this); } } setParent(parent) { let mustBeSelected = false; if (this.parent && !parent) { this.#cleanDrawLayer(); } else if (parent) { this.#addToDrawLayer(parent); mustBeSelected = !this.parent && this.div?.classList.contains("selectedEditor"); } super.setParent(parent); this.show(this._isVisible); if (mustBeSelected) { this.select(); } } #changeThickness(thickness) { if (!this.#isFreeHighlight) { return; } this.#createFreeOutlines({ highlightOutlines: this.#highlightOutlines.getNewOutline(thickness / 2) }); this.fixAndSetPosition(); const [parentWidth, parentHeight] = this.parentDimensions; this.setDims(this.width * parentWidth, this.height * parentHeight); } #cleanDrawLayer() { if (this.#id === null || !this.parent) { return; } this.parent.drawLayer.remove(this.#id); this.#id = null; this.parent.drawLayer.remove(this.#outlineId); this.#outlineId = null; } #addToDrawLayer(parent = this.parent) { if (this.#id !== null) { return; } ({ id: this.#id, clipPathId: this.#clipPathId } = parent.drawLayer.highlight(this.#highlightOutlines, this.color, this.#opacity)); this.#outlineId = parent.drawLayer.highlightOutline(this.#focusOutlines); if (this.#highlightDiv) { this.#highlightDiv.style.clipPath = this.#clipPathId; } } static #rotateBbox({ x, y, width, height }, angle) { switch (angle) { case 90: return { x: 1 - y - height, y: x, width: height, height: width }; case 180: return { x: 1 - x - width, y: 1 - y - height, width, height }; case 270: return { x: y, y: 1 - x - width, width: height, height: width }; } return { x, y, width, height }; } rotate(angle) { const { drawLayer } = this.parent; let box; if (this.#isFreeHighlight) { angle = (angle - this.rotation + 360) % 360; box = HighlightEditor.#rotateBbox(this.#highlightOutlines.box, angle); } else { box = HighlightEditor.#rotateBbox(this, angle); } drawLayer.rotate(this.#id, angle); drawLayer.rotate(this.#outlineId, angle); drawLayer.updateBox(this.#id, box); drawLayer.updateBox(this.#outlineId, HighlightEditor.#rotateBbox(this.#focusOutlines.box, angle)); } render() { if (this.div) { return this.div; } const div = super.render(); if (this.#text) { div.setAttribute("aria-label", this.#text); div.setAttribute("role", "mark"); } if (this.#isFreeHighlight) { div.classList.add("free"); } else { this.div.addEventListener("keydown", this.#boundKeydown); } const highlightDiv = this.#highlightDiv = document.createElement("div"); div.append(highlightDiv); highlightDiv.setAttribute("aria-hidden", "true"); highlightDiv.className = "internal"; highlightDiv.style.clipPath = this.#clipPathId; const [parentWidth, parentHeight] = this.parentDimensions; this.setDims(this.width * parentWidth, this.height * parentHeight); bindEvents(this, this.#highlightDiv, ["pointerover", "pointerleave"]); this.enableEditing(); return div; } pointerover() { this.parent.drawLayer.addClass(this.#outlineId, "hovered"); } pointerleave() { this.parent.drawLayer.removeClass(this.#outlineId, "hovered"); } #keydown(event) { HighlightEditor._keyboardManager.exec(this, event); } _moveCaret(direction) { this.parent.unselect(this); switch (direction) { case 0: case 2: this.#setCaret(true); break; case 1: case 3: this.#setCaret(false); break; } } #setCaret(start) { if (!this.#anchorNode) { return; } const selection = window.getSelection(); if (start) { selection.setPosition(this.#anchorNode, this.#anchorOffset); } else { selection.setPosition(this.#focusNode, this.#focusOffset); } } select() { super.select(); if (!this.#outlineId) { return; } this.parent?.drawLayer.removeClass(this.#outlineId, "hovered"); this.parent?.drawLayer.addClass(this.#outlineId, "selected"); } unselect() { super.unselect(); if (!this.#outlineId) { return; } this.parent?.drawLayer.removeClass(this.#outlineId, "selected"); if (!this.#isFreeHighlight) { this.#setCaret(false); } } get _mustFixPosition() { return !this.#isFreeHighlight; } show(visible = this._isVisible) { super.show(visible); if (this.parent) { this.parent.drawLayer.show(this.#id, visible); this.parent.drawLayer.show(this.#outlineId, visible); } } #getRotation() { return this.#isFreeHighlight ? this.rotation : 0; } #serializeBoxes() { if (this.#isFreeHighlight) { return null; } const [pageWidth, pageHeight] = this.pageDimensions; const boxes = this.#boxes; const quadPoints = new Array(boxes.length * 8); let i = 0; for (const { x, y, width, height } of boxes) { const sx = x * pageWidth; const sy = (1 - y - height) * pageHeight; quadPoints[i] = quadPoints[i + 4] = sx; quadPoints[i + 1] = quadPoints[i + 3] = sy; quadPoints[i + 2] = quadPoints[i + 6] = sx + width * pageWidth; quadPoints[i + 5] = quadPoints[i + 7] = sy + height * pageHeight; i += 8; } return quadPoints; } #serializeOutlines(rect) { return this.#highlightOutlines.serialize(rect, this.#getRotation()); } static startHighlighting(parent, isLTR, { target: textLayer, x, y }) { const { x: layerX, y: layerY, width: parentWidth, height: parentHeight } = textLayer.getBoundingClientRect(); const pointerMove = e => { this.#highlightMove(parent, e); }; const pointerDownOptions = { capture: true, passive: false }; const pointerDown = e => { e.preventDefault(); e.stopPropagation(); }; const pointerUpCallback = e => { textLayer.removeEventListener("pointermove", pointerMove); window.removeEventListener("blur", pointerUpCallback); window.removeEventListener("pointerup", pointerUpCallback); window.removeEventListener("pointerdown", pointerDown, pointerDownOptions); window.removeEventListener("contextmenu", noContextMenu); this.#endHighlight(parent, e); }; window.addEventListener("blur", pointerUpCallback); window.addEventListener("pointerup", pointerUpCallback); window.addEventListener("pointerdown", pointerDown, pointerDownOptions); window.addEventListener("contextmenu", noContextMenu); textLayer.addEventListener("pointermove", pointerMove); this._freeHighlight = new FreeOutliner({ x, y }, [layerX, layerY, parentWidth, parentHeight], parent.scale, this._defaultThickness / 2, isLTR, 0.001); ({ id: this._freeHighlightId, clipPathId: this._freeHighlightClipId } = parent.drawLayer.highlight(this._freeHighlight, this._defaultColor, this._defaultOpacity, true)); } static #highlightMove(parent, event) { if (this._freeHighlight.add(event)) { parent.drawLayer.updatePath(this._freeHighlightId, this._freeHighlight); } } static #endHighlight(parent, event) { if (!this._freeHighlight.isEmpty()) { parent.createAndAddNewEditor(event, false, { highlightId: this._freeHighlightId, highlightOutlines: this._freeHighlight.getOutlines(), clipPathId: this._freeHighlightClipId, methodOfCreation: "main_toolbar" }); } else { parent.drawLayer.removeFreeHighlight(this._freeHighlightId); } this._freeHighlightId = -1; this._freeHighlight = null; this._freeHighlightClipId = ""; } static deserialize(data, parent, uiManager) { const editor = super.deserialize(data, parent, uiManager); const { rect: [blX, blY, trX, trY], color, quadPoints } = data; editor.color = Util.makeHexColor(...color); editor.#opacity = data.opacity; const [pageWidth, pageHeight] = editor.pageDimensions; editor.width = (trX - blX) / pageWidth; editor.height = (trY - blY) / pageHeight; const boxes = editor.#boxes = []; for (let i = 0; i < quadPoints.length; i += 8) { boxes.push({ x: (quadPoints[4] - trX) / pageWidth, y: (trY - (1 - quadPoints[i + 5])) / pageHeight, width: (quadPoints[i + 2] - quadPoints[i]) / pageWidth, height: (quadPoints[i + 5] - quadPoints[i + 1]) / pageHeight }); } editor.#createOutlines(); return editor; } serialize(isForCopying = false) { if (this.isEmpty() || isForCopying) { return null; } const rect = this.getRect(0, 0); const color = AnnotationEditor._colorManager.convert(this.color); return { annotationType: AnnotationEditorType.HIGHLIGHT, color, opacity: this.#opacity, thickness: this.#thickness, quadPoints: this.#serializeBoxes(), outlines: this.#serializeOutlines(rect), pageIndex: this.pageIndex, rect, rotation: this.#getRotation(), structTreeParentId: this._structTreeParentId }; } static canCreateNewEmptyEditor() { return false; } } ;// CONCATENATED MODULE: ./src/display/editor/ink.js class InkEditor extends AnnotationEditor { #baseHeight = 0; #baseWidth = 0; #boundCanvasPointermove = this.canvasPointermove.bind(this); #boundCanvasPointerleave = this.canvasPointerleave.bind(this); #boundCanvasPointerup = this.canvasPointerup.bind(this); #boundCanvasPointerdown = this.canvasPointerdown.bind(this); #canvasContextMenuTimeoutId = null; #currentPath2D = new Path2D(); #disableEditing = false; #hasSomethingToDraw = false; #isCanvasInitialized = false; #observer = null; #realWidth = 0; #realHeight = 0; #requestFrameCallback = null; static _defaultColor = null; static _defaultOpacity = 1; static _defaultThickness = 1; static _type = "ink"; static _editorType = AnnotationEditorType.INK; constructor(params) { super({ ...params, name: "inkEditor" }); this.color = params.color || null; this.thickness = params.thickness || null; this.opacity = params.opacity || null; this.paths = []; this.bezierPath2D = []; this.allRawPaths = []; this.currentPath = []; this.scaleFactor = 1; this.translationX = this.translationY = 0; this.x = 0; this.y = 0; this._willKeepAspectRatio = true; } static initialize(l10n, uiManager) { AnnotationEditor.initialize(l10n, uiManager); } static updateDefaultParams(type, value) { switch (type) { case AnnotationEditorParamsType.INK_THICKNESS: InkEditor._defaultThickness = value; break; case AnnotationEditorParamsType.INK_COLOR: InkEditor._defaultColor = value; break; case AnnotationEditorParamsType.INK_OPACITY: InkEditor._defaultOpacity = value / 100; break; } } updateParams(type, value) { switch (type) { case AnnotationEditorParamsType.INK_THICKNESS: this.#updateThickness(value); break; case AnnotationEditorParamsType.INK_COLOR: this.#updateColor(value); break; case AnnotationEditorParamsType.INK_OPACITY: this.#updateOpacity(value); break; } } static get defaultPropertiesToUpdate() { return [[AnnotationEditorParamsType.INK_THICKNESS, InkEditor._defaultThickness], [AnnotationEditorParamsType.INK_COLOR, InkEditor._defaultColor || AnnotationEditor._defaultLineColor], [AnnotationEditorParamsType.INK_OPACITY, Math.round(InkEditor._defaultOpacity * 100)]]; } get propertiesToUpdate() { return [[AnnotationEditorParamsType.INK_THICKNESS, this.thickness || InkEditor._defaultThickness], [AnnotationEditorParamsType.INK_COLOR, this.color || InkEditor._defaultColor || AnnotationEditor._defaultLineColor], [AnnotationEditorParamsType.INK_OPACITY, Math.round(100 * (this.opacity ?? InkEditor._defaultOpacity))]]; } #updateThickness(thickness) { const setThickness = th => { this.thickness = th; this.#fitToContent(); }; const savedThickness = this.thickness; this.addCommands({ cmd: setThickness.bind(this, thickness), undo: setThickness.bind(this, savedThickness), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.INK_THICKNESS, overwriteIfSameType: true, keepUndo: true }); } #updateColor(color) { const setColor = col => { this.color = col; this.#redraw(); }; const savedColor = this.color; this.addCommands({ cmd: setColor.bind(this, color), undo: setColor.bind(this, savedColor), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.INK_COLOR, overwriteIfSameType: true, keepUndo: true }); } #updateOpacity(opacity) { const setOpacity = op => { this.opacity = op; this.#redraw(); }; opacity /= 100; const savedOpacity = this.opacity; this.addCommands({ cmd: setOpacity.bind(this, opacity), undo: setOpacity.bind(this, savedOpacity), post: this._uiManager.updateUI.bind(this._uiManager, this), mustExec: true, type: AnnotationEditorParamsType.INK_OPACITY, overwriteIfSameType: true, keepUndo: true }); } rebuild() { if (!this.parent) { return; } super.rebuild(); if (this.div === null) { return; } if (!this.canvas) { this.#createCanvas(); this.#createObserver(); } if (!this.isAttachedToDOM) { this.parent.add(this); this.#setCanvasDims(); } this.#fitToContent(); } remove() { if (this.canvas === null) { return; } if (!this.isEmpty()) { this.commit(); } this.canvas.width = this.canvas.height = 0; this.canvas.remove(); this.canvas = null; if (this.#canvasContextMenuTimeoutId) { clearTimeout(this.#canvasContextMenuTimeoutId); this.#canvasContextMenuTimeoutId = null; } this.#observer.disconnect(); this.#observer = null; super.remove(); } setParent(parent) { if (!this.parent && parent) { this._uiManager.removeShouldRescale(this); } else if (this.parent && parent === null) { this._uiManager.addShouldRescale(this); } super.setParent(parent); } onScaleChanging() { const [parentWidth, parentHeight] = this.parentDimensions; const width = this.width * parentWidth; const height = this.height * parentHeight; this.setDimensions(width, height); } enableEditMode() { if (this.#disableEditing || this.canvas === null) { return; } super.enableEditMode(); this._isDraggable = false; this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); } disableEditMode() { if (!this.isInEditMode() || this.canvas === null) { return; } super.disableEditMode(); this._isDraggable = !this.isEmpty(); this.div.classList.remove("editing"); this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); } onceAdded() { this._isDraggable = !this.isEmpty(); } isEmpty() { return this.paths.length === 0 || this.paths.length === 1 && this.paths[0].length === 0; } #getInitialBBox() { const { parentRotation, parentDimensions: [width, height] } = this; switch (parentRotation) { case 90: return [0, height, height, width]; case 180: return [width, height, width, height]; case 270: return [width, 0, height, width]; default: return [0, 0, width, height]; } } #setStroke() { const { ctx, color, opacity, thickness, parentScale, scaleFactor } = this; ctx.lineWidth = thickness * parentScale / scaleFactor; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.miterLimit = 10; ctx.strokeStyle = `${color}${opacityToHex(opacity)}`; } #startDrawing(x, y) { this.canvas.addEventListener("contextmenu", noContextMenu); this.canvas.addEventListener("pointerleave", this.#boundCanvasPointerleave); this.canvas.addEventListener("pointermove", this.#boundCanvasPointermove); this.canvas.addEventListener("pointerup", this.#boundCanvasPointerup); this.canvas.removeEventListener("pointerdown", this.#boundCanvasPointerdown); this.isEditing = true; if (!this.#isCanvasInitialized) { this.#isCanvasInitialized = true; this.#setCanvasDims(); this.thickness ||= InkEditor._defaultThickness; this.color ||= InkEditor._defaultColor || AnnotationEditor._defaultLineColor; this.opacity ??= InkEditor._defaultOpacity; } this.currentPath.push([x, y]); this.#hasSomethingToDraw = false; this.#setStroke(); this.#requestFrameCallback = () => { this.#drawPoints(); if (this.#requestFrameCallback) { window.requestAnimationFrame(this.#requestFrameCallback); } }; window.requestAnimationFrame(this.#requestFrameCallback); } #draw(x, y) { const [lastX, lastY] = this.currentPath.at(-1); if (this.currentPath.length > 1 && x === lastX && y === lastY) { return; } const currentPath = this.currentPath; let path2D = this.#currentPath2D; currentPath.push([x, y]); this.#hasSomethingToDraw = true; if (currentPath.length <= 2) { path2D.moveTo(...currentPath[0]); path2D.lineTo(x, y); return; } if (currentPath.length === 3) { this.#currentPath2D = path2D = new Path2D(); path2D.moveTo(...currentPath[0]); } this.#makeBezierCurve(path2D, ...currentPath.at(-3), ...currentPath.at(-2), x, y); } #endPath() { if (this.currentPath.length === 0) { return; } const lastPoint = this.currentPath.at(-1); this.#currentPath2D.lineTo(...lastPoint); } #stopDrawing(x, y) { this.#requestFrameCallback = null; x = Math.min(Math.max(x, 0), this.canvas.width); y = Math.min(Math.max(y, 0), this.canvas.height); this.#draw(x, y); this.#endPath(); let bezier; if (this.currentPath.length !== 1) { bezier = this.#generateBezierPoints(); } else { const xy = [x, y]; bezier = [[xy, xy.slice(), xy.slice(), xy]]; } const path2D = this.#currentPath2D; const currentPath = this.currentPath; this.currentPath = []; this.#currentPath2D = new Path2D(); const cmd = () => { this.allRawPaths.push(currentPath); this.paths.push(bezier); this.bezierPath2D.push(path2D); this._uiManager.rebuild(this); }; const undo = () => { this.allRawPaths.pop(); this.paths.pop(); this.bezierPath2D.pop(); if (this.paths.length === 0) { this.remove(); } else { if (!this.canvas) { this.#createCanvas(); this.#createObserver(); } this.#fitToContent(); } }; this.addCommands({ cmd, undo, mustExec: true }); } #drawPoints() { if (!this.#hasSomethingToDraw) { return; } this.#hasSomethingToDraw = false; const thickness = Math.ceil(this.thickness * this.parentScale); const lastPoints = this.currentPath.slice(-3); const x = lastPoints.map(xy => xy[0]); const y = lastPoints.map(xy => xy[1]); const xMin = Math.min(...x) - thickness; const xMax = Math.max(...x) + thickness; const yMin = Math.min(...y) - thickness; const yMax = Math.max(...y) + thickness; const { ctx } = this; ctx.save(); ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); for (const path of this.bezierPath2D) { ctx.stroke(path); } ctx.stroke(this.#currentPath2D); ctx.restore(); } #makeBezierCurve(path2D, x0, y0, x1, y1, x2, y2) { const prevX = (x0 + x1) / 2; const prevY = (y0 + y1) / 2; const x3 = (x1 + x2) / 2; const y3 = (y1 + y2) / 2; path2D.bezierCurveTo(prevX + 2 * (x1 - prevX) / 3, prevY + 2 * (y1 - prevY) / 3, x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3, x3, y3); } #generateBezierPoints() { const path = this.currentPath; if (path.length <= 2) { return [[path[0], path[0], path.at(-1), path.at(-1)]]; } const bezierPoints = []; let i; let [x0, y0] = path[0]; for (i = 1; i < path.length - 2; i++) { const [x1, y1] = path[i]; const [x2, y2] = path[i + 1]; const x3 = (x1 + x2) / 2; const y3 = (y1 + y2) / 2; const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; const control2 = [x3 + 2 * (x1 - x3) / 3, y3 + 2 * (y1 - y3) / 3]; bezierPoints.push([[x0, y0], control1, control2, [x3, y3]]); [x0, y0] = [x3, y3]; } const [x1, y1] = path[i]; const [x2, y2] = path[i + 1]; const control1 = [x0 + 2 * (x1 - x0) / 3, y0 + 2 * (y1 - y0) / 3]; const control2 = [x2 + 2 * (x1 - x2) / 3, y2 + 2 * (y1 - y2) / 3]; bezierPoints.push([[x0, y0], control1, control2, [x2, y2]]); return bezierPoints; } #redraw() { if (this.isEmpty()) { this.#updateTransform(); return; } this.#setStroke(); const { canvas, ctx } = this; ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.clearRect(0, 0, canvas.width, canvas.height); this.#updateTransform(); for (const path of this.bezierPath2D) { ctx.stroke(path); } } commit() { if (this.#disableEditing) { return; } super.commit(); this.isEditing = false; this.disableEditMode(); this.setInForeground(); this.#disableEditing = true; this.div.classList.add("disabled"); this.#fitToContent(true); this.select(); this.parent.addInkEditorIfNeeded(true); this.moveInDOM(); this.div.focus({ preventScroll: true }); } focusin(event) { if (!this._focusEventsAllowed) { return; } super.focusin(event); this.enableEditMode(); } canvasPointerdown(event) { if (event.button !== 0 || !this.isInEditMode() || this.#disableEditing) { return; } this.setInForeground(); event.preventDefault(); if (!this.div.contains(document.activeElement)) { this.div.focus({ preventScroll: true }); } this.#startDrawing(event.offsetX, event.offsetY); } canvasPointermove(event) { event.preventDefault(); this.#draw(event.offsetX, event.offsetY); } canvasPointerup(event) { event.preventDefault(); this.#endDrawing(event); } canvasPointerleave(event) { this.#endDrawing(event); } #endDrawing(event) { this.canvas.removeEventListener("pointerleave", this.#boundCanvasPointerleave); this.canvas.removeEventListener("pointermove", this.#boundCanvasPointermove); this.canvas.removeEventListener("pointerup", this.#boundCanvasPointerup); this.canvas.addEventListener("pointerdown", this.#boundCanvasPointerdown); if (this.#canvasContextMenuTimeoutId) { clearTimeout(this.#canvasContextMenuTimeoutId); } this.#canvasContextMenuTimeoutId = setTimeout(() => { this.#canvasContextMenuTimeoutId = null; this.canvas.removeEventListener("contextmenu", noContextMenu); }, 10); this.#stopDrawing(event.offsetX, event.offsetY); this.addToAnnotationStorage(); this.setInBackground(); } #createCanvas() { this.canvas = document.createElement("canvas"); this.canvas.width = this.canvas.height = 0; this.canvas.className = "inkEditorCanvas"; this.canvas.setAttribute("data-l10n-id", "pdfjs-ink-canvas"); this.div.append(this.canvas); this.ctx = this.canvas.getContext("2d"); } #createObserver() { this.#observer = new ResizeObserver(entries => { const rect = entries[0].contentRect; if (rect.width && rect.height) { this.setDimensions(rect.width, rect.height); } }); this.#observer.observe(this.div); } get isResizable() { return !this.isEmpty() && this.#disableEditing; } render() { if (this.div) { return this.div; } let baseX, baseY; if (this.width) { baseX = this.x; baseY = this.y; } super.render(); this.div.setAttribute("data-l10n-id", "pdfjs-ink"); const [x, y, w, h] = this.#getInitialBBox(); this.setAt(x, y, 0, 0); this.setDims(w, h); this.#createCanvas(); if (this.width) { const [parentWidth, parentHeight] = this.parentDimensions; this.setAspectRatio(this.width * parentWidth, this.height * parentHeight); this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); this.#isCanvasInitialized = true; this.#setCanvasDims(); this.setDims(this.width * parentWidth, this.height * parentHeight); this.#redraw(); this.div.classList.add("disabled"); } else { this.div.classList.add("editing"); this.enableEditMode(); } this.#createObserver(); return this.div; } #setCanvasDims() { if (!this.#isCanvasInitialized) { return; } const [parentWidth, parentHeight] = this.parentDimensions; this.canvas.width = Math.ceil(this.width * parentWidth); this.canvas.height = Math.ceil(this.height * parentHeight); this.#updateTransform(); } setDimensions(width, height) { const roundedWidth = Math.round(width); const roundedHeight = Math.round(height); if (this.#realWidth === roundedWidth && this.#realHeight === roundedHeight) { return; } this.#realWidth = roundedWidth; this.#realHeight = roundedHeight; this.canvas.style.visibility = "hidden"; const [parentWidth, parentHeight] = this.parentDimensions; this.width = width / parentWidth; this.height = height / parentHeight; this.fixAndSetPosition(); if (this.#disableEditing) { this.#setScaleFactor(width, height); } this.#setCanvasDims(); this.#redraw(); this.canvas.style.visibility = "visible"; this.fixDims(); } #setScaleFactor(width, height) { const padding = this.#getPadding(); const scaleFactorW = (width - padding) / this.#baseWidth; const scaleFactorH = (height - padding) / this.#baseHeight; this.scaleFactor = Math.min(scaleFactorW, scaleFactorH); } #updateTransform() { const padding = this.#getPadding() / 2; this.ctx.setTransform(this.scaleFactor, 0, 0, this.scaleFactor, this.translationX * this.scaleFactor + padding, this.translationY * this.scaleFactor + padding); } static #buildPath2D(bezier) { const path2D = new Path2D(); for (let i = 0, ii = bezier.length; i < ii; i++) { const [first, control1, control2, second] = bezier[i]; if (i === 0) { path2D.moveTo(...first); } path2D.bezierCurveTo(control1[0], control1[1], control2[0], control2[1], second[0], second[1]); } return path2D; } static #toPDFCoordinates(points, rect, rotation) { const [blX, blY, trX, trY] = rect; switch (rotation) { case 0: for (let i = 0, ii = points.length; i < ii; i += 2) { points[i] += blX; points[i + 1] = trY - points[i + 1]; } break; case 90: for (let i = 0, ii = points.length; i < ii; i += 2) { const x = points[i]; points[i] = points[i + 1] + blX; points[i + 1] = x + blY; } break; case 180: for (let i = 0, ii = points.length; i < ii; i += 2) { points[i] = trX - points[i]; points[i + 1] += blY; } break; case 270: for (let i = 0, ii = points.length; i < ii; i += 2) { const x = points[i]; points[i] = trX - points[i + 1]; points[i + 1] = trY - x; } break; default: throw new Error("Invalid rotation"); } return points; } static #fromPDFCoordinates(points, rect, rotation) { const [blX, blY, trX, trY] = rect; switch (rotation) { case 0: for (let i = 0, ii = points.length; i < ii; i += 2) { points[i] -= blX; points[i + 1] = trY - points[i + 1]; } break; case 90: for (let i = 0, ii = points.length; i < ii; i += 2) { const x = points[i]; points[i] = points[i + 1] - blY; points[i + 1] = x - blX; } break; case 180: for (let i = 0, ii = points.length; i < ii; i += 2) { points[i] = trX - points[i]; points[i + 1] -= blY; } break; case 270: for (let i = 0, ii = points.length; i < ii; i += 2) { const x = points[i]; points[i] = trY - points[i + 1]; points[i + 1] = trX - x; } break; default: throw new Error("Invalid rotation"); } return points; } #serializePaths(s, tx, ty, rect) { const paths = []; const padding = this.thickness / 2; const shiftX = s * tx + padding; const shiftY = s * ty + padding; for (const bezier of this.paths) { const buffer = []; const points = []; for (let j = 0, jj = bezier.length; j < jj; j++) { const [first, control1, control2, second] = bezier[j]; if (first[0] === second[0] && first[1] === second[1] && jj === 1) { const p0 = s * first[0] + shiftX; const p1 = s * first[1] + shiftY; buffer.push(p0, p1); points.push(p0, p1); break; } const p10 = s * first[0] + shiftX; const p11 = s * first[1] + shiftY; const p20 = s * control1[0] + shiftX; const p21 = s * control1[1] + shiftY; const p30 = s * control2[0] + shiftX; const p31 = s * control2[1] + shiftY; const p40 = s * second[0] + shiftX; const p41 = s * second[1] + shiftY; if (j === 0) { buffer.push(p10, p11); points.push(p10, p11); } buffer.push(p20, p21, p30, p31, p40, p41); points.push(p20, p21); if (j === jj - 1) { points.push(p40, p41); } } paths.push({ bezier: InkEditor.#toPDFCoordinates(buffer, rect, this.rotation), points: InkEditor.#toPDFCoordinates(points, rect, this.rotation) }); } return paths; } #getBbox() { let xMin = Infinity; let xMax = -Infinity; let yMin = Infinity; let yMax = -Infinity; for (const path of this.paths) { for (const [first, control1, control2, second] of path) { const bbox = Util.bezierBoundingBox(...first, ...control1, ...control2, ...second); xMin = Math.min(xMin, bbox[0]); yMin = Math.min(yMin, bbox[1]); xMax = Math.max(xMax, bbox[2]); yMax = Math.max(yMax, bbox[3]); } } return [xMin, yMin, xMax, yMax]; } #getPadding() { return this.#disableEditing ? Math.ceil(this.thickness * this.parentScale) : 0; } #fitToContent(firstTime = false) { if (this.isEmpty()) { return; } if (!this.#disableEditing) { this.#redraw(); return; } const bbox = this.#getBbox(); const padding = this.#getPadding(); this.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); this.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); const width = Math.ceil(padding + this.#baseWidth * this.scaleFactor); const height = Math.ceil(padding + this.#baseHeight * this.scaleFactor); const [parentWidth, parentHeight] = this.parentDimensions; this.width = width / parentWidth; this.height = height / parentHeight; this.setAspectRatio(width, height); const prevTranslationX = this.translationX; const prevTranslationY = this.translationY; this.translationX = -bbox[0]; this.translationY = -bbox[1]; this.#setCanvasDims(); this.#redraw(); this.#realWidth = width; this.#realHeight = height; this.setDims(width, height); const unscaledPadding = firstTime ? padding / this.scaleFactor / 2 : 0; this.translate(prevTranslationX - this.translationX - unscaledPadding, prevTranslationY - this.translationY - unscaledPadding); } static deserialize(data, parent, uiManager) { if (data instanceof InkAnnotationElement) { return null; } const editor = super.deserialize(data, parent, uiManager); editor.thickness = data.thickness; editor.color = Util.makeHexColor(...data.color); editor.opacity = data.opacity; const [pageWidth, pageHeight] = editor.pageDimensions; const width = editor.width * pageWidth; const height = editor.height * pageHeight; const scaleFactor = editor.parentScale; const padding = data.thickness / 2; editor.#disableEditing = true; editor.#realWidth = Math.round(width); editor.#realHeight = Math.round(height); const { paths, rect, rotation } = data; for (let { bezier } of paths) { bezier = InkEditor.#fromPDFCoordinates(bezier, rect, rotation); const path = []; editor.paths.push(path); let p0 = scaleFactor * (bezier[0] - padding); let p1 = scaleFactor * (bezier[1] - padding); for (let i = 2, ii = bezier.length; i < ii; i += 6) { const p10 = scaleFactor * (bezier[i] - padding); const p11 = scaleFactor * (bezier[i + 1] - padding); const p20 = scaleFactor * (bezier[i + 2] - padding); const p21 = scaleFactor * (bezier[i + 3] - padding); const p30 = scaleFactor * (bezier[i + 4] - padding); const p31 = scaleFactor * (bezier[i + 5] - padding); path.push([[p0, p1], [p10, p11], [p20, p21], [p30, p31]]); p0 = p30; p1 = p31; } const path2D = this.#buildPath2D(path); editor.bezierPath2D.push(path2D); } const bbox = editor.#getBbox(); editor.#baseWidth = Math.max(AnnotationEditor.MIN_SIZE, bbox[2] - bbox[0]); editor.#baseHeight = Math.max(AnnotationEditor.MIN_SIZE, bbox[3] - bbox[1]); editor.#setScaleFactor(width, height); return editor; } serialize() { if (this.isEmpty()) { return null; } const rect = this.getRect(0, 0); const color = AnnotationEditor._colorManager.convert(this.ctx.strokeStyle); return { annotationType: AnnotationEditorType.INK, color, thickness: this.thickness, opacity: this.opacity, paths: this.#serializePaths(this.scaleFactor / this.parentScale, this.translationX, this.translationY, rect), pageIndex: this.pageIndex, rect, rotation: this.rotation, structTreeParentId: this._structTreeParentId }; } } ;// CONCATENATED MODULE: ./src/display/editor/stamp.js class StampEditor extends AnnotationEditor { #bitmap = null; #bitmapId = null; #bitmapPromise = null; #bitmapUrl = null; #bitmapFile = null; #bitmapFileName = ""; #canvas = null; #observer = null; #resizeTimeoutId = null; #isSvg = false; #hasBeenAddedInUndoStack = false; static _type = "stamp"; static _editorType = AnnotationEditorType.STAMP; constructor(params) { super({ ...params, name: "stampEditor" }); this.#bitmapUrl = params.bitmapUrl; this.#bitmapFile = params.bitmapFile; } static initialize(l10n, uiManager) { AnnotationEditor.initialize(l10n, uiManager); } static get supportedTypes() { const types = ["apng", "avif", "bmp", "gif", "jpeg", "png", "svg+xml", "webp", "x-icon"]; return shadow(this, "supportedTypes", types.map(type => `image/${type}`)); } static get supportedTypesStr() { return shadow(this, "supportedTypesStr", this.supportedTypes.join(",")); } static isHandlingMimeForPasting(mime) { return this.supportedTypes.includes(mime); } static paste(item, parent) { parent.pasteEditor(AnnotationEditorType.STAMP, { bitmapFile: item.getAsFile() }); } #getBitmapFetched(data, fromId = false) { if (!data) { this.remove(); return; } this.#bitmap = data.bitmap; if (!fromId) { this.#bitmapId = data.id; this.#isSvg = data.isSvg; } if (data.file) { this.#bitmapFileName = data.file.name; } this.#createCanvas(); } #getBitmapDone() { this.#bitmapPromise = null; this._uiManager.enableWaiting(false); if (this.#canvas) { this.div.focus(); } } #getBitmap() { if (this.#bitmapId) { this._uiManager.enableWaiting(true); this._uiManager.imageManager.getFromId(this.#bitmapId).then(data => this.#getBitmapFetched(data, true)).finally(() => this.#getBitmapDone()); return; } if (this.#bitmapUrl) { const url = this.#bitmapUrl; this.#bitmapUrl = null; this._uiManager.enableWaiting(true); this.#bitmapPromise = this._uiManager.imageManager.getFromUrl(url).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); return; } if (this.#bitmapFile) { const file = this.#bitmapFile; this.#bitmapFile = null; this._uiManager.enableWaiting(true); this.#bitmapPromise = this._uiManager.imageManager.getFromFile(file).then(data => this.#getBitmapFetched(data)).finally(() => this.#getBitmapDone()); return; } const input = document.createElement("input"); input.type = "file"; input.accept = StampEditor.supportedTypesStr; this.#bitmapPromise = new Promise(resolve => { input.addEventListener("change", async () => { if (!input.files || input.files.length === 0) { this.remove(); } else { this._uiManager.enableWaiting(true); const data = await this._uiManager.imageManager.getFromFile(input.files[0]); this.#getBitmapFetched(data); } resolve(); }); input.addEventListener("cancel", () => { this.remove(); resolve(); }); }).finally(() => this.#getBitmapDone()); input.click(); } remove() { if (this.#bitmapId) { this.#bitmap = null; this._uiManager.imageManager.deleteId(this.#bitmapId); this.#canvas?.remove(); this.#canvas = null; this.#observer?.disconnect(); this.#observer = null; if (this.#resizeTimeoutId) { clearTimeout(this.#resizeTimeoutId); this.#resizeTimeoutId = null; } } super.remove(); } rebuild() { if (!this.parent) { if (this.#bitmapId) { this.#getBitmap(); } return; } super.rebuild(); if (this.div === null) { return; } if (this.#bitmapId && this.#canvas === null) { this.#getBitmap(); } if (!this.isAttachedToDOM) { this.parent.add(this); } } onceAdded() { this._isDraggable = true; this.div.focus(); } isEmpty() { return !(this.#bitmapPromise || this.#bitmap || this.#bitmapUrl || this.#bitmapFile || this.#bitmapId); } get isResizable() { return true; } render() { if (this.div) { return this.div; } let baseX, baseY; if (this.width) { baseX = this.x; baseY = this.y; } super.render(); this.div.hidden = true; this.addAltTextButton(); if (this.#bitmap) { this.#createCanvas(); } else { this.#getBitmap(); } if (this.width) { const [parentWidth, parentHeight] = this.parentDimensions; this.setAt(baseX * parentWidth, baseY * parentHeight, this.width * parentWidth, this.height * parentHeight); } return this.div; } #createCanvas() { const { div } = this; let { width, height } = this.#bitmap; const [pageWidth, pageHeight] = this.pageDimensions; const MAX_RATIO = 0.75; if (this.width) { width = this.width * pageWidth; height = this.height * pageHeight; } else if (width > MAX_RATIO * pageWidth || height > MAX_RATIO * pageHeight) { const factor = Math.min(MAX_RATIO * pageWidth / width, MAX_RATIO * pageHeight / height); width *= factor; height *= factor; } const [parentWidth, parentHeight] = this.parentDimensions; this.setDims(width * parentWidth / pageWidth, height * parentHeight / pageHeight); this._uiManager.enableWaiting(false); const canvas = this.#canvas = document.createElement("canvas"); div.append(canvas); div.hidden = false; this.#drawBitmap(width, height); this.#createObserver(); if (!this.#hasBeenAddedInUndoStack) { this.parent.addUndoableEditor(this); this.#hasBeenAddedInUndoStack = true; } this._reportTelemetry({ action: "inserted_image" }); if (this.#bitmapFileName) { canvas.setAttribute("aria-label", this.#bitmapFileName); } } #setDimensions(width, height) { const [parentWidth, parentHeight] = this.parentDimensions; this.width = width / parentWidth; this.height = height / parentHeight; this.setDims(width, height); if (this._initialOptions?.isCentered) { this.center(); } else { this.fixAndSetPosition(); } this._initialOptions = null; if (this.#resizeTimeoutId !== null) { clearTimeout(this.#resizeTimeoutId); } const TIME_TO_WAIT = 200; this.#resizeTimeoutId = setTimeout(() => { this.#resizeTimeoutId = null; this.#drawBitmap(width, height); }, TIME_TO_WAIT); } #scaleBitmap(width, height) { const { width: bitmapWidth, height: bitmapHeight } = this.#bitmap; let newWidth = bitmapWidth; let newHeight = bitmapHeight; let bitmap = this.#bitmap; while (newWidth > 2 * width || newHeight > 2 * height) { const prevWidth = newWidth; const prevHeight = newHeight; if (newWidth > 2 * width) { newWidth = newWidth >= 16384 ? Math.floor(newWidth / 2) - 1 : Math.ceil(newWidth / 2); } if (newHeight > 2 * height) { newHeight = newHeight >= 16384 ? Math.floor(newHeight / 2) - 1 : Math.ceil(newHeight / 2); } const offscreen = new OffscreenCanvas(newWidth, newHeight); const ctx = offscreen.getContext("2d"); ctx.drawImage(bitmap, 0, 0, prevWidth, prevHeight, 0, 0, newWidth, newHeight); bitmap = offscreen.transferToImageBitmap(); } return bitmap; } #drawBitmap(width, height) { width = Math.ceil(width); height = Math.ceil(height); const canvas = this.#canvas; if (!canvas || canvas.width === width && canvas.height === height) { return; } canvas.width = width; canvas.height = height; const bitmap = this.#isSvg ? this.#bitmap : this.#scaleBitmap(width, height); if (this._uiManager.hasMLManager && !this.hasAltText()) { const offscreen = new OffscreenCanvas(width, height); const ctx = offscreen.getContext("2d"); ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); this._uiManager.mlGuess({ service: "image-to-text", request: { data: ctx.getImageData(0, 0, width, height).data, width, height, channels: 4 } }).then(response => { const altText = response?.output || ""; if (this.parent && altText && !this.hasAltText()) { this.altTextData = { altText, decorative: false }; } }); } const ctx = canvas.getContext("2d"); ctx.filter = this._uiManager.hcmFilter; ctx.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, width, height); } getImageForAltText() { return this.#canvas; } #serializeBitmap(toUrl) { if (toUrl) { if (this.#isSvg) { const url = this._uiManager.imageManager.getSvgUrl(this.#bitmapId); if (url) { return url; } } const canvas = document.createElement("canvas"); ({ width: canvas.width, height: canvas.height } = this.#bitmap); const ctx = canvas.getContext("2d"); ctx.drawImage(this.#bitmap, 0, 0); return canvas.toDataURL(); } if (this.#isSvg) { const [pageWidth, pageHeight] = this.pageDimensions; const width = Math.round(this.width * pageWidth * PixelsPerInch.PDF_TO_CSS_UNITS); const height = Math.round(this.height * pageHeight * PixelsPerInch.PDF_TO_CSS_UNITS); const offscreen = new OffscreenCanvas(width, height); const ctx = offscreen.getContext("2d"); ctx.drawImage(this.#bitmap, 0, 0, this.#bitmap.width, this.#bitmap.height, 0, 0, width, height); return offscreen.transferToImageBitmap(); } return structuredClone(this.#bitmap); } #createObserver() { this.#observer = new ResizeObserver(entries => { const rect = entries[0].contentRect; if (rect.width && rect.height) { this.#setDimensions(rect.width, rect.height); } }); this.#observer.observe(this.div); } static deserialize(data, parent, uiManager) { if (data instanceof StampAnnotationElement) { return null; } const editor = super.deserialize(data, parent, uiManager); const { rect, bitmapUrl, bitmapId, isSvg, accessibilityData } = data; if (bitmapId && uiManager.imageManager.isValidId(bitmapId)) { editor.#bitmapId = bitmapId; } else { editor.#bitmapUrl = bitmapUrl; } editor.#isSvg = isSvg; const [parentWidth, parentHeight] = editor.pageDimensions; editor.width = (rect[2] - rect[0]) / parentWidth; editor.height = (rect[3] - rect[1]) / parentHeight; if (accessibilityData) { editor.altTextData = accessibilityData; } return editor; } serialize(isForCopying = false, context = null) { if (this.isEmpty()) { return null; } const serialized = { annotationType: AnnotationEditorType.STAMP, bitmapId: this.#bitmapId, pageIndex: this.pageIndex, rect: this.getRect(0, 0), rotation: this.rotation, isSvg: this.#isSvg, structTreeParentId: this._structTreeParentId }; if (isForCopying) { serialized.bitmapUrl = this.#serializeBitmap(true); serialized.accessibilityData = this.altTextData; return serialized; } const { decorative, altText } = this.altTextData; if (!decorative && altText) { serialized.accessibilityData = { type: "Figure", alt: altText }; } if (context === null) { return serialized; } context.stamps ||= new Map(); const area = this.#isSvg ? (serialized.rect[2] - serialized.rect[0]) * (serialized.rect[3] - serialized.rect[1]) : null; if (!context.stamps.has(this.#bitmapId)) { context.stamps.set(this.#bitmapId, { area, serialized }); serialized.bitmap = this.#serializeBitmap(false); } else if (this.#isSvg) { const prevData = context.stamps.get(this.#bitmapId); if (area > prevData.area) { prevData.area = area; prevData.serialized.bitmap.close(); prevData.serialized.bitmap = this.#serializeBitmap(false); } } return serialized; } } ;// CONCATENATED MODULE: ./src/display/editor/annotation_editor_layer.js class AnnotationEditorLayer { #accessibilityManager; #allowClick = false; #annotationLayer = null; #boundPointerup = null; #boundPointerdown = null; #boundTextLayerPointerDown = null; #editorFocusTimeoutId = null; #editors = new Map(); #hadPointerDown = false; #isCleaningUp = false; #isDisabling = false; #textLayer = null; #uiManager; static _initialized = false; static #editorTypes = new Map([FreeTextEditor, InkEditor, StampEditor, HighlightEditor].map(type => [type._editorType, type])); constructor({ uiManager, pageIndex, div, accessibilityManager, annotationLayer, drawLayer, textLayer, viewport, l10n }) { const editorTypes = [...AnnotationEditorLayer.#editorTypes.values()]; if (!AnnotationEditorLayer._initialized) { AnnotationEditorLayer._initialized = true; for (const editorType of editorTypes) { editorType.initialize(l10n, uiManager); } } uiManager.registerEditorTypes(editorTypes); this.#uiManager = uiManager; this.pageIndex = pageIndex; this.div = div; this.#accessibilityManager = accessibilityManager; this.#annotationLayer = annotationLayer; this.viewport = viewport; this.#textLayer = textLayer; this.drawLayer = drawLayer; this.#uiManager.addLayer(this); } get isEmpty() { return this.#editors.size === 0; } get isInvisible() { return this.isEmpty && this.#uiManager.getMode() === AnnotationEditorType.NONE; } updateToolbar(mode) { this.#uiManager.updateToolbar(mode); } updateMode(mode = this.#uiManager.getMode()) { this.#cleanup(); switch (mode) { case AnnotationEditorType.NONE: this.disableTextSelection(); this.togglePointerEvents(false); this.toggleAnnotationLayerPointerEvents(true); this.disableClick(); return; case AnnotationEditorType.INK: this.addInkEditorIfNeeded(false); this.disableTextSelection(); this.togglePointerEvents(true); this.disableClick(); break; case AnnotationEditorType.HIGHLIGHT: this.enableTextSelection(); this.togglePointerEvents(false); this.disableClick(); break; default: this.disableTextSelection(); this.togglePointerEvents(true); this.enableClick(); } this.toggleAnnotationLayerPointerEvents(false); const { classList } = this.div; for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { classList.toggle(`${editorType._type}Editing`, mode === editorType._editorType); } this.div.hidden = false; } hasTextLayer(textLayer) { return textLayer === this.#textLayer?.div; } addInkEditorIfNeeded(isCommitting) { if (this.#uiManager.getMode() !== AnnotationEditorType.INK) { return; } if (!isCommitting) { for (const editor of this.#editors.values()) { if (editor.isEmpty()) { editor.setInBackground(); return; } } } const editor = this.createAndAddNewEditor({ offsetX: 0, offsetY: 0 }, false); editor.setInBackground(); } setEditingState(isEditing) { this.#uiManager.setEditingState(isEditing); } addCommands(params) { this.#uiManager.addCommands(params); } togglePointerEvents(enabled = false) { this.div.classList.toggle("disabled", !enabled); } toggleAnnotationLayerPointerEvents(enabled = false) { this.#annotationLayer?.div.classList.toggle("disabled", !enabled); } enable() { this.div.tabIndex = 0; this.togglePointerEvents(true); const annotationElementIds = new Set(); for (const editor of this.#editors.values()) { editor.enableEditing(); editor.show(true); if (editor.annotationElementId) { this.#uiManager.removeChangedExistingAnnotation(editor); annotationElementIds.add(editor.annotationElementId); } } if (!this.#annotationLayer) { return; } const editables = this.#annotationLayer.getEditableAnnotations(); for (const editable of editables) { editable.hide(); if (this.#uiManager.isDeletedAnnotationElement(editable.data.id)) { continue; } if (annotationElementIds.has(editable.data.id)) { continue; } const editor = this.deserialize(editable); if (!editor) { continue; } this.addOrRebuild(editor); editor.enableEditing(); } } disable() { this.#isDisabling = true; this.div.tabIndex = -1; this.togglePointerEvents(false); const changedAnnotations = new Map(); const resetAnnotations = new Map(); for (const editor of this.#editors.values()) { editor.disableEditing(); if (!editor.annotationElementId) { continue; } if (editor.serialize() !== null) { changedAnnotations.set(editor.annotationElementId, editor); continue; } else { resetAnnotations.set(editor.annotationElementId, editor); } this.getEditableAnnotation(editor.annotationElementId)?.show(); editor.remove(); } if (this.#annotationLayer) { const editables = this.#annotationLayer.getEditableAnnotations(); for (const editable of editables) { const { id } = editable.data; if (this.#uiManager.isDeletedAnnotationElement(id)) { continue; } let editor = resetAnnotations.get(id); if (editor) { editor.resetAnnotationElement(editable); editor.show(false); editable.show(); continue; } editor = changedAnnotations.get(id); if (editor) { this.#uiManager.addChangedExistingAnnotation(editor); editor.renderAnnotationElement(editable); editor.show(false); } editable.show(); } } this.#cleanup(); if (this.isEmpty) { this.div.hidden = true; } const { classList } = this.div; for (const editorType of AnnotationEditorLayer.#editorTypes.values()) { classList.remove(`${editorType._type}Editing`); } this.disableTextSelection(); this.toggleAnnotationLayerPointerEvents(true); this.#isDisabling = false; } getEditableAnnotation(id) { return this.#annotationLayer?.getEditableAnnotation(id) || null; } setActiveEditor(editor) { const currentActive = this.#uiManager.getActive(); if (currentActive === editor) { return; } this.#uiManager.setActiveEditor(editor); } enableTextSelection() { this.div.tabIndex = -1; if (this.#textLayer?.div && !this.#boundTextLayerPointerDown) { this.#boundTextLayerPointerDown = this.#textLayerPointerDown.bind(this); this.#textLayer.div.addEventListener("pointerdown", this.#boundTextLayerPointerDown); this.#textLayer.div.classList.add("highlighting"); } } disableTextSelection() { this.div.tabIndex = 0; if (this.#textLayer?.div && this.#boundTextLayerPointerDown) { this.#textLayer.div.removeEventListener("pointerdown", this.#boundTextLayerPointerDown); this.#boundTextLayerPointerDown = null; this.#textLayer.div.classList.remove("highlighting"); } } #textLayerPointerDown(event) { this.#uiManager.unselectAll(); if (event.target === this.#textLayer.div) { const { isMac } = util_FeatureTest.platform; if (event.button !== 0 || event.ctrlKey && isMac) { return; } this.#uiManager.showAllEditors("highlight", true, true); this.#textLayer.div.classList.add("free"); HighlightEditor.startHighlighting(this, this.#uiManager.direction === "ltr", event); this.#textLayer.div.addEventListener("pointerup", () => { this.#textLayer.div.classList.remove("free"); }, { once: true }); event.preventDefault(); } } enableClick() { if (this.#boundPointerdown) { return; } this.#boundPointerdown = this.pointerdown.bind(this); this.#boundPointerup = this.pointerup.bind(this); this.div.addEventListener("pointerdown", this.#boundPointerdown); this.div.addEventListener("pointerup", this.#boundPointerup); } disableClick() { if (!this.#boundPointerdown) { return; } this.div.removeEventListener("pointerdown", this.#boundPointerdown); this.div.removeEventListener("pointerup", this.#boundPointerup); this.#boundPointerdown = null; this.#boundPointerup = null; } attach(editor) { this.#editors.set(editor.id, editor); const { annotationElementId } = editor; if (annotationElementId && this.#uiManager.isDeletedAnnotationElement(annotationElementId)) { this.#uiManager.removeDeletedAnnotationElement(editor); } } detach(editor) { this.#editors.delete(editor.id); this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); if (!this.#isDisabling && editor.annotationElementId) { this.#uiManager.addDeletedAnnotationElement(editor); } } remove(editor) { this.detach(editor); this.#uiManager.removeEditor(editor); editor.div.remove(); editor.isAttachedToDOM = false; if (!this.#isCleaningUp) { this.addInkEditorIfNeeded(false); } } changeParent(editor) { if (editor.parent === this) { return; } if (editor.parent && editor.annotationElementId) { this.#uiManager.addDeletedAnnotationElement(editor.annotationElementId); AnnotationEditor.deleteAnnotationElement(editor); editor.annotationElementId = null; } this.attach(editor); editor.parent?.detach(editor); editor.setParent(this); if (editor.div && editor.isAttachedToDOM) { editor.div.remove(); this.div.append(editor.div); } } add(editor) { if (editor.parent === this && editor.isAttachedToDOM) { return; } this.changeParent(editor); this.#uiManager.addEditor(editor); this.attach(editor); if (!editor.isAttachedToDOM) { const div = editor.render(); this.div.append(div); editor.isAttachedToDOM = true; } editor.fixAndSetPosition(); editor.onceAdded(); this.#uiManager.addToAnnotationStorage(editor); editor._reportTelemetry(editor.telemetryInitialData); } moveEditorInDOM(editor) { if (!editor.isAttachedToDOM) { return; } const { activeElement } = document; if (editor.div.contains(activeElement) && !this.#editorFocusTimeoutId) { editor._focusEventsAllowed = false; this.#editorFocusTimeoutId = setTimeout(() => { this.#editorFocusTimeoutId = null; if (!editor.div.contains(document.activeElement)) { editor.div.addEventListener("focusin", () => { editor._focusEventsAllowed = true; }, { once: true }); activeElement.focus(); } else { editor._focusEventsAllowed = true; } }, 0); } editor._structTreeParentId = this.#accessibilityManager?.moveElementInDOM(this.div, editor.div, editor.contentDiv, true); } addOrRebuild(editor) { if (editor.needsToBeRebuilt()) { editor.parent ||= this; editor.rebuild(); editor.show(); } else { this.add(editor); } } addUndoableEditor(editor) { const cmd = () => editor._uiManager.rebuild(editor); const undo = () => { editor.remove(); }; this.addCommands({ cmd, undo, mustExec: false }); } getNextId() { return this.#uiManager.getId(); } get #currentEditorType() { return AnnotationEditorLayer.#editorTypes.get(this.#uiManager.getMode()); } #createNewEditor(params) { const editorType = this.#currentEditorType; return editorType ? new editorType.prototype.constructor(params) : null; } canCreateNewEmptyEditor() { return this.#currentEditorType?.canCreateNewEmptyEditor(); } pasteEditor(mode, params) { this.#uiManager.updateToolbar(mode); this.#uiManager.updateMode(mode); const { offsetX, offsetY } = this.#getCenterPoint(); const id = this.getNextId(); const editor = this.#createNewEditor({ parent: this, id, x: offsetX, y: offsetY, uiManager: this.#uiManager, isCentered: true, ...params }); if (editor) { this.add(editor); } } deserialize(data) { return AnnotationEditorLayer.#editorTypes.get(data.annotationType ?? data.annotationEditorType)?.deserialize(data, this, this.#uiManager) || null; } createAndAddNewEditor(event, isCentered, data = {}) { const id = this.getNextId(); const editor = this.#createNewEditor({ parent: this, id, x: event.offsetX, y: event.offsetY, uiManager: this.#uiManager, isCentered, ...data }); if (editor) { this.add(editor); } return editor; } #getCenterPoint() { const { x, y, width, height } = this.div.getBoundingClientRect(); const tlX = Math.max(0, x); const tlY = Math.max(0, y); const brX = Math.min(window.innerWidth, x + width); const brY = Math.min(window.innerHeight, y + height); const centerX = (tlX + brX) / 2 - x; const centerY = (tlY + brY) / 2 - y; const [offsetX, offsetY] = this.viewport.rotation % 180 === 0 ? [centerX, centerY] : [centerY, centerX]; return { offsetX, offsetY }; } addNewEditor() { this.createAndAddNewEditor(this.#getCenterPoint(), true); } setSelected(editor) { this.#uiManager.setSelected(editor); } toggleSelected(editor) { this.#uiManager.toggleSelected(editor); } isSelected(editor) { return this.#uiManager.isSelected(editor); } unselect(editor) { this.#uiManager.unselect(editor); } pointerup(event) { const { isMac } = util_FeatureTest.platform; if (event.button !== 0 || event.ctrlKey && isMac) { return; } if (event.target !== this.div) { return; } if (!this.#hadPointerDown) { return; } this.#hadPointerDown = false; if (!this.#allowClick) { this.#allowClick = true; return; } if (this.#uiManager.getMode() === AnnotationEditorType.STAMP) { this.#uiManager.unselectAll(); return; } this.createAndAddNewEditor(event, false); } pointerdown(event) { if (this.#uiManager.getMode() === AnnotationEditorType.HIGHLIGHT) { this.enableTextSelection(); } if (this.#hadPointerDown) { this.#hadPointerDown = false; return; } const { isMac } = util_FeatureTest.platform; if (event.button !== 0 || event.ctrlKey && isMac) { return; } if (event.target !== this.div) { return; } this.#hadPointerDown = true; const editor = this.#uiManager.getActive(); this.#allowClick = !editor || editor.isEmpty(); } findNewParent(editor, x, y) { const layer = this.#uiManager.findParent(x, y); if (layer === null || layer === this) { return false; } layer.changeParent(editor); return true; } destroy() { if (this.#uiManager.getActive()?.parent === this) { this.#uiManager.commitOrRemove(); this.#uiManager.setActiveEditor(null); } if (this.#editorFocusTimeoutId) { clearTimeout(this.#editorFocusTimeoutId); this.#editorFocusTimeoutId = null; } for (const editor of this.#editors.values()) { this.#accessibilityManager?.removePointerInTextLayer(editor.contentDiv); editor.setParent(null); editor.isAttachedToDOM = false; editor.div.remove(); } this.div = null; this.#editors.clear(); this.#uiManager.removeLayer(this); } #cleanup() { this.#isCleaningUp = true; for (const editor of this.#editors.values()) { if (editor.isEmpty()) { editor.remove(); } } this.#isCleaningUp = false; } render({ viewport }) { this.viewport = viewport; setLayerDimensions(this.div, viewport); for (const editor of this.#uiManager.getEditors(this.pageIndex)) { this.add(editor); editor.rebuild(); } this.updateMode(); } update({ viewport }) { this.#uiManager.commitOrRemove(); this.#cleanup(); const oldRotation = this.viewport.rotation; const rotation = viewport.rotation; this.viewport = viewport; setLayerDimensions(this.div, { rotation }); if (oldRotation !== rotation) { for (const editor of this.#editors.values()) { editor.rotate(rotation); } } this.addInkEditorIfNeeded(false); } get pageDimensions() { const { pageWidth, pageHeight } = this.viewport.rawDims; return [pageWidth, pageHeight]; } get scale() { return this.#uiManager.viewParameters.realScale; } } ;// CONCATENATED MODULE: ./src/display/draw_layer.js class DrawLayer { #parent = null; #id = 0; #mapping = new Map(); #toUpdate = new Map(); constructor({ pageIndex }) { this.pageIndex = pageIndex; } setParent(parent) { if (!this.#parent) { this.#parent = parent; return; } if (this.#parent !== parent) { if (this.#mapping.size > 0) { for (const root of this.#mapping.values()) { root.remove(); parent.append(root); } } this.#parent = parent; } } static get _svgFactory() { return shadow(this, "_svgFactory", new DOMSVGFactory()); } static #setBox(element, { x = 0, y = 0, width = 1, height = 1 } = {}) { const { style } = element; style.top = `${100 * y}%`; style.left = `${100 * x}%`; style.width = `${100 * width}%`; style.height = `${100 * height}%`; } #createSVG(box) { const svg = DrawLayer._svgFactory.create(1, 1, true); this.#parent.append(svg); svg.setAttribute("aria-hidden", true); DrawLayer.#setBox(svg, box); return svg; } #createClipPath(defs, pathId) { const clipPath = DrawLayer._svgFactory.createElement("clipPath"); defs.append(clipPath); const clipPathId = `clip_${pathId}`; clipPath.setAttribute("id", clipPathId); clipPath.setAttribute("clipPathUnits", "objectBoundingBox"); const clipPathUse = DrawLayer._svgFactory.createElement("use"); clipPath.append(clipPathUse); clipPathUse.setAttribute("href", `#${pathId}`); clipPathUse.classList.add("clip"); return clipPathId; } highlight(outlines, color, opacity, isPathUpdatable = false) { const id = this.#id++; const root = this.#createSVG(outlines.box); root.classList.add("highlight"); if (outlines.free) { root.classList.add("free"); } const defs = DrawLayer._svgFactory.createElement("defs"); root.append(defs); const path = DrawLayer._svgFactory.createElement("path"); defs.append(path); const pathId = `path_p${this.pageIndex}_${id}`; path.setAttribute("id", pathId); path.setAttribute("d", outlines.toSVGPath()); if (isPathUpdatable) { this.#toUpdate.set(id, path); } const clipPathId = this.#createClipPath(defs, pathId); const use = DrawLayer._svgFactory.createElement("use"); root.append(use); root.setAttribute("fill", color); root.setAttribute("fill-opacity", opacity); use.setAttribute("href", `#${pathId}`); this.#mapping.set(id, root); return { id, clipPathId: `url(#${clipPathId})` }; } highlightOutline(outlines) { const id = this.#id++; const root = this.#createSVG(outlines.box); root.classList.add("highlightOutline"); const defs = DrawLayer._svgFactory.createElement("defs"); root.append(defs); const path = DrawLayer._svgFactory.createElement("path"); defs.append(path); const pathId = `path_p${this.pageIndex}_${id}`; path.setAttribute("id", pathId); path.setAttribute("d", outlines.toSVGPath()); path.setAttribute("vector-effect", "non-scaling-stroke"); let maskId; if (outlines.free) { root.classList.add("free"); const mask = DrawLayer._svgFactory.createElement("mask"); defs.append(mask); maskId = `mask_p${this.pageIndex}_${id}`; mask.setAttribute("id", maskId); mask.setAttribute("maskUnits", "objectBoundingBox"); const rect = DrawLayer._svgFactory.createElement("rect"); mask.append(rect); rect.setAttribute("width", "1"); rect.setAttribute("height", "1"); rect.setAttribute("fill", "white"); const use = DrawLayer._svgFactory.createElement("use"); mask.append(use); use.setAttribute("href", `#${pathId}`); use.setAttribute("stroke", "none"); use.setAttribute("fill", "black"); use.setAttribute("fill-rule", "nonzero"); use.classList.add("mask"); } const use1 = DrawLayer._svgFactory.createElement("use"); root.append(use1); use1.setAttribute("href", `#${pathId}`); if (maskId) { use1.setAttribute("mask", `url(#${maskId})`); } const use2 = use1.cloneNode(); root.append(use2); use1.classList.add("mainOutline"); use2.classList.add("secondaryOutline"); this.#mapping.set(id, root); return id; } finalizeLine(id, line) { const path = this.#toUpdate.get(id); this.#toUpdate.delete(id); this.updateBox(id, line.box); path.setAttribute("d", line.toSVGPath()); } updateLine(id, line) { const root = this.#mapping.get(id); const defs = root.firstChild; const path = defs.firstChild; path.setAttribute("d", line.toSVGPath()); } removeFreeHighlight(id) { this.remove(id); this.#toUpdate.delete(id); } updatePath(id, line) { this.#toUpdate.get(id).setAttribute("d", line.toSVGPath()); } updateBox(id, box) { DrawLayer.#setBox(this.#mapping.get(id), box); } show(id, visible) { this.#mapping.get(id).classList.toggle("hidden", !visible); } rotate(id, angle) { this.#mapping.get(id).setAttribute("data-main-rotation", angle); } changeColor(id, color) { this.#mapping.get(id).setAttribute("fill", color); } changeOpacity(id, opacity) { this.#mapping.get(id).setAttribute("fill-opacity", opacity); } addClass(id, className) { this.#mapping.get(id).classList.add(className); } removeClass(id, className) { this.#mapping.get(id).classList.remove(className); } remove(id) { if (this.#parent === null) { return; } this.#mapping.get(id).remove(); this.#mapping.delete(id); } destroy() { this.#parent = null; for (const root of this.#mapping.values()) { root.remove(); } this.#mapping.clear(); } } ;// CONCATENATED MODULE: ./src/pdf.js const pdfjsVersion = "4.3.136"; const pdfjsBuild = "0cec64437"; })(); var __webpack_exports__AbortException = __webpack_exports__.AbortException; var __webpack_exports__AnnotationEditorLayer = __webpack_exports__.AnnotationEditorLayer; var __webpack_exports__AnnotationEditorParamsType = __webpack_exports__.AnnotationEditorParamsType; var __webpack_exports__AnnotationEditorType = __webpack_exports__.AnnotationEditorType; var __webpack_exports__AnnotationEditorUIManager = __webpack_exports__.AnnotationEditorUIManager; var __webpack_exports__AnnotationLayer = __webpack_exports__.AnnotationLayer; var __webpack_exports__AnnotationMode = __webpack_exports__.AnnotationMode; var __webpack_exports__CMapCompressionType = __webpack_exports__.CMapCompressionType; var __webpack_exports__ColorPicker = __webpack_exports__.ColorPicker; var __webpack_exports__DOMSVGFactory = __webpack_exports__.DOMSVGFactory; var __webpack_exports__DrawLayer = __webpack_exports__.DrawLayer; var __webpack_exports__FeatureTest = __webpack_exports__.FeatureTest; var __webpack_exports__GlobalWorkerOptions = __webpack_exports__.GlobalWorkerOptions; var __webpack_exports__ImageKind = __webpack_exports__.ImageKind; var __webpack_exports__InvalidPDFException = __webpack_exports__.InvalidPDFException; var __webpack_exports__MissingPDFException = __webpack_exports__.MissingPDFException; var __webpack_exports__OPS = __webpack_exports__.OPS; var __webpack_exports__Outliner = __webpack_exports__.Outliner; var __webpack_exports__PDFDataRangeTransport = __webpack_exports__.PDFDataRangeTransport; var __webpack_exports__PDFDateString = __webpack_exports__.PDFDateString; var __webpack_exports__PDFWorker = __webpack_exports__.PDFWorker; var __webpack_exports__PasswordResponses = __webpack_exports__.PasswordResponses; var __webpack_exports__PermissionFlag = __webpack_exports__.PermissionFlag; var __webpack_exports__PixelsPerInch = __webpack_exports__.PixelsPerInch; var __webpack_exports__RenderingCancelledException = __webpack_exports__.RenderingCancelledException; var __webpack_exports__TextLayer = __webpack_exports__.TextLayer; var __webpack_exports__UnexpectedResponseException = __webpack_exports__.UnexpectedResponseException; var __webpack_exports__Util = __webpack_exports__.Util; var __webpack_exports__VerbosityLevel = __webpack_exports__.VerbosityLevel; var __webpack_exports__XfaLayer = __webpack_exports__.XfaLayer; var __webpack_exports__build = __webpack_exports__.build; var __webpack_exports__createValidAbsoluteUrl = __webpack_exports__.createValidAbsoluteUrl; var __webpack_exports__fetchData = __webpack_exports__.fetchData; var __webpack_exports__getDocument = __webpack_exports__.getDocument; var __webpack_exports__getFilenameFromUrl = __webpack_exports__.getFilenameFromUrl; var __webpack_exports__getPdfFilenameFromUrl = __webpack_exports__.getPdfFilenameFromUrl; var __webpack_exports__getXfaPageViewport = __webpack_exports__.getXfaPageViewport; var __webpack_exports__isDataScheme = __webpack_exports__.isDataScheme; var __webpack_exports__isPdfFile = __webpack_exports__.isPdfFile; var __webpack_exports__noContextMenu = __webpack_exports__.noContextMenu; var __webpack_exports__normalizeUnicode = __webpack_exports__.normalizeUnicode; var __webpack_exports__renderTextLayer = __webpack_exports__.renderTextLayer; var __webpack_exports__setLayerDimensions = __webpack_exports__.setLayerDimensions; var __webpack_exports__shadow = __webpack_exports__.shadow; var __webpack_exports__updateTextLayer = __webpack_exports__.updateTextLayer; var __webpack_exports__version = __webpack_exports__.version; export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__TextLayer as TextLayer, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version }; //# sourceMappingURL=pdf.js.map
•
Search:
•
Replace:
1
2
3
Function
Edit by line
Download
Information
Rename
Copy
Move
Delete
Chmod
List