{
  "version": 3,
  "sources": ["../src/Epub.ts", "../src/constants.ts", "../src/convert/navdoc.ts", "../src/convert/ncx.ts", "../src/convert/metadata.ts", "../src/convert/resourcesAndReadingOrder.ts", "../src/convert/index.ts", "../src/Fetcher.ts", "../src/LocalFetcher.ts", "../src/RemoteFetcher.ts"],
  "sourcesContent": ["import { Container } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/container';\nimport { OPF } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/opf';\nimport { NCX } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/ncx';\nimport { DCMetadata } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/opf-dc-metadata';\nimport { Metafield } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/opf-metafield';\nimport { XML } from 'r2-utils-js/dist/es8-es2017/src/_utils/xml-js-mapper';\nimport { DOMParser } from 'xmldom';\nimport { EpubVersion } from './types';\nimport { Rootfile } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/container-rootfile';\nimport { WebpubManifest } from './WebpubManifestTypes/WebpubManifest';\nimport { epubToManifest } from './convert';\nimport Decryptor from '@nypl-simplified-packages/axisnow-access-control-web';\nimport Fetcher from './Fetcher';\n\n/**\n * This class represents a complete EPUB. It is abstract\n * because it is meant to be subclassed to support various\n * ways an EPUB can be sourced:\n *  - Local (filesystem) exploded EPUB\n *  - Local packaged EPUB\n *  - Remote (external server) exploded EPUB\n *  - Remote packaged EPUB\n *\n * This class includes utilites used to parse the string file values\n * into in-memory representations and to extract values from the various\n * data structures. They will be used by all subclasses.\n */\nexport default class Epub {\n  static NCX_MEDIA_TYPE = 'application/x-dtbncx+xml';\n\n  constructor(\n    public readonly fetcher: Fetcher,\n    private readonly containerXmlPath: string,\n    // used to resolve items relative to the opf file\n    public readonly opfPath: string,\n    public readonly container: Container,\n    public readonly opf: OPF,\n    // EPUB 2 uses NCX, EPUB 3 uses NavDoc\n    public readonly ncx: NCX | undefined,\n    public readonly navDoc: Document | undefined,\n    // pass a decryptor to have all files except container.xml and opf run through it\n    public readonly decryptor?: Decryptor\n  ) {}\n\n  public static async build(\n    containerXmlPath: string,\n    fetcher: Fetcher,\n    decryptor?: Decryptor\n  ) {\n    const container = Epub.parseContainer(\n      await fetcher.getFileStr(containerXmlPath)\n    );\n    const relativeOpfPath = Epub.getOpfPath(container);\n    const opfPath = fetcher.getOpfPath(relativeOpfPath);\n    const opf = await Epub.parseOpf(await fetcher.getFileStr(opfPath));\n\n    const relativeNcxPath = Epub.getNcxHref(opf);\n    const ncxPath = relativeNcxPath\n      ? fetcher.resolvePath(opfPath, relativeNcxPath)\n      : undefined;\n\n    const ncxBuffer = ncxPath\n      ? await fetcher.getArrayBuffer(ncxPath)\n      : undefined;\n    const ncxStr = await Epub.decryptStr(ncxBuffer, decryptor);\n    const ncx = Epub.parseNcx(ncxStr);\n\n    const relativeNavDocPath = Epub.getNavDocHref(opf);\n    const navDocPath = relativeNavDocPath\n      ? fetcher.resolvePath(opfPath, relativeNavDocPath)\n      : undefined;\n    const navDocBuffer = navDocPath\n      ? await fetcher.getArrayBuffer(navDocPath)\n      : undefined;\n    const navDocStr = await Epub.decryptStr(navDocBuffer, decryptor);\n    const navDoc = Epub.parseNavDoc(navDocStr);\n\n    return new Epub(\n      fetcher,\n      containerXmlPath,\n      opfPath,\n      container,\n      opf,\n      ncx,\n      navDoc,\n      decryptor\n    );\n  }\n\n  ///////////////////\n  // ACCESSOR METHODS AND UTILS\n  // We need static and instance methods of these because the static version is\n  // used in the subclass's `build` method\n  ///////////////////\n\n  static getVersion(rootfile: Rootfile | undefined, opf: OPF): EpubVersion {\n    const versionNumber = rootfile?.Version ?? opf.Version;\n    return versionNumber.startsWith('3') ? '3' : '2';\n  }\n  get version(): EpubVersion {\n    return Epub.getVersion(this.rootfile, this.opf);\n  }\n\n  static getRootfile(container: Container): Rootfile | undefined {\n    return container.Rootfile[0];\n  }\n  get rootfile(): Rootfile | undefined {\n    return Epub.getRootfile(this.container);\n  }\n\n  static getContentPath(rootfile: Rootfile | undefined, opf: OPF): string {\n    return Epub.getVersion(rootfile, opf) === '2' ? 'OEBPS/' : 'OPS/';\n  }\n  get contentPath(): string {\n    return Epub.getContentPath(this.rootfile, this.opf);\n  }\n\n  get webpubManifest(): Promise<WebpubManifest> {\n    return epubToManifest(this);\n  }\n\n  ///////////////////\n  // METHODS FOR DESERIALIZING VALUES INTO IN-MEMORY CLASSES\n  ///////////////////\n\n  /**\n   * Parses an XML string into a JS class\n   */\n  static parseXmlString<T>(str: string, objectType: any): T {\n    const containerXmlDoc = new DOMParser().parseFromString(str, 'utf-8');\n    return XML.deserialize<T>(containerXmlDoc, objectType);\n  }\n\n  /**\n   * Parses an XML string into an OPF class, resolving edge cases on the way.\n   */\n  static async parseOpf(str: string): Promise<OPF> {\n    const fixed = Epub.fixOpfString(str);\n    const opf = Epub.parseXmlString<OPF>(fixed, OPF);\n    return opf;\n  }\n\n  /**\n   * This code was found in the r2-shared-js repo. I'm not sure if\n   * it's necessary, but it seems to fix an edge case of how the package\n   * is defined in the XML.\n   */\n  static fixOpfString(opfStr: string): string {\n    const iStart = opfStr.indexOf('<package');\n    if (iStart >= 0) {\n      const iEnd = opfStr.indexOf('>', iStart);\n      if (iEnd > iStart) {\n        const clip = opfStr.substr(iStart, iEnd - iStart);\n        if (clip.indexOf('xmlns') < 0) {\n          return opfStr.replace(\n            /<package/,\n            '<package xmlns=\"http://openebook.org/namespaces/oeb-package/1.0/\" '\n          );\n        }\n      }\n    }\n    return opfStr;\n  }\n\n  /**\n   * Parse a xml string into a Container class.\n   */\n  static parseContainer(str: string): Container {\n    const container = Epub.parseXmlString<Container>(str, Container);\n    return container;\n  }\n\n  /**\n   * Extract the OPF path from a Container\n   */\n  static getOpfPath(container: Container): string {\n    // get the content.opf file from the container.xml file\n    const rootfilePath = container.Rootfile[0]?.PathDecoded;\n    if (!rootfilePath) {\n      throw new Error('container.xml file is missing rootfile path.');\n    }\n    return rootfilePath;\n  }\n\n  /**\n   * As best I can tell, the TOC.ncx file is always referenced with\n   * an <item> in the <manifest> with id === 'ncx\n   */\n  static getNcxHref(opf: OPF) {\n    return opf.Manifest.find(\n      (item) => item.ID === 'ncx' && item.MediaType === Epub.NCX_MEDIA_TYPE\n    )?.HrefDecoded;\n  }\n\n  /**\n   * Parses an NCX XML string into a TOC Document\n   */\n  static parseNcx(ncxStr: string | undefined) {\n    return ncxStr ? Epub.parseXmlString<NCX>(ncxStr, NCX) : undefined;\n  }\n\n  static getNavDocHref(opf: OPF): string | undefined {\n    const navDocItem = opf.Manifest.find((item) =>\n      Epub.parseSpaceSeparatedString(item.Properties).includes('nav')\n    );\n    return navDocItem?.HrefDecoded;\n  }\n\n  static parseNavDoc(navDocStr: string | undefined) {\n    return navDocStr ? new DOMParser().parseFromString(navDocStr) : undefined;\n  }\n\n  /**\n   * Parses a space separated string of properties into an array\n   */\n  static parseSpaceSeparatedString(str: string | undefined | null): string[] {\n    return (\n      str\n        ?.trim()\n        .split(' ')\n        .map((role) => role.trim())\n        .filter((role) => role.length > 0) ?? []\n    );\n  }\n\n  /**\n   * Takes a maybe file and a maybe decryptor and returns\n   * a string\n   */\n  static async decryptStr(\n    buffer: ArrayBuffer | undefined,\n    decryptor: Decryptor | undefined\n  ): Promise<string | undefined> {\n    if (!buffer) return undefined;\n    if (!decryptor) return new TextDecoder('utf-8').decode(buffer);\n    return await decryptor.decryptStr(new Uint8Array(buffer));\n  }\n\n  static async decryptAb(\n    buffer: ArrayBuffer,\n    decryptor: Decryptor | undefined\n  ): Promise<ArrayBuffer> {\n    if (!decryptor) return buffer;\n    return await decryptor.decrypt(new Uint8Array(buffer));\n  }\n\n  ///////////////////\n  // METHODS FOR GETTING VALUES FROM THE TOC AND NCX FILES\n  ///////////////////\n\n  /**\n   * Extracts a named metadata property from either epub.opf.Metatada.DCMetadata\n   * or epub.opf.Metadata, if the prior doesn't exist. Returns undefined\n   * in case of failure. This is to support EPUB 2.0, which allows\n   * metadata to be nested within dc:metadata:\n   * http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.2\n   */\n  extractMetadataMember<T extends keyof DCMetadata>(key: T) {\n    return this.opf.Metadata?.DCMetadata?.[key] ?? this.opf.Metadata[key];\n  }\n\n  /**\n   * Extracts meta fields that are found in the XMetadata or Meta arrays\n   * within the Metadata object. This is necessary because EPUB allows metadata\n   * to be nested under either tag.\n   */\n  extractMetaField(filter: (meta: Metafield) => boolean) {\n    /**\n     * These properties are not marked as optional, but that is a mistake, they\n     * are indeed optional and need to use optional chaining and nullish coalescing\n     */\n    const xMetaFields =\n      this.opf.Metadata?.XMetadata?.Meta?.filter(filter) ?? [];\n    const metaFields = this.opf.Metadata?.Meta?.filter(filter) ?? [];\n\n    return [...xMetaFields, ...metaFields];\n  }\n}\n", "export const ReadiumWebpubContext =\n  'https://readium.org/webpub-manifest/context.jsonld';\n", "import Epub from '../Epub';\nimport { ReadiumLink } from '../WebpubManifestTypes/ReadiumLink';\nimport xpath from 'xpath';\nimport { DOMParser } from 'xmldom';\n\n/**\n * This file is for converting an EPUB 3 Navigation Document into a\n * Readium TOC represented by a nested list of ReadiumLink's.\n */\n\n// used for extracting things from the NavDoc\nconst select = xpath.useNamespaces({\n  epub: 'http://www.idpf.org/2007/ops',\n  xhtml: 'http://www.w3.org/1999/xhtml',\n});\n\n/**\n * EPUB 3s embed the TOC information in a Nav Document,\n * whereas EPUB 2s put that info in the NCX file. This function\n * extracts TOC information for the manifest from the Nav Document\n */\nexport function extractTocFromNavDoc(epub: Epub): ReadiumLink[] {\n  const { navDoc } = epub;\n\n  // we only care about the toc nav currently. In the future we can\n  // parse the other navs, like PageList\n  const tocListItems = select(\n    \"/xhtml:html/xhtml:body//xhtml:nav[@*[name()='epub:type'] = 'toc']/xhtml:ol/xhtml:li\",\n    navDoc\n  ) as Element[]; //?\n\n  const toc = tocListItems.map(listItemToLink(epub));\n  return toc;\n}\n\n/**\n * Converts a NavDoc ListItem to a ReadiumLink. A List Item might have its title\n * and href defined in a child <a> tag, but if it contains children, it also can\n * contain a <span> in place of the <a> tag indicating it doesn't have an href itself,\n * only a title and children. This is invalid in Readium, so we hoist the href of\n * the first child to be the href of the parent as well.\n */\nexport const listItemToLink =\n  (epub: Epub) =>\n  (listItem: Element): ReadiumLink => {\n    const doc = new DOMParser().parseFromString(listItem.toString(), 'utf-8');\n    const spanTitle = select('string(/xhtml:li/xhtml:span)', doc, true); //?\n    const anchorTitle = select('string(/xhtml:li/xhtml:a)', doc, true); //?\n    const href = select('string(/xhtml:li/xhtml:a/@href)', doc); //?\n\n    const childElements = select('/xhtml:li/xhtml:ol/xhtml:li', doc) as\n      | Element[]\n      | undefined;\n    const children = childElements?.map(listItemToLink(epub));\n\n    // if it has a spanTitle then it doesn't have a child <a> tag, and\n    // we have to get the href from the children.\n    if (typeof spanTitle === 'string' && spanTitle.length > 0) {\n      if (!children?.[0]) {\n        throw new Error('TOC List Item with <span> is missing children.');\n      }\n      const firstChildHref = children?.[0].href;\n      const link: ReadiumLink = {\n        href: firstChildHref,\n        title: spanTitle,\n      };\n      // add children if there are any\n      if (children && children.length > 0) link.children = children;\n      return link;\n    }\n\n    // otherwise we are dealing with a standard element with an <a> tag within.\n    if (typeof anchorTitle !== 'string' || anchorTitle.length < 1) {\n      throw new Error(`TOC List item missing title: ${listItem.toString()}`);\n    }\n    if (typeof href !== 'string') {\n      throw new Error(`TOC List item missing href: ${listItem.toString()}`);\n    }\n    const relativePath = epub.fetcher.resolveRelativePath(epub.opfPath, href);\n    const link: ReadiumLink = {\n      title: anchorTitle,\n      href: relativePath,\n    };\n    // add children if there are any\n    if (children && children.length > 0) link.children = children;\n    return link;\n  };\n", "import { NCX } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/ncx';\nimport { NavPoint } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/ncx-navpoint';\nimport Epub from '../Epub';\nimport { ReadiumLink } from '../WebpubManifestTypes/ReadiumLink';\n\n/**\n * NCX files are used by EPUB 2 books to define the\n * TOC. The spec is here:\n * http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4.1\n */\nexport function extractTocFromNcx(epub: Epub, ncx: NCX): ReadiumLink[] {\n  const points = ncx.Points;\n\n  const toc = points.map(navPointToLink(epub));\n\n  return toc;\n}\n\n/**\n * Turns a NavPoint from an NCX file into a ReadiumLink.\n */\nexport const navPointToLink =\n  (epub: Epub) =>\n  (point: NavPoint): ReadiumLink => {\n    const href = point.Content.SrcDecoded;\n    if (!href) {\n      throw new Error(`NavPoint missing href: ${point}`);\n    }\n    const link: ReadiumLink = {\n      title: point.NavLabel.Text,\n      href: epub.fetcher.resolveRelativePath(epub.opfPath, href),\n    };\n\n    // we cast this to make the type wider because it's wrong in r2-shared-js.\n    // it actually can be undefined.\n    const childPoints = point.Points as NavPoint[] | undefined;\n    // recurse on the children points\n    if (childPoints && childPoints.length > 0) {\n      const children = childPoints.map(navPointToLink(epub)).filter(isLink);\n      link.children = children;\n    }\n    return link;\n  };\n\n// useful for typescript to use in a filter\nfunction isLink(val: ReadiumLink | undefined): val is ReadiumLink {\n  return !!val;\n}\n", "import { Metafield } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/opf-metafield';\nimport Epub from '../Epub';\nimport { Contributors } from '../WebpubManifestTypes/Metadata';\nimport { WebpubManifest } from '../WebpubManifestTypes/WebpubManifest';\n\n/**\n * For the purposes of this project, the metadata is not _super_ important since\n * these are not being distributed as webpubs, we just need enough info for our\n * reader to display the book correctly.\n *\n * Missing from metadata:\n * - Language Map support for language-based fields\n * - Subtitle extraction\n * - Publication Direction\n * - ...less important stuff defined in the Metadata type\n */\nexport function extractMetadata(epub: Epub): WebpubManifest['metadata'] {\n  const language = epub.extractMetadataMember('Language');\n  const title = extractTitle(epub);\n  const contributors = extractContributors(epub);\n\n  return {\n    title,\n    language: language.length > 1 ? language : language[0],\n    ...contributors,\n  };\n}\n\n/**\n * Instead of extracting a map of titles based on language, we will just use\n * the first title we find. This can be extended later to add a\n * map of languages and titles.\n */\nfunction extractTitle(epub: Epub) {\n  const titleMeta = epub.extractMetadataMember('Title');\n  return titleMeta?.[0].Data ?? 'Uknown Title';\n}\n\n/**\n * We will extract a simple list of string contributor names\n * for each contributor role.\n */\nfunction extractContributors(epub: Epub): Contributors {\n  const contributorFields = epub.extractMetaField(\n    (meta: Metafield) =>\n      meta.Property === 'dcterms:creator' ||\n      meta.Property === 'dcterms:contributor'\n  );\n\n  // Map from EPUB role codes to Webpub Roles\n  const roleMap: Record<string, string> = {\n    aut: 'author',\n    trl: 'translator',\n    art: 'artist',\n    edt: 'editor',\n    ill: 'illustrator',\n    ltr: 'letterer',\n    pen: 'penciler',\n    clr: 'colorist',\n    ink: 'inker',\n    nrt: 'narrator',\n    pbl: 'publisher',\n  };\n\n  const contributors = contributorFields.reduce<Contributors>(\n    (all, contributor) => {\n      const name = contributor.Data;\n      // get the role, which is a sibling xml node. The default is contributor\n      const epubRole =\n        epub.extractMetaField(\n          (field) => field.Property === 'role' && field.ID === contributor.ID\n        )?.[0]?.Data ?? 'contributor';\n      const webpubRole = roleMap[epubRole] ?? 'contributor';\n      return {\n        ...all,\n        [webpubRole]: name,\n      };\n    },\n    {}\n  );\n\n  // the author get pre-extracted for some reason from the metafields\n  const creators = epub.extractMetadataMember('Creator');\n  if (creators.length > 0) {\n    if (creators.length > 1) {\n      contributors.author = creators.map((creator) => creator.Data);\n    } else {\n      contributors.author = creators[0].Data;\n    }\n  }\n\n  return contributors;\n}\n", "import { Manifest } from 'r2-shared-js/dist/es8-es2017/src/parser/epub/opf-manifest';\nimport Epub from '../Epub';\nimport { ReadiumLink } from '../WebpubManifestTypes/ReadiumLink';\n\n/**\n * The readingOrder lists the resources of the publication in the reading order\n * they should be read in. The resources object is for any _other_ resources needed,\n * but not found in the readingOrder, such as css files. We first get all the resources,\n * then remove the ones that are in the reading order (the opf's Spine). Spec:\n *\n * http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4.\n */\nexport async function resourcesAndReadingOrder(\n  epub: Epub\n): Promise<ReadingOrderAndResources> {\n  // get out every resources from the manifest\n  const allResources = await extractResources(epub);\n  // keep a record of what IDs appear in the reading order so we can filter them\n  // from the resources later\n  const appearsInReadingOrder: Record<string, boolean> = {};\n  const readingOrder = epub.opf.Spine.Items.reduce<ReadiumLink[]>(\n    (acc, item) => {\n      const link = allResources.find((link) => link.id === item.IDref);\n      if (link) {\n        if (!item.Linear || item.Linear === 'yes') {\n          acc.push(link);\n          appearsInReadingOrder[link.id] = true;\n        }\n      }\n      return acc;\n    },\n    []\n  );\n  // filter allResources to only have ones not found in reading order\n  const resources = allResources.filter(\n    (link) => !appearsInReadingOrder[link.id]\n  );\n\n  return {\n    resources,\n    readingOrder,\n  };\n}\n\ntype LinkWithId = ReadiumLink & { id: string };\n\ntype ReadingOrderAndResources = {\n  readingOrder: ReadiumLink[];\n  resources?: ReadiumLink[];\n};\n\n/**\n * This is a very basic implementation that extracts resources from the OPF\n * manifest. The links href, type, and ID, and other info detected\n * from the properties string.\n *\n * The Readium implementation will look for a <meta name=\"cover\"> tag\n * to add a rel:\"cover\" property to the link, but we have decided not\n * to do that since it's not in the EPUB 2 or EPUB 3 spec.\n * We can add it in the future if necessary.\n */\nasync function extractResources(epub: Epub): Promise<LinkWithId[]> {\n  const resources: LinkWithId[] = await Promise.all(\n    epub.opf.Manifest.map(manifestToLink(epub))\n  );\n\n  return resources;\n}\n\n/**\n * Process an OPF Manifest item (called a Manifest) into\n * a Readium link for the resources or reading order.\n *\n * EPUB 3 OPF files can have 'properties' on the <meta> tags and on th\n * manifest items. These need to be processed into values we define on the\n * ReadiumLink, like rel: \"cover\" for example.\n *\n * EPUB 2 files do not have properties.\n *\n * This function is curried so we can pass it an epub once and then use it in a map\n * function.\n *\n */\nconst manifestToLink =\n  (epub: Epub) =>\n  async (manifest: Manifest): Promise<LinkWithId> => {\n    const decodedHref = manifest.HrefDecoded;\n    if (!decodedHref) {\n      throw new Error(`OPF Link missing HrefDecoded`);\n    }\n    const relativePath = epub.fetcher.resolveRelativePath(\n      epub.opfPath,\n      decodedHref\n    );\n    const link: LinkWithId = {\n      href: relativePath,\n      type: manifest.MediaType,\n      id: manifest.ID,\n    };\n\n    // if it is an image, we should get the height and width\n    if (link.type?.includes('image/')) {\n      const fullPath = epub.fetcher.resolvePath(epub.opfPath, decodedHref);\n      const dimensions = await epub.fetcher.getImageDimensions(fullPath);\n      if (dimensions?.width && dimensions.height) {\n        link.width = dimensions.width;\n        link.height = dimensions.height;\n      }\n    }\n\n    const linkWithProperties = addEpub3Properties(epub, manifest, link);\n\n    return linkWithProperties;\n  };\n\n/**\n * EPUB 3\n * Add the properties to the link. This is barely implemented\n * and there is much more to add if we want. It is found in:\n * Readium Code: https://github.com/readium/r2-shared-js/blob/79378116dd296ad3c8dd474818a0cd37fc84dd53/src/parser/epub.ts#L441\n * EPUB 3 Spec: http://idpf.org/epub/30/spec/epub30-publications.html#sec-item-property-values\n * @TODO :\n *  - add media overlay\n */\nfunction addEpub3Properties(\n  epub: Epub,\n  manifest: Manifest,\n  link: LinkWithId\n): LinkWithId {\n  // get properties from both the manifest itself and the spine\n  const manifestProperties = Epub.parseSpaceSeparatedString(\n    manifest.Properties\n  );\n  const spineProperties = Epub.parseSpaceSeparatedString(\n    epub.opf.Spine?.Items?.find((item) => item.IDref === manifest.ID)\n      ?.Properties\n  );\n  const allProperties = [...manifestProperties, ...spineProperties];\n\n  for (const p of allProperties) {\n    switch (p) {\n      case 'cover-image':\n        link.rel = 'cover';\n        break;\n      case 'nav':\n        link.rel = 'contents';\n        break;\n      default:\n        break;\n    }\n  }\n  return link;\n}\n", "import { ReadiumWebpubContext } from '../constants';\nimport { WebpubManifest } from '../WebpubManifestTypes/WebpubManifest';\nimport Epub from '../Epub';\nimport { extractTocFromNavDoc } from './navdoc';\nimport { extractTocFromNcx } from './ncx';\nimport { extractMetadata } from './metadata';\nimport { resourcesAndReadingOrder } from './resourcesAndReadingOrder';\n\n/**\n * References:\n * - EPUB 2 Spec: http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm\n * - EPUB 3 Spec: http://idpf.org/epub/30/spec/epub30-publications.html\n *\n * @TODO (presently):\n * - Add media overlay?\n *\n * @TODO (in the future maybe):\n * - support NavMap, Page List and NavList from EPUB NCX and EPUB 3 Nav Doc\n *    http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4.1\n * - support more metadata\n * - Add links, like a self link to start with\n * - Add cover info. Search for the cover Meta, then find that manifes\n *    by the id of the cover, then add the info from the manifest to the\n *    link in resources.\n */\n\n/**\n * Main entrypoint to constructing a manifest from an opf and NCX\n */\nexport async function epubToManifest(epub: Epub): Promise<WebpubManifest> {\n  const metadata = extractMetadata(epub);\n  const resourcesObj = await resourcesAndReadingOrder(epub);\n  const toc = extractToc(epub);\n\n  return {\n    '@context': ReadiumWebpubContext,\n    metadata,\n    ...resourcesObj,\n    toc,\n    // we have not implemented any links\n    links: [],\n  };\n}\n\n/**\n * Only EPUB 2 uses the toc.ncx file. EPUB 3 uses\n * the spine insted. In EPUB 2, the spine defines the reading order\n * only, while in EPUB 3 it defines reading order and TOC.\n */\nfunction extractToc(epub: Epub): WebpubManifest['toc'] {\n  // detect versionjj\n  if (epub.version === '3') {\n    return extractTocFromNavDoc(epub);\n  }\n  if (!epub.ncx) {\n    throw new Error('EPUB 2 missing NCX file');\n  }\n  return extractTocFromNcx(epub, epub.ncx);\n}\n", "import Decryptor from '@nypl-simplified-packages/axisnow-access-control-web';\nimport { ImageDimensions } from './types';\n\nexport default abstract class Fetcher {\n  static readonly CONTAINER_PATH = 'META-INF/container.xml';\n  readonly folderPath: string;\n  readonly containerXmlPath: string;\n  readonly decryptor?: Decryptor;\n\n  constructor(containerXmlPath: string, decryptor?: Decryptor) {\n    this.containerXmlPath = containerXmlPath;\n    this.decryptor = decryptor;\n    const folderPath = containerXmlPath.replace(Fetcher.CONTAINER_PATH, '');\n    this.folderPath = folderPath;\n  }\n\n  abstract resolvePath(from: string, to: string): string;\n  abstract resolveRelativePath(from: string, to: string): string;\n\n  // this differs per fetcher because path.resolve(...) and new URL(...) don't work the same way\n  abstract getOpfPath(relativeOpfPath: string): string;\n\n  // the following functions take absolute paths/hrefs\n  abstract getArrayBuffer(path: string): Promise<ArrayBuffer>;\n  abstract getFileStr(path: string): Promise<string>;\n  abstract getImageDimensions(\n    path: string\n  ): Promise<ImageDimensions | undefined>;\n}\n", "import fs from 'fs';\nimport path from 'path';\nimport Epub from './Epub';\nimport sizeOf from 'image-size';\nimport { ImageDimensions } from './types';\nimport Decryptor from '@nypl-simplified-packages/axisnow-access-control-web';\nimport Fetcher from './Fetcher';\n\nexport default class LocalFetcher extends Fetcher {\n  constructor(\n    public readonly containerXmlPath: string,\n    public readonly decryptor?: Decryptor\n  ) {\n    super(containerXmlPath, decryptor);\n  }\n\n  getOpfPath(relativeOpfPath: string): string {\n    return path.resolve(this.containerXmlPath, '../../', relativeOpfPath);\n  }\n\n  resolvePath(from: string, to: string): string {\n    return path.resolve(from, '../', to);\n  }\n  resolveRelativePath(from: string, to: string): string {\n    return this.resolvePath(from, to).replace(this.folderPath, '');\n  }\n  async getArrayBuffer(path: string): Promise<ArrayBuffer> {\n    const buffer = fs.readFileSync(path, null);\n    return Promise.resolve(buffer);\n  }\n\n  getFileStr(path: string): Promise<string> {\n    return Promise.resolve(fs.readFileSync(path, 'utf-8'));\n  }\n\n  /**\n   * You must pass this function the absolute path to the image\n   */\n  async getImageDimensions(path: string): Promise<ImageDimensions | undefined> {\n    /**\n     * If the decryptor is defined, we read the file as a buffer, decrypt it\n     * and pass that to sizeOf. Otherwise we just pass the path and let it\n     * read the file internally.\n     */\n    let arg: string | Buffer = path;\n    if (this.decryptor) {\n      const buffer = await this.getArrayBuffer(path);\n      arg = Buffer.from(await Epub.decryptAb(buffer, this.decryptor));\n    }\n    const { width, height } = sizeOf(arg) ?? {};\n    if (typeof width === 'number' && typeof height === 'number') {\n      return { width, height };\n    }\n    return undefined;\n  }\n}\n", "import Epub from './Epub';\nimport fetch from 'node-fetch';\nimport sizeOf from 'image-size';\nimport Decryptor from '@nypl-simplified-packages/axisnow-access-control-web';\nimport Fetcher from './Fetcher';\n\nexport default class RemoteFetcher extends Fetcher {\n  constructor(\n    public readonly containerXmlPath: string,\n    public readonly decryptor?: Decryptor\n  ) {\n    super(containerXmlPath, decryptor);\n  }\n\n  /**\n   * Fetch a file and throw an error if the response is not ok.\n   */\n  async fetch(url: string): Promise<ReturnType<typeof fetch>> {\n    const result = await fetch(url);\n    if (!result.ok) {\n      throw new Error(`Could not fetch at: ${url}`);\n    }\n    return result;\n  }\n\n  async getArrayBuffer(url: string): Promise<ArrayBuffer> {\n    const result = await this.fetch(url);\n    return await result.arrayBuffer();\n  }\n\n  async getFileStr(url: string) {\n    const result = await this.fetch(url);\n    return await result.text();\n  }\n\n  getOpfPath(relativeOpfPath: string): string {\n    return this.resolvePath(this.folderPath, relativeOpfPath);\n  }\n\n  resolvePath(from: string, to: string): string {\n    return new URL(to, from).toString();\n  }\n  resolveRelativePath(from: string, to: string): string {\n    return this.resolvePath(from, to).replace(this.folderPath, '');\n  }\n\n  async getImageDimensions(relativePath: string) {\n    const url = this.resolvePath(this.folderPath, relativePath);\n    const response = await fetch(url);\n    if (!response.ok) {\n      throw new Error(`Could not fetch image at: ${url.toString()}`);\n    }\n    const buffer = await response.buffer();\n    const decrypted = await Epub.decryptAb(buffer, this.decryptor);\n    const { width, height } = sizeOf(Buffer.from(decrypted)) ?? {};\n    if (typeof width === 'number' && typeof height === 'number') {\n      return { width, height };\n    }\n    return undefined;\n  }\n}\n"],
  "mappings": "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",
  "names": []
}
