: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (!accessibilityData?.type) {
nextKey = Math.max(nextKey, parentTreeId);
const tagRef = xref.getNewTemporaryRef();
const tagDict = new Dict(xref);
tagDict.set("S", Name.get(type));
tagDict.set("Lang", lang);
tagDict.set("E", expanded);
tagDict.set("ActualText", actualText);
await this.#updateParentTag({
const objDict = new Dict(xref);
tagDict.set("K", objDict);
objDict.set("Type", objr);
objDict.set("Pg", pageRef);
cache.put(tagRef, tagDict);
nums.push(parentTreeId, tagRef);
const idToElements = new Map();
for (const element of elements) {
if (element.structTreeParentId) {
const id = parseInt(element.structTreeParentId.split("_mc")[1], 10);
let elems = idToElements.get(id);
idToElements.set(id, elems);
const id = pageDict.get("StructParents");
if (!Number.isInteger(id)) {
const parentArray = numberTree.get(id);
const updateElement = (kid, pageKid, kidRef) => {
const elems = idToElements.get(kid);
const parentRef = pageKid.getRaw("P");
const parentDict = xref.fetchIfRef(parentRef);
if (parentRef instanceof Ref && parentDict instanceof Dict) {
for (const element of elems) {
element.structTreeParent = params;
for (const kidRef of parentArray) {
if (!(kidRef instanceof Ref)) {
const pageKid = xref.fetch(kidRef);
const k = pageKid.get("K");
if (Number.isInteger(k)) {
updateElement(k, pageKid, kidRef);
kid = xref.fetchIfRef(kid);
if (Number.isInteger(kid) && updateElement(kid, pageKid, kidRef)) {
if (!(kid instanceof Dict)) {
if (!isName(kid.get("Type"), "MCR")) {
const mcid = kid.get("MCID");
if (Number.isInteger(mcid) && updateElement(mcid, pageKid, kidRef)) {
static async #updateParentTag({
parentRef = structTreeParent.dict.getRaw("P") || structTreeRootRef;
parentRef = structTreeRootRef;
tagDict.set("P", parentRef);
const parentDict = xref.fetchIfRef(parentRef);
fallbackKids.push(newTagRef);
let cachedParentDict = cache.get(parentRef);
cachedParentDict = parentDict.clone();
cache.put(parentRef, cachedParentDict);
const parentKidsRaw = cachedParentDict.getRaw("K");
let cachedParentKids = parentKidsRaw instanceof Ref ? cache.get(parentKidsRaw) : null;
cachedParentKids = xref.fetchIfRef(parentKidsRaw);
cachedParentKids = Array.isArray(cachedParentKids) ? cachedParentKids.slice() : [parentKidsRaw];
const parentKidsRef = xref.getNewTemporaryRef();
cachedParentDict.set("K", parentKidsRef);
cache.put(parentKidsRef, cachedParentKids);
const index = cachedParentKids.indexOf(ref);
cachedParentKids.splice(index >= 0 ? index + 1 : cachedParentKids.length, 0, newTagRef);
class StructElementNode {
constructor(tree, dict) {
const nameObj = this.dict.get("S");
const name = nameObj instanceof Name ? nameObj.name : "";
if (root.roleMap.has(name)) {
return root.roleMap.get(name);
const objRef = this.dict.getRaw("Pg");
if (objRef instanceof Ref) {
pageObjId = objRef.toString();
const kids = this.dict.get("K");
if (Array.isArray(kids)) {
for (const kid of kids) {
const element = this.parseKid(pageObjId, kid);
const element = this.parseKid(pageObjId, kids);
parseKid(pageObjId, kid) {
if (Number.isInteger(kid)) {
if (this.tree.pageDict.objId !== pageObjId) {
return new StructElement({
type: StructElementType.PAGE_CONTENT,
if (kid instanceof Ref) {
kidDict = this.dict.xref.fetch(kid);
} else if (kid instanceof Dict) {
const pageRef = kidDict.getRaw("Pg");
if (pageRef instanceof Ref) {
pageObjId = pageRef.toString();
const type = kidDict.get("Type") instanceof Name ? kidDict.get("Type").name : null;
if (this.tree.pageDict.objId !== pageObjId) {
const kidRef = kidDict.getRaw("Stm");
return new StructElement({
type: StructElementType.STREAM_CONTENT,
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
mcid: kidDict.get("MCID")
if (this.tree.pageDict.objId !== pageObjId) {
const kidRef = kidDict.getRaw("Obj");
return new StructElement({
type: StructElementType.OBJECT,
refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
return new StructElement({
type: StructElementType.ELEMENT,
this.pageObjId = pageObjId;
this.refObjId = refObjId;
constructor(structTreeRoot, pageDict) {
this.root = structTreeRoot;
this.rootDict = structTreeRoot ? structTreeRoot.dict : null;
this.pageDict = pageDict;
if (!this.root || !this.rootDict) {
const parentTree = this.rootDict.get("ParentTree");
const id = this.pageDict.get("StructParents");
const ids = pageRef instanceof Ref && this.root.structParentIds?.get(pageRef);
if (!Number.isInteger(id) && !ids) {
const numberTree = new NumberTree(parentTree, this.rootDict.xref);
if (Number.isInteger(id)) {
const parentArray = numberTree.get(id);
if (Array.isArray(parentArray)) {
for (const ref of parentArray) {
if (ref instanceof Ref) {
this.addNode(this.rootDict.xref.fetch(ref), map);
for (const [elemId, type] of ids) {
const obj = numberTree.get(elemId);
const elem = this.addNode(this.rootDict.xref.fetchIfRef(obj), map);
if (elem?.kids?.length === 1 && elem.kids[0].type === StructElementType.OBJECT) {
elem.kids[0].type = type;
addNode(dict, map, level = 0) {
warn("StructTree MAX_DEPTH reached.");
const element = new StructElementNode(this, dict);
const parent = dict.get("P");
if (!parent || isName(parent.get("Type"), "StructTreeRoot")) {
if (!this.addTopLevelNode(dict, element)) {
const parentNode = this.addNode(parent, map, level + 1);
for (const kid of parentNode.kids) {
if (kid.type === StructElementType.ELEMENT && kid.dict === dict) {
kid.parentNode = element;
addTopLevelNode(dict, element) {
const obj = this.rootDict.get("K");
if (obj instanceof Dict) {
if (obj.objId !== dict.objId) {
if (!Array.isArray(obj)) {
for (let i = 0; i < obj.length; i++) {
if (kidRef?.toString() === dict.objId) {
function nodeToSerializable(node, parent, level = 0) {
warn("StructTree too deep to be fully serialized.");
const obj = Object.create(null);
parent.children.push(obj);
const alt = node.dict.get("Alt");
if (typeof alt === "string") {
obj.alt = stringToPDFString(alt);
const lang = node.dict.get("Lang");
if (typeof lang === "string") {
obj.lang = stringToPDFString(lang);
for (const kid of node.kids) {
const kidElement = kid.type === StructElementType.ELEMENT ? kid.parentNode : null;
nodeToSerializable(kidElement, obj, level + 1);
} else if (kid.type === StructElementType.PAGE_CONTENT || kid.type === StructElementType.STREAM_CONTENT) {
id: `p${kid.pageObjId}_mc${kid.mcid}`
} else if (kid.type === StructElementType.OBJECT) {
} else if (kid.type === StructElementType.ANNOTATION) {
id: `${AnnotationPrefix}${kid.refObjId}`
const root = Object.create(null);
for (const child of this.nodes) {
nodeToSerializable(child, root);
;// CONCATENATED MODULE: ./src/core/catalog.js
function isValidExplicitDest(dest) {
if (!Array.isArray(dest) || dest.length < 2) {
const [page, zoom, ...args] = dest;
if (!(page instanceof Ref) && !Number.isInteger(page)) {
if (!(zoom instanceof Name)) {
return args.length === 0;
for (const arg of args) {
if (!(typeof arg === "number" || allowNull && arg === null)) {