{"version":3,"file":"morph-transition.mjs","sources":["../../../../src/lib/layouts/adaptive/morph-transition.ts"],"sourcesContent":["/**\n * @fileoverview FLIP-Based Morph Transition System\n *\n * Implements a high-performance animation system using the FLIP (First, Last,\n * Invert, Play) technique for smooth layout morphing between states. The system\n * uses only GPU-accelerated properties (transform, opacity) to achieve 60fps\n * animations.\n *\n * Key Features:\n * - FLIP animation technique\n * - GPU-accelerated transforms only\n * - Interruptible transitions\n * - Configurable easing and timing\n * - Staggered animations for multiple elements\n * - Spring physics easing\n *\n * @module layouts/adaptive/morph-transition\n * @version 1.0.0\n */\n\nimport type {\n  AnimationContext,\n  EasingFunction,\n  FLIPSnapshot,\n  LayoutRect,\n  MorphControllerInterface,\n  MorphTransitionConfig,\n  Transform3D,\n} from './types';\nimport { DEFAULT_MORPH_TRANSITION_CONFIG } from './types';\n\n// =============================================================================\n// CONSTANTS\n// =============================================================================\n\n/**\n * Default transform state.\n */\nconst IDENTITY_TRANSFORM: Transform3D = {\n  translateX: 0,\n  translateY: 0,\n  translateZ: 0,\n  scaleX: 1,\n  scaleY: 1,\n  scaleZ: 1,\n  rotateX: 0,\n  rotateY: 0,\n  rotateZ: 0,\n} as const;\n\n/**\n * Spring physics constants for spring easing.\n */\nconst SPRING_CONSTANTS = {\n  stiffness: 100,\n  damping: 10,\n  mass: 1,\n} as const;\n\n// =============================================================================\n// EASING FUNCTIONS\n// =============================================================================\n\n/**\n * Collection of easing functions.\n */\nconst EASING_FUNCTIONS: Record<string, (t: number) => number> = {\n  linear: (t) => t,\n  ease: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,\n  'ease-in': (t) => t * t * t,\n  'ease-out': (t) => (--t) * t * t + 1,\n  'ease-in-out': (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,\n  spring: createSpringEasing(SPRING_CONSTANTS.stiffness, SPRING_CONSTANTS.damping, SPRING_CONSTANTS.mass),\n  bounce: (t) => {\n    const n1 = 7.5625;\n    const d1 = 2.75;\n\n    if (t < 1 / d1) {\n      return n1 * t * t;\n    } else if (t < 2 / d1) {\n      return n1 * (t -= 1.5 / d1) * t + 0.75;\n    } else if (t < 2.5 / d1) {\n      return n1 * (t -= 2.25 / d1) * t + 0.9375;\n    } else {\n      return n1 * (t -= 2.625 / d1) * t + 0.984375;\n    }\n  },\n};\n\n/**\n * Creates a spring easing function.\n */\nfunction createSpringEasing(stiffness: number, damping: number, mass: number): (t: number) => number {\n  const w0 = Math.sqrt(stiffness / mass);\n  const zeta = damping / (2 * Math.sqrt(stiffness * mass));\n\n  if (zeta < 1) {\n    // Underdamped\n    const wd = w0 * Math.sqrt(1 - zeta * zeta);\n    return (t: number) => {\n      return 1 - Math.exp(-zeta * w0 * t) * (Math.cos(wd * t) + (zeta * w0 / wd) * Math.sin(wd * t));\n    };\n  } else {\n    // Critically damped or overdamped\n    return (t: number) => {\n      return 1 - (1 + w0 * t) * Math.exp(-w0 * t);\n    };\n  }\n}\n\n/**\n * Parses a cubic-bezier string and returns an easing function.\n */\nfunction parseCubicBezier(bezierStr: string): (t: number) => number {\n  const match = bezierStr.match(/cubic-bezier\\(([^)]+)\\)/);\n  if (match?.[1] == null) return EASING_FUNCTIONS.ease as (t: number) => number;\n\n  const [p1x, p1y, p2x, p2y] = match[1].split(',').map((s) => parseFloat(s.trim()));\n  if (p1x === undefined || p1y === undefined || p2x === undefined || p2y === undefined) {\n    return EASING_FUNCTIONS.ease as (t: number) => number;\n  }\n\n  // Approximate cubic bezier using de Casteljau's algorithm\n  return (t: number) => {\n    const cx = 3 * p1x;\n    const bx = 3 * (p2x - p1x) - cx;\n    const ax = 1 - cx - bx;\n\n    const cy = 3 * p1y;\n    const by = 3 * (p2y - p1y) - cy;\n    const ay = 1 - cy - by;\n\n    // Solve for t given x using Newton-Raphson\n    let x = t;\n    for (let i = 0; i < 8; i++) {\n      const currentX = ((ax * x + bx) * x + cx) * x;\n      const currentSlope = (3 * ax * x + 2 * bx) * x + cx;\n      if (Math.abs(currentSlope) < 1e-6) break;\n      x -= (currentX - t) / currentSlope;\n    }\n\n    return ((ay * x + by) * x + cy) * x;\n  };\n}\n\n/**\n * Gets an easing function by name or cubic-bezier string.\n */\nfunction getEasingFunction(easing: EasingFunction): (t: number) => number {\n  if (easing.startsWith('cubic-bezier')) {\n    return parseCubicBezier(easing);\n  }\n  return (EASING_FUNCTIONS[easing] ?? EASING_FUNCTIONS.ease) as (t: number) => number;\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Generates a unique batch ID.\n */\nfunction generateBatchId(): string {\n  return `morph_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Gets the current layout rect of an element.\n */\nfunction getLayoutRect(element: HTMLElement): LayoutRect {\n  const rect = element.getBoundingClientRect();\n  const style = getComputedStyle(element);\n\n  // Parse current transform\n  const {transform} = style;\n  let scaleX = 1;\n  let scaleY = 1;\n  let rotation = 0;\n\n  if (transform && transform !== 'none') {\n    const matrix = new DOMMatrix(transform);\n    scaleX = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b);\n    scaleY = Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d);\n    rotation = Math.atan2(matrix.b, matrix.a) * (180 / Math.PI);\n  }\n\n  return {\n    x: rect.x,\n    y: rect.y,\n    width: rect.width,\n    height: rect.height,\n    scaleX,\n    scaleY,\n    rotation,\n    opacity: parseFloat(style.opacity) || 1,\n  };\n}\n\n/**\n * Calculates the invert transform from first to last position.\n */\nfunction calculateInvert(first: LayoutRect, last: LayoutRect): Transform3D {\n  return {\n    translateX: first.x - last.x,\n    translateY: first.y - last.y,\n    translateZ: 0,\n    scaleX: first.width / (last.width || 1),\n    scaleY: first.height / (last.height || 1),\n    scaleZ: 1,\n    rotateX: 0,\n    rotateY: 0,\n    rotateZ: first.rotation - last.rotation,\n  };\n}\n\n/**\n * Applies a transform to an element.\n */\nfunction applyTransform(element: HTMLElement, transform: Transform3D, opacity: number): void {\n  const { translateX, translateY, scaleX, scaleY, rotateZ } = transform;\n\n  // Use transform3d to force GPU acceleration\n  element.style.transform = `\n    translate3d(${translateX}px, ${translateY}px, 0)\n    scale(${scaleX}, ${scaleY})\n    rotate(${rotateZ}deg)\n  `.replace(/\\s+/g, ' ').trim();\n\n  element.style.opacity = String(opacity);\n}\n\n/**\n * Interpolates between two values.\n */\nfunction lerp(start: number, end: number, t: number): number {\n  return start + (end - start) * t;\n}\n\n/**\n * Interpolates between two transforms.\n */\nfunction lerpTransform(from: Transform3D, to: Transform3D, t: number): Transform3D {\n  return {\n    translateX: lerp(from.translateX, to.translateX, t),\n    translateY: lerp(from.translateY, to.translateY, t),\n    translateZ: lerp(from.translateZ, to.translateZ, t),\n    scaleX: lerp(from.scaleX, to.scaleX, t),\n    scaleY: lerp(from.scaleY, to.scaleY, t),\n    scaleZ: lerp(from.scaleZ, to.scaleZ, t),\n    rotateX: lerp(from.rotateX, to.rotateX, t),\n    rotateY: lerp(from.rotateY, to.rotateY, t),\n    rotateZ: lerp(from.rotateZ, to.rotateZ, t),\n  };\n}\n\n// =============================================================================\n// MORPH CONTROLLER IMPLEMENTATION\n// =============================================================================\n\n/**\n * Controls FLIP-based morph transitions between layout states.\n *\n * @example\n * ```typescript\n * const controller = createMorphController();\n *\n * // Capture first state\n * const first = controller.snapshotFirst(elements);\n *\n * // Apply layout changes...\n *\n * // Capture last state\n * const last = controller.snapshotLast(elements);\n *\n * // Create and play animation\n * const context = controller.createAnimation(first, last, elements);\n * await controller.play(context);\n * ```\n */\nexport class MorphController implements MorphControllerInterface {\n  private _activeContext: AnimationContext | null = null;\n  private _animationFrameId: number | null = null;\n  private _destroyed: boolean = false;\n\n  constructor(config: Partial<MorphTransitionConfig> = {}) {\n    this._config = { ...DEFAULT_MORPH_TRANSITION_CONFIG, ...config };\n  }\n\n  private _config: MorphTransitionConfig;\n\n  /**\n   * Current configuration.\n   */\n  get config(): MorphTransitionConfig {\n    return this._config;\n  }\n\n  /**\n   * Whether a transition is currently running.\n   */\n  get isTransitioning(): boolean {\n    return this._activeContext?.isRunning ?? false;\n  }\n\n  /**\n   * Updates the controller configuration.\n   */\n  configure(config: Partial<MorphTransitionConfig>): void {\n    this._assertNotDestroyed();\n    this._config = { ...this._config, ...config };\n  }\n\n  /**\n   * Captures the \"First\" state of elements (before layout change).\n   *\n   * @param elements - Map of element IDs to elements\n   * @returns Map of element IDs to their layout rects\n   */\n  snapshotFirst(elements: Map<string, HTMLElement>): Map<string, LayoutRect> {\n    this._assertNotDestroyed();\n    const rects = new Map<string, LayoutRect>();\n\n    for (const [id, element] of elements) {\n      rects.set(id, getLayoutRect(element));\n    }\n\n    return rects;\n  }\n\n  /**\n   * Captures the \"Last\" state of elements (after layout change).\n   *\n   * @param elements - Map of element IDs to elements\n   * @returns Map of element IDs to their layout rects\n   */\n  snapshotLast(elements: Map<string, HTMLElement>): Map<string, LayoutRect> {\n    this._assertNotDestroyed();\n    return this.snapshotFirst(elements);\n  }\n\n  /**\n   * Creates an animation context from first and last states.\n   *\n   * @param first - First (before) layout rects\n   * @param last - Last (after) layout rects\n   * @param elements - Map of element IDs to elements\n   * @returns Animation context\n   */\n  createAnimation(\n    first: Map<string, LayoutRect>,\n    last: Map<string, LayoutRect>,\n    elements: Map<string, HTMLElement>\n  ): AnimationContext {\n    this._assertNotDestroyed();\n\n    const snapshots = new Map<string, FLIPSnapshot>();\n\n    for (const [id, firstRect] of first) {\n      const lastRect = last.get(id);\n      if (!lastRect) continue;\n\n      const invert = calculateInvert(firstRect, lastRect);\n\n      snapshots.set(id, {\n        id,\n        first: firstRect,\n        last: lastRect,\n        invert,\n        playState: 'pending',\n      });\n    }\n\n    // Apply inverted transforms immediately\n    for (const [id, snapshot] of snapshots) {\n      const element = elements.get(id);\n      if (element) {\n        applyTransform(element, snapshot.invert, snapshot.first.opacity);\n      }\n    }\n\n    // Force layout to ensure transforms are applied\n    if (elements.size > 0) {\n      const firstElement = elements.values().next().value;\n      if (firstElement != null) {\n        void firstElement.offsetHeight;\n      }\n    }\n\n\n\n\n    return {\n      batchId: generateBatchId(),\n      snapshots,\n      progress: 0,\n      isRunning: false,\n      startTime: null,\n      cancel: () => this.cancel(),\n    };\n  }\n\n  /**\n   * Plays an animation context.\n   *\n   * @param context - The animation context to play\n   * @returns Promise that resolves when animation completes\n   */\n  async play(context: AnimationContext): Promise<void> {\n    this._assertNotDestroyed();\n\n    // Cancel any existing animation\n    if (this._activeContext?.isRunning === true) {\n      if (this._config.interruptible) {\n        this.cancel();\n      } else {\n        // Wait for current animation to complete\n        return new Promise((resolve) => {\n          const checkComplete = (): void => {\n            if (this._activeContext?.isRunning !== true) {\n              void this.play(context).then(resolve);\n            } else {\n              requestAnimationFrame(checkComplete);\n            }\n          };\n          requestAnimationFrame(checkComplete);\n        });\n      }\n    }\n\n    this._activeContext = {\n      ...context,\n      isRunning: true,\n      startTime: null,\n    };\n\n    this._config.onStart?.();\n\n    return new Promise((resolve) => {\n      const elements = this._collectElements(context.snapshots);\n      const easingFn = getEasingFunction(this._config.easing);\n\n      const animate = (timestamp: number): void => {\n        if (this._activeContext?.isRunning !== true) {\n          resolve();\n          return;\n        }\n\n        if (this._activeContext.startTime === null) {\n          this._activeContext = {\n            ...this._activeContext,\n            startTime: timestamp + this._config.delay,\n          };\n        }\n\n        const elapsed = timestamp - (this._activeContext.startTime ?? timestamp);\n\n        if (elapsed < 0) {\n          // Still in delay phase\n          this._animationFrameId = requestAnimationFrame(animate);\n          return;\n        }\n\n        const rawProgress = Math.min(elapsed / this._config.duration, 1);\n        const easedProgress = easingFn(rawProgress);\n\n        this._activeContext = {\n          ...this._activeContext,\n          progress: easedProgress,\n        };\n\n        this._config.onFrame?.(easedProgress);\n\n        // Animate each element with stagger\n        let index = 0;\n        for (const [id, snapshot] of context.snapshots) {\n          const element = elements.get(id);\n          if (!element) continue;\n\n          // Calculate staggered progress\n          const staggerDelay = Math.min(\n            index * this._config.staggerDelay,\n            this._config.maxStaggerDelay\n          );\n          const staggerProgress = Math.max(\n            0,\n            Math.min(1, (elapsed - staggerDelay) / this._config.duration)\n          );\n          const staggeredEasedProgress = easingFn(staggerProgress);\n\n          // Interpolate from inverted state to identity (no transform)\n          const currentTransform = lerpTransform(\n            snapshot.invert,\n            IDENTITY_TRANSFORM,\n            staggeredEasedProgress\n          );\n\n          const currentOpacity = lerp(snapshot.first.opacity, snapshot.last.opacity, staggeredEasedProgress);\n\n          applyTransform(element, currentTransform, currentOpacity);\n\n          index++;\n        }\n\n        if (rawProgress < 1) {\n          this._animationFrameId = requestAnimationFrame(animate);\n        } else {\n          // Animation complete\n          this._cleanupAnimation(elements);\n          this._activeContext = {\n            ...this._activeContext,\n            isRunning: false,\n            progress: 1,\n          };\n          this._config.onComplete?.();\n          resolve();\n        }\n      };\n\n      this._animationFrameId = requestAnimationFrame(animate);\n    });\n  }\n\n  /**\n   * Cancels the current animation.\n   */\n  cancel(): void {\n    if (this._animationFrameId !== null) {\n      cancelAnimationFrame(this._animationFrameId);\n      this._animationFrameId = null;\n    }\n\n    if (this._activeContext?.isRunning === true) {\n      const elements = this._collectElements(this._activeContext.snapshots);\n      this._cleanupAnimation(elements);\n\n      this._activeContext = {\n        ...this._activeContext,\n        isRunning: false,\n      };\n\n      for (const [_id, snapshot] of this._activeContext.snapshots) {\n        (snapshot as { playState: string }).playState = 'interrupted';\n      }\n\n      this._config.onInterrupt?.();\n    }\n  }\n\n  /**\n   * Cleans up all resources.\n   */\n  destroy(): void {\n    if (this._destroyed) return;\n\n    this.cancel();\n    this._destroyed = true;\n  }\n\n  // ===========================================================================\n  // PRIVATE METHODS\n  // ===========================================================================\n\n  /**\n   * Collects elements from the DOM based on snapshot IDs.\n   */\n  private _collectElements(snapshots: ReadonlyMap<string, FLIPSnapshot>): Map<string, HTMLElement> {\n    const elements = new Map<string, HTMLElement>();\n\n    for (const [id] of snapshots) {\n      const element = document.querySelector(`[data-layout-id=\"${id}\"]`);\n      if (element instanceof HTMLElement) {\n        elements.set(id, element);\n      }\n    }\n\n    return elements;\n  }\n\n  /**\n   * Cleans up element styles after animation.\n   */\n  private _cleanupAnimation(elements: Map<string, HTMLElement>): void {\n    for (const element of elements.values()) {\n      element.style.transform = '';\n      element.style.opacity = '';\n    }\n  }\n\n  /**\n   * Asserts that the controller has not been destroyed.\n   */\n  private _assertNotDestroyed(): void {\n    if (this._destroyed) {\n      throw new Error('MorphController has been destroyed and cannot be used.');\n    }\n  }\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Creates a new MorphController instance.\n *\n * @param config - Optional configuration overrides\n * @returns A new MorphController instance\n */\nexport function createMorphController(config: Partial<MorphTransitionConfig> = {}): MorphControllerInterface {\n  return new MorphController(config);\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n/**\n * Creates a FLIP animation helper for a single element.\n *\n * @param element - Element to animate\n * @param config - Animation configuration\n * @returns FLIP animation controller\n */\nexport function createElementFLIP(\n  element: HTMLElement,\n  config: Partial<MorphTransitionConfig> = {}\n): {\n  first: () => LayoutRect;\n  last: () => LayoutRect;\n  invert: (first: LayoutRect, last: LayoutRect) => void;\n  play: () => Promise<void>;\n} {\n  const controller = new MorphController(config);\n  let firstRect: LayoutRect | null = null;\n  let lastRect: LayoutRect | null = null;\n\n  const id = element.getAttribute('data-layout-id') ??\n    `flip_${Math.random().toString(36).substring(2, 9)}`;\n\n  if (!element.hasAttribute('data-layout-id')) {\n    element.setAttribute('data-layout-id', id);\n  }\n\n  return {\n    first: () => {\n      firstRect = getLayoutRect(element);\n      return firstRect;\n    },\n    last: () => {\n      lastRect = getLayoutRect(element);\n      return lastRect;\n    },\n    invert: (first: LayoutRect, last: LayoutRect) => {\n      const invert = calculateInvert(first, last);\n      applyTransform(element, invert, first.opacity);\n    },\n    play: async () => {\n      if (!firstRect || !lastRect) {\n        throw new Error('Must call first() and last() before play()');\n      }\n\n      const elements = new Map([[id, element]]);\n      const first = new Map([[id, firstRect]]);\n      const last = new Map([[id, lastRect]]);\n\n      const context = controller.createAnimation(first, last, elements);\n      await controller.play(context);\n\n      firstRect = null;\n      lastRect = null;\n    },\n  };\n}\n\n/**\n * Performs a quick FLIP animation for layout changes.\n *\n * @param elements - Elements to animate\n * @param layoutChange - Function that performs the layout change\n * @param config - Animation configuration\n */\nexport async function performFLIP(\n  elements: HTMLElement[],\n  layoutChange: () => void | Promise<void>,\n  config: Partial<MorphTransitionConfig> = {}\n): Promise<void> {\n  const controller = new MorphController(config);\n  const elementMap = new Map<string, HTMLElement>();\n\n  // Ensure all elements have layout IDs\n  for (const element of elements) {\n    const existingId = element.getAttribute('data-layout-id');\n    const id = existingId != null && existingId !== '' ? existingId : `flip_${Math.random().toString(36).substring(2, 9)}`;\n    if (existingId == null || existingId === '') {\n      element.setAttribute('data-layout-id', id);\n    }\n    elementMap.set(id, element);\n  }\n\n  // Capture first state\n  const first = controller.snapshotFirst(elementMap);\n\n  // Perform layout change\n  await layoutChange();\n\n  // Capture last state\n  const last = controller.snapshotLast(elementMap);\n\n  // Create and play animation\n  const context = controller.createAnimation(first, last, elementMap);\n  await controller.play(context);\n\n  controller.destroy();\n}\n"],"names":["IDENTITY_TRANSFORM","SPRING_CONSTANTS","EASING_FUNCTIONS","createSpringEasing","stiffness","damping","mass","w0","zeta","wd","t","parseCubicBezier","bezierStr","match","p1x","p1y","p2x","p2y","s","cx","bx","ax","cy","by","ay","x","i","currentX","currentSlope","getEasingFunction","easing","generateBatchId","getLayoutRect","element","rect","style","transform","scaleX","scaleY","rotation","matrix","calculateInvert","first","last","applyTransform","opacity","translateX","translateY","rotateZ","lerp","start","end","lerpTransform","from","to","MorphController","config","DEFAULT_MORPH_TRANSITION_CONFIG","elements","rects","id","snapshots","firstRect","lastRect","invert","snapshot","firstElement","context","resolve","checkComplete","easingFn","animate","timestamp","elapsed","rawProgress","easedProgress","index","staggerDelay","staggerProgress","staggeredEasedProgress","currentTransform","currentOpacity","_id","createMorphController","createElementFLIP","controller","performFLIP","layoutChange","elementMap","existingId"],"mappings":";AAsCA,MAAMA,IAAkC;AAAA,EACtC,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX,GAKMC,IAAmB;AAAA,EACvB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,MAAM;AACR,GASMC,IAA0D;AAAA,EAC9D,QAAQ,CAAC,MAAM;AAAA,EACf,MAAM,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EACtD,WAAW,CAAC,MAAM,IAAI,IAAI;AAAA,EAC1B,YAAY,CAAC,MAAO,EAAE,IAAK,IAAI,IAAI;AAAA,EACnC,eAAe,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EACtF,QAAQC,EAAmBF,EAAiB,WAAWA,EAAiB,SAASA,EAAiB,IAAI;AAAA,EACtG,QAAQ,CAAC,MAIH,IAAI,IAAI,OACH,SAAK,IAAI,IACP,IAAI,IAAI,OACV,UAAM,KAAK,MAAM,QAAM,IAAI,OACzB,IAAI,MAAM,OACZ,UAAM,KAAK,OAAO,QAAM,IAAI,SAE5B,UAAM,KAAK,QAAQ,QAAM,IAAI;AAG1C;AAKA,SAASE,EAAmBC,GAAmBC,GAAiBC,GAAqC;AACnG,QAAMC,IAAK,KAAK,KAAKH,IAAYE,CAAI,GAC/BE,IAAOH,KAAW,IAAI,KAAK,KAAKD,IAAYE,CAAI;AAEtD,MAAIE,IAAO,GAAG;AAEZ,UAAMC,IAAKF,IAAK,KAAK,KAAK,IAAIC,IAAOA,CAAI;AACzC,WAAO,CAACE,MACC,IAAI,KAAK,IAAI,CAACF,IAAOD,IAAKG,CAAC,KAAK,KAAK,IAAID,IAAKC,CAAC,IAAKF,IAAOD,IAAKE,IAAM,KAAK,IAAIA,IAAKC,CAAC;AAAA,EAEhG;AAEE,WAAO,CAACA,MACC,KAAK,IAAIH,IAAKG,KAAK,KAAK,IAAI,CAACH,IAAKG,CAAC;AAGhD;AAKA,SAASC,EAAiBC,GAA0C;AAClE,QAAMC,IAAQD,EAAU,MAAM,yBAAyB;AACvD,MAAIC,IAAQ,CAAC,KAAK,aAAaX,EAAiB;AAEhD,QAAM,CAACY,GAAKC,GAAKC,GAAKC,CAAG,IAAIJ,EAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAACK,MAAM,WAAWA,EAAE,KAAA,CAAM,CAAC;AAChF,SAAIJ,MAAQ,UAAaC,MAAQ,UAAaC,MAAQ,UAAaC,MAAQ,SAClEf,EAAiB,OAInB,CAACQ,MAAc;AACpB,UAAMS,IAAK,IAAIL,GACTM,IAAK,KAAKJ,IAAMF,KAAOK,GACvBE,IAAK,IAAIF,IAAKC,GAEdE,IAAK,IAAIP,GACTQ,IAAK,KAAKN,IAAMF,KAAOO,GACvBE,IAAK,IAAIF,IAAKC;AAGpB,QAAIE,IAAIf;AACR,aAASgB,IAAI,GAAGA,IAAI,GAAGA,KAAK;AAC1B,YAAMC,MAAaN,IAAKI,IAAIL,KAAMK,IAAIN,KAAMM,GACtCG,KAAgB,IAAIP,IAAKI,IAAI,IAAIL,KAAMK,IAAIN;AACjD,UAAI,KAAK,IAAIS,CAAY,IAAI,KAAM;AACnC,MAAAH,MAAME,IAAWjB,KAAKkB;AAAA,IACxB;AAEA,aAASJ,IAAKC,IAAIF,KAAME,IAAIH,KAAMG;AAAA,EACpC;AACF;AAKA,SAASI,EAAkBC,GAA+C;AACxE,SAAIA,EAAO,WAAW,cAAc,IAC3BnB,EAAiBmB,CAAM,IAExB5B,EAAiB4B,CAAM,KAAK5B,EAAiB;AACvD;AASA,SAAS6B,IAA0B;AACjC,SAAO,SAAS,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC;AAC1E;AAKA,SAASC,EAAcC,GAAkC;AACvD,QAAMC,IAAOD,EAAQ,sBAAA,GACfE,IAAQ,iBAAiBF,CAAO,GAGhC,EAAC,WAAAG,MAAaD;AACpB,MAAIE,IAAS,GACTC,IAAS,GACTC,IAAW;AAEf,MAAIH,KAAaA,MAAc,QAAQ;AACrC,UAAMI,IAAS,IAAI,UAAUJ,CAAS;AACtC,IAAAC,IAAS,KAAK,KAAKG,EAAO,IAAIA,EAAO,IAAIA,EAAO,IAAIA,EAAO,CAAC,GAC5DF,IAAS,KAAK,KAAKE,EAAO,IAAIA,EAAO,IAAIA,EAAO,IAAIA,EAAO,CAAC,GAC5DD,IAAW,KAAK,MAAMC,EAAO,GAAGA,EAAO,CAAC,KAAK,MAAM,KAAK;AAAA,EAC1D;AAEA,SAAO;AAAA,IACL,GAAGN,EAAK;AAAA,IACR,GAAGA,EAAK;AAAA,IACR,OAAOA,EAAK;AAAA,IACZ,QAAQA,EAAK;AAAA,IACb,QAAAG;AAAA,IACA,QAAAC;AAAA,IACA,UAAAC;AAAA,IACA,SAAS,WAAWJ,EAAM,OAAO,KAAK;AAAA,EAAA;AAE1C;AAKA,SAASM,EAAgBC,GAAmBC,GAA+B;AACzE,SAAO;AAAA,IACL,YAAYD,EAAM,IAAIC,EAAK;AAAA,IAC3B,YAAYD,EAAM,IAAIC,EAAK;AAAA,IAC3B,YAAY;AAAA,IACZ,QAAQD,EAAM,SAASC,EAAK,SAAS;AAAA,IACrC,QAAQD,EAAM,UAAUC,EAAK,UAAU;AAAA,IACvC,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAASD,EAAM,WAAWC,EAAK;AAAA,EAAA;AAEnC;AAKA,SAASC,EAAeX,GAAsBG,GAAwBS,GAAuB;AAC3F,QAAM,EAAE,YAAAC,GAAY,YAAAC,GAAY,QAAAV,GAAQ,QAAAC,GAAQ,SAAAU,MAAYZ;AAG5D,EAAAH,EAAQ,MAAM,YAAY;AAAA,kBACVa,CAAU,OAAOC,CAAU;AAAA,YACjCV,CAAM,KAAKC,CAAM;AAAA,aAChBU,CAAO;AAAA,IAChB,QAAQ,QAAQ,GAAG,EAAE,KAAA,GAEvBf,EAAQ,MAAM,UAAU,OAAOY,CAAO;AACxC;AAKA,SAASI,EAAKC,GAAeC,GAAazC,GAAmB;AAC3D,SAAOwC,KAASC,IAAMD,KAASxC;AACjC;AAKA,SAAS0C,EAAcC,GAAmBC,GAAiB5C,GAAwB;AACjF,SAAO;AAAA,IACL,YAAYuC,EAAKI,EAAK,YAAYC,EAAG,YAAY5C,CAAC;AAAA,IAClD,YAAYuC,EAAKI,EAAK,YAAYC,EAAG,YAAY5C,CAAC;AAAA,IAClD,YAAYuC,EAAKI,EAAK,YAAYC,EAAG,YAAY5C,CAAC;AAAA,IAClD,QAAQuC,EAAKI,EAAK,QAAQC,EAAG,QAAQ5C,CAAC;AAAA,IACtC,QAAQuC,EAAKI,EAAK,QAAQC,EAAG,QAAQ5C,CAAC;AAAA,IACtC,QAAQuC,EAAKI,EAAK,QAAQC,EAAG,QAAQ5C,CAAC;AAAA,IACtC,SAASuC,EAAKI,EAAK,SAASC,EAAG,SAAS5C,CAAC;AAAA,IACzC,SAASuC,EAAKI,EAAK,SAASC,EAAG,SAAS5C,CAAC;AAAA,IACzC,SAASuC,EAAKI,EAAK,SAASC,EAAG,SAAS5C,CAAC;AAAA,EAAA;AAE7C;AA0BO,MAAM6C,EAAoD;AAAA,EACvD,iBAA0C;AAAA,EAC1C,oBAAmC;AAAA,EACnC,aAAsB;AAAA,EAE9B,YAAYC,IAAyC,IAAI;AACvD,SAAK,UAAU,EAAE,GAAGC,GAAiC,GAAGD,EAAA;AAAA,EAC1D;AAAA,EAEQ;AAAA;AAAA;AAAA;AAAA,EAKR,IAAI,SAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,kBAA2B;AAC7B,WAAO,KAAK,gBAAgB,aAAa;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAUA,GAA8C;AACtD,SAAK,oBAAA,GACL,KAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAGA,EAAA;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAcE,GAA6D;AACzE,SAAK,oBAAA;AACL,UAAMC,wBAAY,IAAA;AAElB,eAAW,CAACC,GAAI3B,CAAO,KAAKyB;AAC1B,MAAAC,EAAM,IAAIC,GAAI5B,EAAcC,CAAO,CAAC;AAGtC,WAAO0B;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAaD,GAA6D;AACxE,gBAAK,oBAAA,GACE,KAAK,cAAcA,CAAQ;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,gBACEhB,GACAC,GACAe,GACkB;AAClB,SAAK,oBAAA;AAEL,UAAMG,wBAAgB,IAAA;AAEtB,eAAW,CAACD,GAAIE,CAAS,KAAKpB,GAAO;AACnC,YAAMqB,IAAWpB,EAAK,IAAIiB,CAAE;AAC5B,UAAI,CAACG,EAAU;AAEf,YAAMC,IAASvB,EAAgBqB,GAAWC,CAAQ;AAElD,MAAAF,EAAU,IAAID,GAAI;AAAA,QAChB,IAAAA;AAAA,QACA,OAAOE;AAAA,QACP,MAAMC;AAAA,QACN,QAAAC;AAAA,QACA,WAAW;AAAA,MAAA,CACZ;AAAA,IACH;AAGA,eAAW,CAACJ,GAAIK,CAAQ,KAAKJ,GAAW;AACtC,YAAM5B,IAAUyB,EAAS,IAAIE,CAAE;AAC/B,MAAI3B,KACFW,EAAeX,GAASgC,EAAS,QAAQA,EAAS,MAAM,OAAO;AAAA,IAEnE;AAGA,QAAIP,EAAS,OAAO,GAAG;AACrB,YAAMQ,IAAeR,EAAS,OAAA,EAAS,OAAO;AAC9C,MACOQ,GAAa;AAAA,IAEtB;AAKA,WAAO;AAAA,MACL,SAASnC,EAAA;AAAA,MACT,WAAA8B;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ,MAAM,KAAK,OAAA;AAAA,IAAO;AAAA,EAE9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAKM,GAA0C;AAInD,QAHA,KAAK,oBAAA,GAGD,KAAK,gBAAgB,cAAc;AACrC,UAAI,KAAK,QAAQ;AACf,aAAK,OAAA;AAAA;AAGL,eAAO,IAAI,QAAQ,CAACC,MAAY;AAC9B,gBAAMC,IAAgB,MAAY;AAChC,YAAI,KAAK,gBAAgB,cAAc,KAChC,KAAK,KAAKF,CAAO,EAAE,KAAKC,CAAO,IAEpC,sBAAsBC,CAAa;AAAA,UAEvC;AACA,gCAAsBA,CAAa;AAAA,QACrC,CAAC;AAIL,gBAAK,iBAAiB;AAAA,MACpB,GAAGF;AAAA,MACH,WAAW;AAAA,MACX,WAAW;AAAA,IAAA,GAGb,KAAK,QAAQ,UAAA,GAEN,IAAI,QAAQ,CAACC,MAAY;AAC9B,YAAMV,IAAW,KAAK,iBAAiBS,EAAQ,SAAS,GAClDG,IAAWzC,EAAkB,KAAK,QAAQ,MAAM,GAEhD0C,IAAU,CAACC,MAA4B;AAC3C,YAAI,KAAK,gBAAgB,cAAc,IAAM;AAC3C,UAAAJ,EAAA;AACA;AAAA,QACF;AAEA,QAAI,KAAK,eAAe,cAAc,SACpC,KAAK,iBAAiB;AAAA,UACpB,GAAG,KAAK;AAAA,UACR,WAAWI,IAAY,KAAK,QAAQ;AAAA,QAAA;AAIxC,cAAMC,IAAUD,KAAa,KAAK,eAAe,aAAaA;AAE9D,YAAIC,IAAU,GAAG;AAEf,eAAK,oBAAoB,sBAAsBF,CAAO;AACtD;AAAA,QACF;AAEA,cAAMG,IAAc,KAAK,IAAID,IAAU,KAAK,QAAQ,UAAU,CAAC,GACzDE,IAAgBL,EAASI,CAAW;AAE1C,aAAK,iBAAiB;AAAA,UACpB,GAAG,KAAK;AAAA,UACR,UAAUC;AAAA,QAAA,GAGZ,KAAK,QAAQ,UAAUA,CAAa;AAGpC,YAAIC,IAAQ;AACZ,mBAAW,CAAChB,GAAIK,CAAQ,KAAKE,EAAQ,WAAW;AAC9C,gBAAMlC,IAAUyB,EAAS,IAAIE,CAAE;AAC/B,cAAI,CAAC3B,EAAS;AAGd,gBAAM4C,IAAe,KAAK;AAAA,YACxBD,IAAQ,KAAK,QAAQ;AAAA,YACrB,KAAK,QAAQ;AAAA,UAAA,GAETE,IAAkB,KAAK;AAAA,YAC3B;AAAA,YACA,KAAK,IAAI,IAAIL,IAAUI,KAAgB,KAAK,QAAQ,QAAQ;AAAA,UAAA,GAExDE,IAAyBT,EAASQ,CAAe,GAGjDE,IAAmB5B;AAAA,YACvBa,EAAS;AAAA,YACTjE;AAAA,YACA+E;AAAA,UAAA,GAGIE,IAAiBhC,EAAKgB,EAAS,MAAM,SAASA,EAAS,KAAK,SAASc,CAAsB;AAEjG,UAAAnC,EAAeX,GAAS+C,GAAkBC,CAAc,GAExDL;AAAA,QACF;AAEA,QAAIF,IAAc,IAChB,KAAK,oBAAoB,sBAAsBH,CAAO,KAGtD,KAAK,kBAAkBb,CAAQ,GAC/B,KAAK,iBAAiB;AAAA,UACpB,GAAG,KAAK;AAAA,UACR,WAAW;AAAA,UACX,UAAU;AAAA,QAAA,GAEZ,KAAK,QAAQ,aAAA,GACbU,EAAA;AAAA,MAEJ;AAEA,WAAK,oBAAoB,sBAAsBG,CAAO;AAAA,IACxD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,SAAe;AAMb,QALI,KAAK,sBAAsB,SAC7B,qBAAqB,KAAK,iBAAiB,GAC3C,KAAK,oBAAoB,OAGvB,KAAK,gBAAgB,cAAc,IAAM;AAC3C,YAAMb,IAAW,KAAK,iBAAiB,KAAK,eAAe,SAAS;AACpE,WAAK,kBAAkBA,CAAQ,GAE/B,KAAK,iBAAiB;AAAA,QACpB,GAAG,KAAK;AAAA,QACR,WAAW;AAAA,MAAA;AAGb,iBAAW,CAACwB,GAAKjB,CAAQ,KAAK,KAAK,eAAe;AAC/C,QAAAA,EAAmC,YAAY;AAGlD,WAAK,QAAQ,cAAA;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,IAAI,KAAK,eAET,KAAK,OAAA,GACL,KAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,iBAAiBJ,GAAwE;AAC/F,UAAMH,wBAAe,IAAA;AAErB,eAAW,CAACE,CAAE,KAAKC,GAAW;AAC5B,YAAM5B,IAAU,SAAS,cAAc,oBAAoB2B,CAAE,IAAI;AACjE,MAAI3B,aAAmB,eACrByB,EAAS,IAAIE,GAAI3B,CAAO;AAAA,IAE5B;AAEA,WAAOyB;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkBA,GAA0C;AAClE,eAAWzB,KAAWyB,EAAS;AAC7B,MAAAzB,EAAQ,MAAM,YAAY,IAC1BA,EAAQ,MAAM,UAAU;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAA4B;AAClC,QAAI,KAAK;AACP,YAAM,IAAI,MAAM,wDAAwD;AAAA,EAE5E;AACF;AAYO,SAASkD,EAAsB3B,IAAyC,IAA8B;AAC3G,SAAO,IAAID,EAAgBC,CAAM;AACnC;AAaO,SAAS4B,EACdnD,GACAuB,IAAyC,IAMzC;AACA,QAAM6B,IAAa,IAAI9B,EAAgBC,CAAM;AAC7C,MAAIM,IAA+B,MAC/BC,IAA8B;AAElC,QAAMH,IAAK3B,EAAQ,aAAa,gBAAgB,KAC9C,QAAQ,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC;AAEpD,SAAKA,EAAQ,aAAa,gBAAgB,KACxCA,EAAQ,aAAa,kBAAkB2B,CAAE,GAGpC;AAAA,IACL,OAAO,OACLE,IAAY9B,EAAcC,CAAO,GAC1B6B;AAAA,IAET,MAAM,OACJC,IAAW/B,EAAcC,CAAO,GACzB8B;AAAA,IAET,QAAQ,CAACrB,GAAmBC,MAAqB;AAC/C,YAAMqB,IAASvB,EAAgBC,GAAOC,CAAI;AAC1C,MAAAC,EAAeX,GAAS+B,GAAQtB,EAAM,OAAO;AAAA,IAC/C;AAAA,IACA,MAAM,YAAY;AAChB,UAAI,CAACoB,KAAa,CAACC;AACjB,cAAM,IAAI,MAAM,4CAA4C;AAG9D,YAAML,wBAAe,IAAI,CAAC,CAACE,GAAI3B,CAAO,CAAC,CAAC,GAClCS,wBAAY,IAAI,CAAC,CAACkB,GAAIE,CAAS,CAAC,CAAC,GACjCnB,wBAAW,IAAI,CAAC,CAACiB,GAAIG,CAAQ,CAAC,CAAC,GAE/BI,IAAUkB,EAAW,gBAAgB3C,GAAOC,GAAMe,CAAQ;AAChE,YAAM2B,EAAW,KAAKlB,CAAO,GAE7BL,IAAY,MACZC,IAAW;AAAA,IACb;AAAA,EAAA;AAEJ;AASA,eAAsBuB,EACpB5B,GACA6B,GACA/B,IAAyC,CAAA,GAC1B;AACf,QAAM6B,IAAa,IAAI9B,EAAgBC,CAAM,GACvCgC,wBAAiB,IAAA;AAGvB,aAAWvD,KAAWyB,GAAU;AAC9B,UAAM+B,IAAaxD,EAAQ,aAAa,gBAAgB,GAClD2B,IAAK6B,KAAc,QAAQA,MAAe,KAAKA,IAAa,QAAQ,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC;AACpH,KAAIA,KAAc,QAAQA,MAAe,OACvCxD,EAAQ,aAAa,kBAAkB2B,CAAE,GAE3C4B,EAAW,IAAI5B,GAAI3B,CAAO;AAAA,EAC5B;AAGA,QAAMS,IAAQ2C,EAAW,cAAcG,CAAU;AAGjD,QAAMD,EAAA;AAGN,QAAM5C,IAAO0C,EAAW,aAAaG,CAAU,GAGzCrB,IAAUkB,EAAW,gBAAgB3C,GAAOC,GAAM6C,CAAU;AAClE,QAAMH,EAAW,KAAKlB,CAAO,GAE7BkB,EAAW,QAAA;AACb;"}