{"version":3,"sources":["../src/processor.ts","../src/geometry.ts","../src/tile-size.ts","../src/transform.ts","../src/v2/index.ts","../src/v2/info.ts","../src/v3/index.ts","../src/v3/info.ts","../src/versions.ts"],"sourcesContent":["import Debug from 'debug';\nimport mime from 'mime-types';\nimport path from 'path';\nimport sharp from 'sharp';\nimport { calculateGeometry, readGeometry } from './geometry';\nimport { Operations } from './transform';\nimport { IIIFError } from './error';\nimport Versions from './versions';\nimport type {\n  MaxDimensions,\n  ImageGeometry,\n  ProcessorResult,\n  ContentResult,\n  ErrorResult,\n  RedirectResult\n} from './types';\nimport type { VersionModule } from './contracts';\n\nconst debug = Debug('iiif-processor:main');\nconst debugv = Debug('verbose:iiif-processor');\n\nconst defaultpathPrefix = '/iiif/{{version}}/';\n\nfunction getIiifVersion(url: string, template: string) {\n  const { origin, pathname } = new URL(url);\n  const templateMatcher = template.replace(\n    /\\{\\{version\\}\\}/,\n    '(?<iiifVersion>\\\\d+)'\n  );\n  const pathMatcher = `^(?<prefix>${templateMatcher})(?<request>.+)$`;\n  const re = new RegExp(pathMatcher);\n  const parsed = re.exec(pathname);\n  if (parsed) {\n    parsed.groups.prefix = origin + parsed.groups.prefix;\n    return { ...parsed.groups } as {\n      prefix: string;\n      iiifVersion: string;\n      request: string;\n    };\n  } else {\n    throw new IIIFError('Invalid IIIF path');\n  }\n}\n\nexport type GeometryFunction = (input: {\n  id: string;\n  baseUrl: string;\n}) => Promise<ImageGeometry>;\nexport type StreamResolver = (input: {\n  id: string;\n  baseUrl: string;\n}) => Promise<NodeJS.ReadableStream>;\nexport type StreamResolverWithCallback = (\n  input: { id: string; baseUrl: string },\n  callback: (stream: NodeJS.ReadableStream) => Promise<unknown>\n) => Promise<unknown>;\nexport type ProcessorOptions = {\n  geometryFunction?: GeometryFunction;\n  max?: { width: number; height?: number; area?: number };\n  includeMetadata?: boolean;\n  density?: number;\n  debugBorder?: boolean;\n  iiifVersion?: number;\n  pageThreshold?: number;\n  pathPrefix?: string;\n  sharpOptions?: Record<string, unknown>;\n  request?: string;\n};\n\nexport class Processor {\n  private errorClass = IIIFError;\n  private Implementation!: VersionModule;\n  private imageGeometry?: ImageGeometry;\n  private sharpOptions?: Record<string, unknown>;\n\n  id!: string;\n  baseUrl!: string;\n  version!: number;\n  request!: string;\n  streamResolver!: StreamResolver | StreamResolverWithCallback;\n  filename?: string;\n\n  // parsed params from Calculator.parsePath\n  info?: string;\n  region!: string;\n  size!: string;\n  rotation!: string;\n  quality!: string;\n  format!: string;\n\n  // options\n  geometryFunction!: GeometryFunction;\n  max?: MaxDimensions;\n  includeMetadata = false;\n  density?: number | null;\n  debugBorder = false;\n  pageThreshold?: number;\n\n  constructor(\n    url: string,\n    streamResolver: StreamResolver | StreamResolverWithCallback,\n    opts: ProcessorOptions = {}\n  ) {\n    const { prefix, iiifVersion, request } = getIiifVersion(\n      url,\n      opts.pathPrefix || defaultpathPrefix\n    );\n\n    if (typeof streamResolver !== 'function') {\n      throw new IIIFError('streamResolver option must be specified');\n    }\n\n    if (opts.max?.height && !opts.max?.width) {\n      throw new IIIFError('maxHeight cannot be specified without maxWidth');\n    }\n\n    const defaults = {\n      geometryFunction: null,\n      density: null\n    };\n\n    this.setOpts({\n      ...defaults,\n      iiifVersion,\n      ...opts,\n      prefix,\n      request\n    }).initialize(streamResolver);\n  }\n\n  setOpts(opts) {\n    this.geometryFunction = opts.geometryFunction;\n    this.max = { ...opts.max };\n    this.includeMetadata = !!opts.includeMetadata;\n    this.density = opts.density;\n    this.baseUrl = opts.prefix;\n    this.debugBorder = !!opts.debugBorder;\n    this.pageThreshold = opts.pageThreshold;\n    this.sharpOptions = { ...opts.sharpOptions };\n    this.version = Number(opts.iiifVersion);\n    this.request = opts.request;\n    return this;\n  }\n\n  initialize(streamResolver: StreamResolver | StreamResolverWithCallback) {\n    this.Implementation = Versions[this.version] as VersionModule;\n    if (!this.Implementation) {\n      throw new IIIFError(\n        `No implementation found for IIIF Image API v${this.version}`\n      );\n    }\n\n    const params = this.Implementation.Calculator.parsePath(this.request);\n    debug('Parsed URL: %j', params);\n    Object.assign(this, params);\n    this.streamResolver = streamResolver;\n\n    if (this.quality && this.format) {\n      this.filename = [this.quality, this.format].join('.');\n    } else if (this.info) {\n      this.filename = 'info.json';\n    }\n    return this;\n  }\n\n  async withStream(callback: (s: NodeJS.ReadableStream) => Promise<unknown>) {\n    const { id, baseUrl } = this;\n    debug('Requesting stream for %s', id);\n    if (this.streamResolver.length === 2) {\n      return await (this.streamResolver as StreamResolverWithCallback)(\n        { id, baseUrl },\n        callback\n      );\n    } else {\n      const stream = await (this.streamResolver as StreamResolver)({\n        id,\n        baseUrl\n      });\n      return await callback(stream);\n    }\n  }\n\n  async geometry(includeTile = false): Promise<ImageGeometry> {\n    if (!this.imageGeometry) {\n      debug(\n        'Attempting to use geometryFunction to retrieve dimensions for %j',\n        this.id\n      );\n      const params = { id: this.id, baseUrl: this.baseUrl };\n      let geometry: ImageGeometry = {};\n      if (this.geometryFunction) {\n        geometry = await this.geometryFunction(params);\n      }\n      if (!(geometry.tileWidth && geometry.tileHeight) && !includeTile) {\n        geometry.tileWidth = null;\n        geometry.tileHeight = null;\n      }\n      geometry = await readGeometry(this.withStream.bind(this), geometry);\n      this.imageGeometry = calculateGeometry(geometry);\n    }\n    return this.imageGeometry;\n  }\n\n  async infoJson() {\n    const geometry = await this.geometry(true);\n    const uri = new URL(this.baseUrl);\n    // Node's URL has readonly pathname in types; construct via join on new URL\n    uri.pathname = path.join(uri.pathname, this.id);\n    const id = uri.toString();\n    const doc = this.Implementation.infoDoc({\n      id,\n      geometry,\n      max: this.max\n    });\n    for (const prop in doc) {\n      if (doc[prop] === null || doc[prop] === undefined) delete doc[prop];\n    }\n\n    const body = JSON.stringify(doc, (_key, value) =>\n      value?.constructor === Set ? [...value] : value\n    );\n    return {\n      type: 'content',\n      contentType: 'application/ld+json',\n      body\n    } as ContentResult;\n  }\n\n  operations({ sizes }: ImageGeometry) {\n    const sharpOpt = this.sharpOptions;\n    const { max, pageThreshold } = this;\n    debug('pageThreshold: %d', pageThreshold);\n    return new Operations(this.version, sizes, {\n      sharp: sharpOpt,\n      max,\n      pageThreshold\n    })\n      .region(this.region)\n      .size(this.size)\n      .rotation(this.rotation)\n      .quality(this.quality)\n      .format(this.format, this.density ?? undefined)\n      .withMetadata(this.includeMetadata);\n  }\n\n  async applyBorder(transformed: sharp.Sharp) {\n    const buf = await transformed.toBuffer();\n    const borderPipe = sharp(buf, { limitInputPixels: false });\n    const { width, height } = await borderPipe.metadata();\n    const background = { r: 255, g: 0, b: 0, alpha: 1 };\n\n    const topBorder = {\n      create: { width, height: 1, channels: 4, background } as sharp.Create\n    };\n    const bottomBorder = {\n      create: { width, height: 1, channels: 4, background } as sharp.Create\n    };\n    const leftBorder = {\n      create: { width: 1, height, channels: 4, background } as sharp.Create\n    };\n    const rightBorder = {\n      create: { width: 1, height, channels: 4, background } as sharp.Create\n    };\n\n    return borderPipe.composite([\n      { input: topBorder, left: 0, top: 0 },\n      { input: bottomBorder, left: 0, top: (height as number) - 1 },\n      { input: leftBorder, left: 0, top: 0 },\n      { input: rightBorder, left: (width as number) - 1, top: 0 }\n    ]);\n  }\n\n  async iiifImage() {\n    debugv('Request %s', this.request);\n    const geometry = await this.geometry();\n    const operations = this.operations(geometry);\n    debugv('Operations: %j', operations);\n    const pipeline = await operations.pipeline();\n\n    const result = await this.withStream(async (stream) => {\n      debug('piping stream to pipeline');\n      let transformed = await stream.pipe(pipeline);\n      if (this.debugBorder) {\n        transformed = await this.applyBorder(transformed);\n      }\n      debug('converting to buffer');\n      return await transformed.toBuffer();\n    });\n    debug('returning %d bytes', (result as Buffer).length);\n    debug('baseUrl', this.baseUrl);\n\n    const canonicalUrl = new URL(\n      path.join(this.id, operations.canonicalPath()),\n      this.baseUrl\n    );\n    return {\n      type: 'content',\n      canonicalLink: canonicalUrl.toString(),\n      profileLink: this.Implementation.profileLink,\n      contentType: mime.lookup(this.format) as string,\n      body: result as Buffer\n    } as ContentResult;\n  }\n\n  async execute(): Promise<ProcessorResult> {\n    try {\n      if (this.format === undefined && this.info === undefined) {\n        debug('No format or info.json requested; redirecting to info.json');\n        return {\n          location: new URL(\n            path.join(this.id, 'info.json'),\n            this.baseUrl\n          ).toString(),\n          type: 'redirect'\n        } as RedirectResult;\n      }\n\n      if (this.filename === 'info.json') {\n        return await this.infoJson();\n      }\n\n      return await this.iiifImage();\n    } catch (err) {\n      if (err instanceof IIIFError) {\n        debug('IIIFError caught: %j', err);\n        return {\n          type: 'error',\n          message: err.message,\n          statusCode: err.statusCode || 500\n        } as ErrorResult;\n      } else {\n        throw err;\n      }\n    }\n  }\n}\n\nexport default Processor;\n","import Debug from 'debug';\nimport type { ImageGeometry } from './types';\nimport sharp from 'sharp';\nimport { Readable } from 'stream';\nimport { getTileSize } from './tile-size';\n\nconst debug = Debug('iiif:geometry');\n\ntype StreamCallback = (stream: Readable) => Promise<unknown>;\n\nexport async function readGeometry(\n  withStream: (callback: StreamCallback) => Promise<unknown>,\n  geometry: ImageGeometry\n): Promise<ImageGeometry> {\n  let metadata = {} as ImageGeometry;\n  let tileSize = {} as ImageGeometry;\n  const result = { ...geometry };\n\n  debug('Initial geometry: %O', geometry);\n\n  if (\n    !geometry.width ||\n    !geometry.height ||\n    !(geometry.pages || geometry.sizes)\n  ) {\n    await withStream(async (metadataStream) => {\n      metadata = await readMetadata(metadataStream);\n    });\n    if (!metadata.pages) metadata.pages = 1;\n    debug('Read metadata: %O', metadata);\n  }\n\n  if (geometry.tileWidth === undefined) {\n    await withStream(async (sizeStream) => {\n      const size = await getTileSize(sizeStream);\n      tileSize = { tileWidth: size.width, tileHeight: size.height };\n    });\n    debug('Read tile size: %O', tileSize);\n  }\n\n  const final = { ...result, ...metadata, ...tileSize };\n  debug('Final geometry: %O', final);\n  return final;\n}\n\nexport function calculateGeometry(geometry: ImageGeometry): ImageGeometry {\n  if (geometry.sizes) {\n    const result: ImageGeometry = { ...geometry };\n    if (!geometry.pages) {\n      result.pages = geometry.sizes.length;\n    }\n    if (!geometry.width || !geometry.height) {\n      result.width = geometry.sizes[0].width;\n      result.height = geometry.sizes[0].height;\n    }\n    return result;\n  }\n\n  if (geometry.width && geometry.height) {\n    if (geometry.pages)\n      if (geometry.pages === 1) {\n        return {\n          ...geometry,\n          sizes: [{ width: geometry.width, height: geometry.height }]\n        };\n      }\n    if (geometry.pages > 1) {\n      return calculateSizesFromPages(geometry);\n    }\n    if (geometry.tileWidth && geometry.tileHeight) {\n      return calculateSizesFromTiles(geometry);\n    }\n  }\n\n  return geometry;\n}\n\nasync function readMetadata(stream: Readable): Promise<ImageGeometry> {\n  const target = sharp({ limitInputPixels: false, page: 0 });\n\n  stream.pipe(target);\n  const { autoOrient, ...metadata } = await target.metadata();\n  const { width, height, pages } = { ...metadata, ...autoOrient };\n  return { width, height, pages };\n}\n\nfunction calculateSizesFromTiles(geometry: ImageGeometry): ImageGeometry {\n  const pages =\n    Math.max(\n      Math.ceil(Math.log2(geometry.width! / geometry.tileWidth!)),\n      Math.ceil(Math.log2(geometry.height! / geometry.tileHeight!))\n    ) + 1;\n  return calculateSizesFromPages({ ...geometry, pages });\n}\n\nfunction calculateSizesFromPages(geometry: ImageGeometry): ImageGeometry {\n  const result: ImageGeometry = { ...geometry };\n  result.sizes = [{ width: geometry.width, height: geometry.height }];\n  let page = 0;\n  for (page += 1; page < geometry.pages; page++) {\n    const scale = 1 / 2 ** page;\n    result.sizes.push({\n      width: Math.floor(geometry.width * scale),\n      height: Math.floor(geometry.height * scale)\n    });\n  }\n  return result;\n}\n","import { Readable } from 'stream';\n\nexport interface TileSize {\n  width: number | undefined | null;\n  height: number | undefined | null;\n}\n\ntype ImageFormat = 'tiff-le' | 'tiff-be' | 'jp2' | 'unknown';\n\nconst CHUNK_SIZE = 5 * 1024; // 5KB\n\n/**\n * Wraps a Readable stream in an async interface that accumulates chunks\n * on demand. Call `ensure(n)` to buffer at least `n` bytes, then read\n * from `buf` directly.\n */\nclass StreamBuffer {\n  private chunks: Buffer[] = [];\n  private _length = 0;\n  private done = false;\n  private iterator: AsyncIterableIterator<Buffer>;\n\n  constructor(stream: Readable) {\n    stream.pause();\n    this.iterator = stream[\n      Symbol.asyncIterator\n    ]() as AsyncIterableIterator<Buffer>;\n  }\n\n  get length() {\n    return this._length;\n  }\n\n  get buf(): Buffer {\n    return Buffer.concat(this.chunks);\n  }\n\n  /** Buffer at least `needed` bytes, or until stream is exhausted. */\n  async ensure(needed: number): Promise<void> {\n    while (this._length < needed && !this.done) {\n      const { value, done } = await this.iterator.next();\n      if (done) {\n        this.done = true;\n      } else {\n        this.chunks.push(value);\n        this._length += value.length;\n      }\n    }\n  }\n\n  /** Read `count` bytes starting at `offset`, fetching more chunks if needed. */\n  async read(offset: number, count: number): Promise<Buffer> {\n    await this.ensure(offset + count);\n    return this.buf.subarray(offset, offset + count);\n  }\n}\n\nconst magicNumbers = [\n  { type: 'tiff-le', magic: Buffer.from([0x49, 0x49, 0x2a, 0x00]) },\n  { type: 'tiff-be', magic: Buffer.from([0x4d, 0x4d, 0x00, 0x2a]) },\n  { type: 'jp2', magic: Buffer.from([0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50]) },\n  { type: 'jp2', magic: Buffer.from([0xff, 0x4f]) }\n];\n\nfunction detectFormat(buf: Buffer): ImageFormat {\n  if (buf.length < 8) return 'unknown';\n  for (const { type, magic } of magicNumbers) {\n    if (buf.subarray(0, magic.length).equals(magic)) return type as ImageFormat;\n  }\n  return 'unknown';\n}\n\nasync function getTiffTileSize(\n  sb: StreamBuffer,\n  littleEndian: boolean\n): Promise<TileSize> {\n  const readUInt16 = (buf: Buffer, offset: number) =>\n    littleEndian ? buf.readUInt16LE(offset) : buf.readUInt16BE(offset);\n  const readUInt32 = (buf: Buffer, offset: number) =>\n    littleEndian ? buf.readUInt32LE(offset) : buf.readUInt32BE(offset);\n\n  // Bytes 4-7 contain the IFD offset\n  const header = await sb.read(0, 8);\n  const ifdOffset = readUInt32(header, 4);\n\n  // First 2 bytes of the IFD are the entry count\n  const ifdHeader = await sb.read(ifdOffset, 2);\n  const entryCount = readUInt16(ifdHeader, 0);\n\n  // Each IFD entry is 12 bytes\n  const ifdData = await sb.read(ifdOffset + 2, entryCount * 12);\n\n  let width: number | undefined | null;\n  let height: number | undefined | null;\n\n  for (let i = 0; i < entryCount; i++) {\n    const entryOffset = i * 12;\n    const tag = readUInt16(ifdData, entryOffset);\n    const value = readUInt32(ifdData, entryOffset + 8);\n\n    if (tag === 322) width = value; // TileWidth\n    if (tag === 323) height = value; // TileLength\n\n    if (width !== undefined && height !== undefined) break;\n  }\n\n  return { width, height };\n}\n\nasync function getJP2TileSize(sb: StreamBuffer): Promise<TileSize> {\n  const magic = await sb.read(0, 2);\n  const isRawCodestream = magic[0] === 0xff && magic[1] === 0x4f;\n\n  let offset = 0;\n\n  if (!isRawCodestream) {\n    // Walk JP2 boxes to find the jp2c (codestream) box\n    let foundCodestream = false;\n    while (true) {\n      const boxHeader = await sb.read(offset, 8);\n      if (boxHeader.length < 8) break;\n\n      const boxLength = boxHeader.readUInt32BE(0);\n      const boxType = boxHeader.readUInt32BE(4);\n\n      if (boxType === 0x6a703263) {\n        // 'jp2c'\n        offset += 8; // skip box header, now pointing at codestream\n        foundCodestream = true;\n        break;\n      }\n\n      if (boxLength < 8) break; // malformed\n      offset += boxLength;\n    }\n\n    if (!foundCodestream) return { width: null, height: null };\n  }\n\n  // Scan for SIZ marker (FF51), reading in chunks to avoid buffering the whole file\n  while (true) {\n    const chunk = await sb.read(offset, CHUNK_SIZE);\n    if (chunk.length < 2) break;\n\n    for (let i = 0; i < chunk.length - 1; i++) {\n      if (chunk[i] === 0xff && chunk[i + 1] === 0x51) {\n        // SIZ layout from marker start:\n        //   FF51 (2) + segment length (2) + Rsiz (2) + Xsiz (4) + Ysiz (4)\n        //   + XOsiz (4) + YOsiz (4) = 22 bytes before XTsiz\n        const sizData = await sb.read(offset + i + 22, 8);\n        if (sizData.length < 8) return { width: null, height: null };\n        return {\n          width: sizData.readUInt32BE(0), // XTsiz\n          height: sizData.readUInt32BE(4) // YTsiz\n        };\n      }\n    }\n\n    if (chunk.length < CHUNK_SIZE) break; // end of stream\n    offset += CHUNK_SIZE - 1; // overlap by 1 to avoid missing a marker at a chunk boundary\n  }\n\n  return { width: null, height: null };\n}\n\nexport async function getTileSize(stream: Readable): Promise<TileSize> {\n  const sb = new StreamBuffer(stream);\n\n  // Read just enough to detect the format\n  await sb.ensure(8);\n  const format = detectFormat(sb.buf);\n\n  if (format === 'tiff-le' || format === 'tiff-be') {\n    return getTiffTileSize(sb, format === 'tiff-le');\n  }\n\n  if (format === 'jp2') {\n    return getJP2TileSize(sb);\n  }\n\n  return { width: null, height: null };\n}\n","import Sharp, { Sharp as SharpType } from 'sharp';\nimport Debug from 'debug';\nimport { Versions } from './versions';\nimport type { VersionModule, CalculatorLike, CalculatorOptions } from './contracts';\nimport type { Dimensions, BoundingBox, Format } from './types';\n\nconst debug = Debug('iiif-processor:transform');\n\nconst DEFAULT_PAGE_THRESHOLD = 1;\nconst SCALE_PRECISION = 10000000;\n\ntype PageDim = { width: number; height: number; page: number };\n\nexport class Operations {\n  private keepMetadata?: boolean;\n  private pages: PageDim[];\n  private sharpOptions?: Record<string, unknown>;\n  private calculator: CalculatorLike;\n  private pageThreshold: number;\n\n  constructor (version: number, dims: Dimensions[], opts: CalculatorOptions & { sharp?: Record<string, unknown>; pageThreshold?: number }) {\n    const { sharp, pageThreshold, ...rest } = { ...opts };\n    const Implementation: VersionModule = Versions[version];\n    this.calculator = new Implementation.Calculator(dims[0], rest);\n    this.pageThreshold = typeof pageThreshold === 'number' ? pageThreshold : DEFAULT_PAGE_THRESHOLD;\n\n    this.pages = dims\n      .map((dim, page) => ({ ...dim, page }))\n      .sort((a, b) => b.width * b.height - a.width * a.height);\n    this.sharpOptions = sharp;\n  }\n\n  region (v: string) {\n    this.calculator.region(v);\n    return this;\n  }\n\n  size (v: string) {\n    this.calculator.size(v);\n    return this;\n  }\n\n  rotation (v: string) {\n    this.calculator.rotation(v);\n    return this;\n  }\n\n  quality (v: string) {\n    this.calculator.quality(v);\n    return this;\n  }\n\n  format (v: string, density?: number) {\n    this.calculator.format(v, density);\n    return this;\n  }\n\n  info () {\n    return this.calculator.info();\n  }\n\n  canonicalPath () {\n    return this.calculator.canonicalPath();\n  }\n\n  withMetadata (v: boolean) {\n    this.keepMetadata = v;\n    return this;\n  }\n\n  private computePage () {\n    const { fullSize } = this.info();\n    const { page } = this.pages.find((_candidate, index) => {\n      const next = this.pages[index + 1];\n      debug('comparing candidate %j to target %j with a %d-pixel buffer', next, fullSize, this.pageThreshold);\n      return !next || (next.width + this.pageThreshold < fullSize.width && next.height + this.pageThreshold < fullSize.height);\n    }) as PageDim;\n\n    const resolution = this.pages[page];\n    const scale = page === 0 ? 1 : Math.round((resolution.width / this.pages[0].width) * SCALE_PRECISION) / SCALE_PRECISION;\n    debug('Using page %d (%j) as source and scaling by %f', page, resolution, scale);\n    return { page, scale };\n  }\n\n  pipeline (): SharpType {\n    const pipeline = Sharp({\n      limitInputPixels: false,\n      ...{ ...this.sharpOptions }\n    });\n    const { page, scale } = this.computePage();\n    (pipeline as any).options.input.page = page; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n    const { format, quality, region, rotation: { flop, degree }, size } = this.info();\n    scaleRegion(region, scale, this.pages[page]);\n\n    pipeline.autoOrient().extract(region).resize(size);\n    if (flop) pipeline.flop();\n    pipeline.rotate(degree);\n    if (quality === 'gray') pipeline.grayscale();\n    if (quality === 'bitonal') pipeline.threshold();\n    setFormat(pipeline, format);\n    if (this.keepMetadata) pipeline.keepMetadata();\n\n    debug('Pipeline: %j', { page, region, size, rotation: { flop, degree }, quality, format });\n    return pipeline;\n  }\n}\n\nfunction setFormat (pipeline: SharpType, format: { type: Format; density?: number }) {\n  let pipelineFormat;\n  const pipelineOptions: any = {}; // eslint-disable-line @typescript-eslint/no-explicit-any\n\n  switch (format.type) {\n    case 'jpeg':\n      pipelineFormat = 'jpg';\n      break;\n    case 'tif':\n      pipelineFormat = 'tiff';\n      if (format.density) {\n        pipelineOptions.xres = format.density / 25.4;\n        pipelineOptions.yres = format.density / 25.4;\n      }\n      break;\n    default:\n      pipelineFormat = format.type;\n  }\n  pipeline.toFormat(pipelineFormat, pipelineOptions);\n  if (format.density) {\n    pipeline.withMetadata({ density: format.density });\n  }\n}\n\nfunction scaleRegion (region: BoundingBox, scale: number, page: { width: number; height: number }) {\n  region.left = Math.floor(region.left * scale);\n  region.top = Math.floor(region.top * scale);\n  region.width = Math.floor(region.width * scale);\n  region.height = Math.floor(region.height * scale);\n  region.left = Math.max(region.left, 0);\n  region.top = Math.max(region.top, 0);\n  region.width = Math.min(region.width, page.width);\n  region.height = Math.min(region.height, page.height);\n  return region;\n}\n\nexport default { Operations };\n","export * from './info';\nexport * from '../calculator/v2';\n","import { Dimensions } from '../types';\nimport { Formats, Qualities } from '../calculator/v2';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport Debug from 'debug';\nimport type { InfoDocInput, InfoDoc } from '../contracts';\nconst profileLink = 'http://iiif.io/api/image/2/level2.json';\n\nconst IIIFProfile = {\n  formats: new Set(Formats),\n  qualities: new Set(Qualities),\n  supports: new Set([\n    'baseUriRedirect',\n    'canonicalLinkHeader',\n    'cors',\n    'jsonldMediaType',\n    'mirroring',\n    'profileLinkHeader',\n    'regionByPct',\n    'regionByPx',\n    'regionSquare',\n    'rotationArbitrary',\n    'rotationBy90s',\n    'sizeAboveFull',\n    'sizeByConfinedWh',\n    'sizeByDistortedWh',\n    'sizeByForcedWh',\n    'sizeByH',\n    'sizeByPct',\n    'sizeByW',\n    'sizeByWh',\n    'sizeByWhListed'\n  ])\n};\n\nexport function infoDoc({ id, geometry, max }: InfoDocInput): InfoDoc {\n  const maxAttrs = {\n    maxWidth: max?.width,\n    maxHeight: max?.height,\n    maxArea: max?.area\n  };\n\n  const { width, height, sizes } = geometry;\n  const tiles = geometry.tileWidth\n    ? [\n        {\n          width: geometry.tileWidth,\n          height: geometry.tileHeight || geometry.tileWidth,\n          scaleFactors: sizes.map((_v: Dimensions, i: number) => 2 ** i)\n        }\n      ]\n    : undefined;\n  return {\n    '@context': 'http://iiif.io/api/image/2/context.json',\n    '@id': id,\n    protocol: 'http://iiif.io/api/image',\n    width,\n    height,\n    sizes,\n    tiles,\n    profile: [profileLink, { ...IIIFProfile, ...maxAttrs }]\n  };\n}\n\nexport { profileLink };\n","export * from './info';\nexport * from '../calculator/v3';\n","import { Dimensions } from '../types';\nimport { Formats, Qualities } from '../calculator/v3';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport Debug from 'debug';\nimport type { InfoDocInput, InfoDoc } from '../contracts';\n\nexport const profileLink = 'https://iiif.io/api/image/3/level2.json';\n\nconst defaultFormats: Set<string> = new Set(['jpg', 'png']);\nconst defaultQualities: Set<string> = new Set(['default']);\nconst IIIFExtras = {\n  extraFeatures: [\n    'canonicalLinkHeader',\n    'mirroring',\n    'profileLinkHeader',\n    'rotationArbitrary',\n    'sizeByDistortedWh',\n    'sizeByForcedWh',\n    'sizeByWhListed',\n    'sizeUpscaling'\n  ],\n  extraFormats: new Set(Formats.filter((f) => !defaultFormats.has(f))),\n  extraQualities: new Set(Qualities.filter((q) => !defaultQualities.has(q)))\n};\n\nexport function infoDoc({ id, geometry, max }: InfoDocInput): InfoDoc {\n  const maxAttrs = {\n    maxWidth: max?.width,\n    maxHeight: max?.height,\n    maxArea: max?.area\n  };\n\n  const { width, height, sizes } = geometry;\n  const tiles = geometry.tileWidth\n    ? [\n        {\n          width: geometry.tileWidth,\n          height: geometry.tileHeight || geometry.tileWidth,\n          scaleFactors: sizes.map((_v: Dimensions, i: number) => 2 ** i)\n        }\n      ]\n    : undefined;\n  return {\n    '@context': 'http://iiif.io/api/image/3/context.json',\n    id,\n    type: 'ImageService3',\n    protocol: 'http://iiif.io/api/image',\n    profile: 'level2',\n    width,\n    height,\n    sizes,\n    tiles,\n    ...IIIFExtras,\n    ...maxAttrs\n  };\n}\n","import * as v2 from './v2';\nimport * as v3 from './v3';\nimport type { VersionModule } from './contracts';\n\nexport const Versions: Record<2 | 3, VersionModule> = {\n  2: v2 as unknown as VersionModule,\n  3: v3 as unknown as VersionModule\n};\n\nexport default Versions;\n"],"mappings":"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","names":["Debug","sharp","Debug","Calculator","infoDoc","profileLink","profileLink","infoDoc","debug","Debug","sharp","debug","Debug","sharp"]}