{"version":3,"sources":["../src/core/effects/LasciiImageEffect.ts"],"names":["_LasciiImageEffect","LasciiEmitter","img","index","options","ResourceTracker","prefersReducedMotion","id","handler","delay","time","type","error","context","err","toError","logLasciiError","width","target","maxCols","cols","measureCtx","wrapper","asciiGrid","brightnessGrid","imageAspect","itemAspect","cropX","cropY","cropW","cropH","samplingCanvas","samplingCtx","data","row","asciiRow","brightnessRow","col","pixelIndex","brightness","charIndex","totalCells","scrambleState","settledCount","cellOrder","_","i","failAnimation","stillScrambling","cellIndex","remaining","char","array","j","selector","images","LasciiImageEffect","LasciiImageEffect_default"],"mappings":"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","file":"chunk-WDVGOYIF.cjs","sourcesContent":["import { type Disposable, ResourceTracker } from \"../disposable.js\";\r\nimport {\r\n  type LasciiErrorContext,\r\n  type LasciiErrorType,\r\n  logLasciiError,\r\n  toError,\r\n} from \"../errors.js\";\r\nimport { LasciiEmitter } from \"../events.js\";\r\nimport { prefersReducedMotion } from \"../a11y.js\";\r\n\r\nexport type {\r\n  LasciiCompleteDetail,\r\n  LasciiErrorDetail,\r\n  LasciiProgressDetail,\r\n  LasciiStartDetail,\r\n} from \"../events.js\";\r\nexport { LasciiEvent } from \"../events.js\";\r\n\r\nexport interface LasciiImageEffectOptions {\r\n  ASCII_CHARS?: string;\r\n  FONT_SIZE?: number;\r\n  ASPECT_WIDTH?: number;\r\n  ASPECT_HEIGHT?: number;\r\n  ASCII_COLUMNS?: number;\r\n  MAX_ASCII_COLUMNS?: number;\r\n  TARGET_CELL_CSS_PX?: number;\r\n  IMAGE_STAGGER_MS?: number;\r\n  CELL_APPEAR_MS?: number;\r\n  SCRAMBLE_COUNT?: number;\r\n  SCRAMBLE_SPEED_MS?: number;\r\n  REVEAL_DELAY_MS?: number;\r\n  BACKGROUND_COLOR?: string;\r\n  TEXT_COLOR?: string;\r\n  reducedMotion?: boolean;\r\n}\r\n\r\nexport interface LasciiImageEffectDefaults\r\n  extends Required<Omit<LasciiImageEffectOptions, \"reducedMotion\">> {}\r\n\r\nclass LasciiImageEffect extends LasciiEmitter implements Disposable {\r\n  static DEFAULTS: LasciiImageEffectDefaults = {\r\n    ASCII_CHARS: \" . . . . . . :::=+xX#0369\",\r\n    FONT_SIZE: 40,\r\n    ASPECT_WIDTH: 4,\r\n    ASPECT_HEIGHT: 5,\r\n    ASCII_COLUMNS: 25,\r\n    MAX_ASCII_COLUMNS: 96,\r\n    TARGET_CELL_CSS_PX: 9,\r\n    IMAGE_STAGGER_MS: 100,\r\n    CELL_APPEAR_MS: 0.5,\r\n    SCRAMBLE_COUNT: 10,\r\n    SCRAMBLE_SPEED_MS: 50,\r\n    REVEAL_DELAY_MS: 0,\r\n    BACKGROUND_COLOR: \"transparent\",\r\n    TEXT_COLOR: \"#c8c8c8\",\r\n  };\r\n\r\n  img: HTMLImageElement;\r\n  index: number;\r\n  config: LasciiImageEffectDefaults;\r\n  _minAsciiColumns: number;\r\n  canvas: HTMLCanvasElement;\r\n  ctx: CanvasRenderingContext2D | null;\r\n  staggerDelay: number;\r\n  failed: boolean;\r\n  charWidth!: number;\r\n  charHeight!: number;\r\n  ASCII_ROWS!: number;\r\n  denseCharIndex!: number;\r\n  denseChars!: string[];\r\n  samplingImg!: HTMLImageElement;\r\n  private readonly tracker = new ResourceTracker();\r\n  private readonly activeTimeouts: Array<ReturnType<typeof setTimeout>> = [];\r\n  private scrambleTicker: ReturnType<typeof setInterval> | null = null;\r\n  private revealScheduled = false;\r\n  private readonly reduceMotion: boolean;\r\n\r\n  constructor(\r\n    img: HTMLImageElement,\r\n    index = 0,\r\n    options: LasciiImageEffectOptions = {},\r\n  ) {\r\n    super();\r\n    this.img = img;\r\n    this.index = index;\r\n    this.config = { ...LasciiImageEffect.DEFAULTS, ...options };\r\n    this._minAsciiColumns = this.config.ASCII_COLUMNS;\r\n    this.canvas = document.createElement(\"canvas\");\r\n    this.canvas.setAttribute(\"aria-hidden\", \"true\");\r\n    this.ctx = null;\r\n    this.reduceMotion = prefersReducedMotion(options.reducedMotion);\r\n    this.staggerDelay = this.index * this.config.IMAGE_STAGGER_MS;\r\n    this.failed = false;\r\n\r\n    this.tracker.track(() => {\r\n      this.clearTimers();\r\n      this.canvas.remove();\r\n      this.clearSamplingImage();\r\n      this.img.removeAttribute(\"aria-busy\");\r\n    });\r\n\r\n    if (this.reduceMotion) {\r\n      this.img.style.opacity = \"1\";\r\n      queueMicrotask(() => this.finishWithoutAnimation());\r\n      return;\r\n    }\r\n\r\n    this.img.style.opacity = \"0\";\r\n    this.img.setAttribute(\"aria-busy\", \"true\");\r\n    this.ctx = this.canvas.getContext(\"2d\");\r\n\r\n    if (!this.ctx) {\r\n      queueMicrotask(() => {\r\n        if (this.tracker.isDisposed) return;\r\n        this.handleError(\r\n          \"canvas_context_unavailable\",\r\n          new Error(\"Unable to acquire 2d rendering context\"),\r\n        );\r\n      });\r\n      return;\r\n    }\r\n\r\n    this.load();\r\n  }\r\n\r\n  get disposed(): boolean {\r\n    return this.tracker.isDisposed;\r\n  }\r\n\r\n  dispose(): void {\r\n    if (this.tracker.isDisposed) return;\r\n    this.failed = true;\r\n    this.tracker.dispose();\r\n    this.img.style.opacity = \"1\";\r\n  }\r\n\r\n  private ensureNotDisposed(): void {\r\n    if (this.tracker.isDisposed) {\r\n      throw new Error(\"LasciiImageEffect has been disposed\");\r\n    }\r\n  }\r\n\r\n  private clearSamplingImage(): void {\r\n    if (!this.samplingImg) return;\r\n    this.samplingImg.onload = null;\r\n    this.samplingImg.onerror = null;\r\n    this.samplingImg.src = \"\";\r\n  }\r\n\r\n  private clearTimers(): void {\r\n    for (const id of this.activeTimeouts) {\r\n      clearTimeout(id);\r\n    }\r\n    this.activeTimeouts.length = 0;\r\n    if (this.scrambleTicker !== null) {\r\n      clearInterval(this.scrambleTicker);\r\n      this.scrambleTicker = null;\r\n    }\r\n  }\r\n\r\n  private trackTimeout(\r\n    handler: () => void,\r\n    delay: number,\r\n  ): ReturnType<typeof setTimeout> {\r\n    const id = setTimeout(() => {\r\n      const index = this.activeTimeouts.indexOf(id);\r\n      if (index >= 0) this.activeTimeouts.splice(index, 1);\r\n      handler();\r\n    }, delay);\r\n    this.activeTimeouts.push(id);\r\n    return id;\r\n  }\r\n\r\n  private trackAnimationFrame(handler: FrameRequestCallback): number {\r\n    const id = requestAnimationFrame((time) => {\r\n      handler(time);\r\n    });\r\n    this.tracker.track(() => cancelAnimationFrame(id));\r\n    return id;\r\n  }\r\n\r\n  private handleError(\r\n    type: LasciiErrorType | string,\r\n    error: unknown,\r\n    context: LasciiErrorContext = {},\r\n  ): void {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n    this.failed = true;\r\n    const err = toError(error);\r\n    logLasciiError(type, err, {\r\n      element: this.img,\r\n      config: this.config,\r\n      ...context,\r\n    });\r\n    this.clearTimers();\r\n    this.cleanup();\r\n    this.fallbackToOriginal();\r\n    this.img.removeAttribute(\"aria-busy\");\r\n    this.emit(\"error\", { error: err });\r\n  }\r\n\r\n  private cleanup(): void {\r\n    this.canvas.remove();\r\n    this.clearSamplingImage();\r\n  }\r\n\r\n  private fallbackToOriginal(): void {\r\n    this.img.style.opacity = \"1\";\r\n  }\r\n\r\n  applyDisplayScaledColumns(): void {\r\n    const rect = this.img.getBoundingClientRect();\r\n    const width = rect.width;\r\n    if (width < 8) return;\r\n    const target = this.config.TARGET_CELL_CSS_PX;\r\n    const maxCols = this.config.MAX_ASCII_COLUMNS;\r\n    const cols = Math.min(\r\n      maxCols,\r\n      Math.max(this._minAsciiColumns, Math.round(width / target)),\r\n    );\r\n    this.config.ASCII_COLUMNS = cols;\r\n  }\r\n\r\n  measureCharacters(): void {\r\n    const measureCtx = document.createElement(\"canvas\").getContext(\"2d\");\r\n    if (!measureCtx) {\r\n      throw new Error(\"Unable to acquire 2d context for character measurement\");\r\n    }\r\n    measureCtx.font = `${this.config.FONT_SIZE}px monospace`;\r\n    this.charWidth = Math.ceil(measureCtx.measureText(\"M\").width);\r\n    this.charHeight = this.config.FONT_SIZE;\r\n    this.ASCII_ROWS = Math.round(\r\n      this.config.ASCII_COLUMNS *\r\n        (this.config.ASPECT_HEIGHT / this.config.ASPECT_WIDTH) *\r\n        (this.charWidth / this.charHeight),\r\n    );\r\n    this.denseCharIndex = this.config.ASCII_CHARS.lastIndexOf(\".\");\r\n    this.denseChars = this.config.ASCII_CHARS.slice(\r\n      this.denseCharIndex + 1,\r\n    ).split(\"\");\r\n  }\r\n\r\n  prepareCanvas(): void {\r\n    if (!this.ctx) {\r\n      throw new Error(\"Canvas 2d context is not available\");\r\n    }\r\n    this.canvas.width = this.config.ASCII_COLUMNS * this.charWidth;\r\n    this.canvas.height = this.ASCII_ROWS * this.charHeight;\r\n    this.ctx.font = `${this.charHeight}px monospace`;\r\n    this.ctx.textBaseline = \"top\";\r\n  }\r\n\r\n  attachCanvas(): void {\r\n    const wrapper = this.img.parentElement;\r\n    if (wrapper) {\r\n      this.img.style.opacity = \"0\";\r\n      this.canvas.style.position = \"absolute\";\r\n      this.canvas.style.top = \"0\";\r\n      this.canvas.style.left = \"0\";\r\n      this.canvas.style.width = \"100%\";\r\n      this.canvas.style.height = \"100%\";\r\n      this.canvas.style.objectFit = \"cover\";\r\n      const computedPosition = getComputedStyle(wrapper).position;\r\n      if (computedPosition === \"static\") {\r\n        wrapper.style.position = \"relative\";\r\n      }\r\n      if (!this.canvas.isConnected) {\r\n        wrapper.appendChild(this.canvas);\r\n      }\r\n    }\r\n  }\r\n\r\n  load(): void {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n\r\n    this.samplingImg = new Image();\r\n    this.samplingImg.crossOrigin = \"anonymous\";\r\n    this.samplingImg.onload = () => {\r\n      if (this.failed || this.tracker.isDisposed) return;\r\n      this.trackAnimationFrame(() => {\r\n        if (this.failed || this.tracker.isDisposed) return;\r\n        this.trackAnimationFrame(() => {\r\n          if (this.failed || this.tracker.isDisposed) return;\r\n          try {\r\n            this.applyDisplayScaledColumns();\r\n            this.measureCharacters();\r\n            this.prepareCanvas();\r\n            this.attachCanvas();\r\n            this.start();\r\n          } catch (error) {\r\n            this.handleError(\"canvas_initialization_failed\", error);\r\n          }\r\n        });\r\n      });\r\n    };\r\n    this.samplingImg.onerror = () => {\r\n      this.handleError(\r\n        \"image_load_failed\",\r\n        new Error(\"Failed to load sampling image\"),\r\n        { src: this.img.src },\r\n      );\r\n    };\r\n    this.samplingImg.src = this.img.src;\r\n  }\r\n\r\n  start(): void {\r\n    this.ensureNotDisposed();\r\n    if (this.failed || !this.ctx) return;\r\n    try {\r\n      this.img.setAttribute(\"aria-busy\", \"true\");\r\n      this.emit(\"start\", { text: this.label() });\r\n      this.emit(\"progress\", { progress: 0 });\r\n      const { asciiGrid, brightnessGrid } = this.imageToAsciiGrid();\r\n      this.animateCells(asciiGrid, brightnessGrid);\r\n    } catch (error) {\r\n      this.handleError(\"image_animation_failed\", error);\r\n    }\r\n  }\r\n\r\n  imageToAsciiGrid(): {\r\n    asciiGrid: string[][];\r\n    brightnessGrid: number[][];\r\n  } {\r\n    const img = this.samplingImg;\r\n    const imageAspect = img.naturalWidth / img.naturalHeight;\r\n    const itemAspect = this.config.ASPECT_WIDTH / this.config.ASPECT_HEIGHT;\r\n    let cropX = 0;\r\n    let cropY = 0;\r\n    let cropW = img.naturalWidth;\r\n    let cropH = img.naturalHeight;\r\n\r\n    if (imageAspect > itemAspect) {\r\n      cropW = img.naturalHeight * itemAspect;\r\n      cropX = (img.naturalWidth - cropW) / 2;\r\n    } else {\r\n      cropH = img.naturalWidth / itemAspect;\r\n      cropY = (img.naturalHeight - cropH) / 2;\r\n    }\r\n\r\n    const samplingCanvas = document.createElement(\"canvas\");\r\n    const samplingCtx = samplingCanvas.getContext(\"2d\");\r\n    if (!samplingCtx) {\r\n      throw new Error(\"Unable to acquire 2d context for image sampling\");\r\n    }\r\n    samplingCanvas.width = this.config.ASCII_COLUMNS;\r\n    samplingCanvas.height = this.ASCII_ROWS;\r\n    samplingCtx.drawImage(\r\n      img,\r\n      cropX,\r\n      cropY,\r\n      cropW,\r\n      cropH,\r\n      0,\r\n      0,\r\n      this.config.ASCII_COLUMNS,\r\n      this.ASCII_ROWS,\r\n    );\r\n\r\n    const { data } = samplingCtx.getImageData(\r\n      0,\r\n      0,\r\n      this.config.ASCII_COLUMNS,\r\n      this.ASCII_ROWS,\r\n    );\r\n    const asciiGrid: string[][] = [];\r\n    const brightnessGrid: number[][] = [];\r\n\r\n    for (let row = 0; row < this.ASCII_ROWS; row++) {\r\n      const asciiRow: string[] = [];\r\n      const brightnessRow: number[] = [];\r\n      for (let col = 0; col < this.config.ASCII_COLUMNS; col++) {\r\n        const pixelIndex = (row * this.config.ASCII_COLUMNS + col) * 4;\r\n        const brightness =\r\n          (data[pixelIndex] * 0.299 +\r\n            data[pixelIndex + 1] * 0.587 +\r\n            data[pixelIndex + 2] * 0.114) /\r\n          255;\r\n        const charIndex = Math.min(\r\n          this.config.ASCII_CHARS.length - 1,\r\n          Math.floor((1 - brightness) * this.config.ASCII_CHARS.length),\r\n        );\r\n        asciiRow.push(this.config.ASCII_CHARS[charIndex]);\r\n        brightnessRow.push(charIndex);\r\n      }\r\n      asciiGrid.push(asciiRow);\r\n      brightnessGrid.push(brightnessRow);\r\n    }\r\n\r\n    return { asciiGrid, brightnessGrid };\r\n  }\r\n\r\n  animateCells(\r\n    asciiGrid: string[][],\r\n    brightnessGrid: number[][],\r\n  ): void {\r\n    const totalCells = this.config.ASCII_COLUMNS * this.ASCII_ROWS;\r\n    const scrambleState: (number | null)[] = new Array(totalCells).fill(null);\r\n    let settledCount = 0;\r\n\r\n    const cellOrder = this.shuffleArray(\r\n      Array.from({ length: totalCells }, (_, i) => i),\r\n    );\r\n\r\n    const failAnimation = (error: unknown): void => {\r\n      this.clearTimers();\r\n      this.handleError(\"image_animation_failed\", toError(error));\r\n    };\r\n\r\n    this.scrambleTicker = setInterval(() => {\r\n      if (this.failed || this.tracker.isDisposed) {\r\n        this.clearTimers();\r\n        return;\r\n      }\r\n      try {\r\n        let stillScrambling = false;\r\n        for (let cellIndex = 0; cellIndex < totalCells; cellIndex++) {\r\n          const remaining = scrambleState[cellIndex];\r\n          if (remaining === null || remaining <= 0) continue;\r\n          stillScrambling = true;\r\n          const row = Math.floor(cellIndex / this.config.ASCII_COLUMNS);\r\n          const col = cellIndex % this.config.ASCII_COLUMNS;\r\n\r\n          if (remaining === 1) {\r\n            this.drawCharacter(col, row, asciiGrid[row][col]);\r\n            scrambleState[cellIndex] = 0;\r\n            settledCount++;\r\n            this.emit(\"progress\", { progress: settledCount / totalCells });\r\n            if (settledCount === totalCells) this.revealImage();\r\n          } else {\r\n            this.drawCharacter(col, row, this.randomDenseCharacter());\r\n            scrambleState[cellIndex] = remaining - 1;\r\n          }\r\n        }\r\n        if (!stillScrambling && settledCount === totalCells) {\r\n          if (this.scrambleTicker !== null) {\r\n            clearInterval(this.scrambleTicker);\r\n            this.scrambleTicker = null;\r\n          }\r\n        }\r\n      } catch (error) {\r\n        failAnimation(error);\r\n      }\r\n    }, this.config.SCRAMBLE_SPEED_MS);\r\n\r\n    cellOrder.forEach((cellIndex, i) => {\r\n      this.trackTimeout(() => {\r\n        if (this.failed || this.tracker.isDisposed) return;\r\n        try {\r\n          const row = Math.floor(cellIndex / this.config.ASCII_COLUMNS);\r\n          const col = cellIndex % this.config.ASCII_COLUMNS;\r\n          const isDark = brightnessGrid[row][col] > this.denseCharIndex;\r\n\r\n          if (!isDark) {\r\n            this.drawCharacter(col, row, asciiGrid[row][col]);\r\n            scrambleState[cellIndex] = 0;\r\n            settledCount++;\r\n            this.emit(\"progress\", { progress: settledCount / totalCells });\r\n            if (settledCount === totalCells) this.revealImage();\r\n          } else {\r\n            scrambleState[cellIndex] = this.config.SCRAMBLE_COUNT;\r\n          }\r\n        } catch (error) {\r\n          failAnimation(error);\r\n        }\r\n      }, this.staggerDelay + i * this.config.CELL_APPEAR_MS);\r\n    });\r\n  }\r\n\r\n  drawCharacter(col: number, row: number, char: string): void {\r\n    if (!this.ctx) {\r\n      throw new Error(\"Canvas 2d context is not available\");\r\n    }\r\n    this.ctx.fillStyle = this.config.BACKGROUND_COLOR;\r\n    this.ctx.fillRect(\r\n      col * this.charWidth,\r\n      row * this.charHeight,\r\n      this.charWidth,\r\n      this.charHeight,\r\n    );\r\n    this.ctx.fillStyle = this.config.TEXT_COLOR;\r\n    this.ctx.fillText(char, col * this.charWidth, row * this.charHeight);\r\n  }\r\n\r\n  randomDenseCharacter(): string {\r\n    return this.denseChars[Math.floor(Math.random() * this.denseChars.length)];\r\n  }\r\n\r\n  private label(): string {\r\n    return this.img.alt || this.img.src;\r\n  }\r\n\r\n  private finishWithoutAnimation(): void {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n    this.emit(\"start\", { text: this.label() });\r\n    this.emit(\"progress\", { progress: 1 });\r\n    this.emit(\"complete\", { text: this.label() });\r\n  }\r\n\r\n  revealImage(): void {\r\n    if (this.failed || this.tracker.isDisposed || this.revealScheduled) return;\r\n    this.revealScheduled = true;\r\n    this.emit(\"progress\", { progress: 1 });\r\n    this.emit(\"complete\", { text: this.label() });\r\n    this.img.removeAttribute(\"aria-busy\");\r\n    this.trackTimeout(() => {\r\n      if (this.failed || this.tracker.isDisposed) return;\r\n      this.canvas.style.transition = \"opacity 0.5s ease\";\r\n      this.canvas.style.opacity = \"0\";\r\n      this.img.style.transition = \"opacity 0.5s ease\";\r\n      this.img.style.opacity = \"1\";\r\n      this.trackTimeout(() => {\r\n        this.canvas.remove();\r\n      }, 500);\r\n    }, this.config.REVEAL_DELAY_MS);\r\n  }\r\n\r\n  shuffleArray<T>(array: T[]): T[] {\r\n    for (let i = array.length - 1; i > 0; i--) {\r\n      const j = Math.floor(Math.random() * (i + 1));\r\n      [array[i], array[j]] = [array[j], array[i]];\r\n    }\r\n    return array;\r\n  }\r\n\r\n  static init(selector = \"[data-lascii-image]\"): LasciiImageEffect[] {\r\n    const images = document.querySelectorAll(selector);\r\n    return Array.from(\r\n      images,\r\n      (img, index) => new LasciiImageEffect(img as HTMLImageElement, index),\r\n    );\r\n  }\r\n}\r\n\r\nexport default LasciiImageEffect;\r\n"]}