: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
throw new Error("Abstract method `toSVGPath` must be implemented.");
throw new Error("Abstract getter `box` must be implemented.");
serialize(_bbox, _rotation) {
throw new Error("Abstract method `serialize` must be implemented.");
return this instanceof FreeHighlightOutline;
class HighlightOutline extends Outline {
constructor(outlines, box) {
this.#outlines = outlines;
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 y = polygon[i + 1];
} else if (y === prevY) {
serialize([blX, blY, trX, trY], _rotation) {
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;
#last = new Float64Array(18);
static #MIN = FreeOutliner.#MIN_DIST + FreeOutliner.#MIN_DIFF;
}, box, scaleFactor, thickness, isLTR, innerMargin = 0) {
this.#thickness = thickness * scaleFactor;
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;
return isNaN(this.#last[8]);
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];
const [layerX, layerY, layerWidth, layerHeight] = this.#box;
let [x1, y1, x2, y2] = this.#last.subarray(8, 12);
const d = Math.hypot(diffX, diffY);
const diffD = d - this.#min_dist;
const shiftX = K * diffX;
const shiftY = K * diffY;
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);
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);
[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);
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`;
buffer.push(`M${top[4]} ${top[5]}`);
for (let i = 6; i < top.length; i += 6) {
buffer.push(`L${top[i + 4]} ${top[i + 5]}`);
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) {
buffer.push(`L${bottom[i + 4]} ${bottom[i + 5]}`);
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`);
const bottom = this.#bottom;
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);
for (let i = 0; i < N; i += 2) {
outline[i] = outline[i + 1] = NaN;
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);
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;
outline[N] = bottom[i + j];
outline[N + 1] = bottom[i + j + 1];
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 {
constructor(outline, points, box, scaleFactor, innerMargin, isLTR) {
this.#scaleFactor = scaleFactor;
this.#innerMargin = innerMargin;
this.#computeMinMax(isLTR);
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;
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]}`);
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]}`);
serialize([blX, blY, trX, trY], rotation) {
const height = trY - blY;
outline = this.#rescale(this.#outline, blX, trY, width, -height);
points = this.#rescale(this.#points, blX, trY, width, -height);
outline = this.#rescaleAndSwap(this.#outline, blX, blY, width, height);
points = this.#rescaleAndSwap(this.#points, blX, blY, width, height);
outline = this.#rescale(this.#outline, trX, blY, -width, height);
points = this.#rescale(this.#points, trX, blY, -width, height);
outline = this.#rescaleAndSwap(this.#outline, trX, trY, -width, -height);
points = this.#rescaleAndSwap(this.#points, trX, trY, -width, -height);
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;
#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;
const outline = this.#outline;
const ltrCallback = isLTR ? Math.max : Math.min;
for (let i = 6, ii = outline.length; i < ii; i += 6) {
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]);
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]) {
} else if (lastPointY === bbox[3]) {
lastPointX = ltrCallback(lastPointX, bbox[2]);
const x = minX - this.#innerMargin,
y = minY - this.#innerMargin,
width = maxX - minX + 2 * this.#innerMargin,
height = maxY - minY + 2 * this.#innerMargin;
lastPoint: [lastPointX, lastPointY]
getNewOutline(thickness, innerMargin) {
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) {
x: this.#points[i] * sx + tx,
y: this.#points[i + 1] * sy + ty
return outliner.getOutlines();
;// CONCATENATED MODULE: ./src/display/editor/color_picker.js
#boundKeyDown = this.#keyDown.bind(this);
#boundPointerDown = this.#pointerDown.bind(this);
#dropdownWasFromKeyboard = false;
#isMainColorPicker = false;
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]]));
this.#isMainColorPicker = false;
this.#type = AnnotationEditorParamsType.HIGHLIGHT_COLOR;
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";
const button = this.#button = document.createElement("button");
button.className = "colorPicker";
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;
const dropdown = this.#dropdown = this.#getDropdownRoot();
dropdown.setAttribute("aria-orientation", "horizontal");
dropdown.setAttribute("aria-labelledby", "highlightColorPickerLabel");
const div = document.createElement("div");
div.addEventListener("contextmenu", noContextMenu);
div.className = "dropdown";
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.setAttribute("data-color", color);
button.setAttribute("data-l10n-id", `pdfjs-editor-colorpicker-${name}`);
const swatch = document.createElement("span");
swatch.className = "swatch";
swatch.style.backgroundColor = color;
button.setAttribute("aria-selected", color === this.#defaultColor);
button.addEventListener("click", this.#colorSelect.bind(this, color));
div.addEventListener("keydown", this.#boundKeyDown);
#colorSelect(color, event) {
this.#eventBus.dispatch("switchannotationeditorparams", {