{"version":3,"file":"EventBoundary.mjs","sources":["../src/EventBoundary.ts"],"sourcesContent":["import { Point, utils } from '@pixi/core';\nimport { EventsTicker } from './EventTicker';\nimport { FederatedMouseEvent } from './FederatedMouseEvent';\nimport { FederatedPointerEvent } from './FederatedPointerEvent';\nimport { FederatedWheelEvent } from './FederatedWheelEvent';\n\nimport type { DisplayObject } from '@pixi/display';\nimport type { EmitterListeners, TrackingData } from './EventBoundaryTypes';\nimport type { FederatedEvent } from './FederatedEvent';\nimport type {\n    Cursor, EventMode, FederatedEventHandler,\n    FederatedEventTarget,\n    IFederatedDisplayObject\n} from './FederatedEventTarget';\n\n// The maximum iterations used in propagation. This prevent infinite loops.\nconst PROPAGATION_LIMIT = 2048;\n\nconst tempHitLocation = new Point();\nconst tempLocalMapping = new Point();\n\n/**\n * Event boundaries are \"barriers\" where events coming from an upstream scene are modified before downstream propagation.\n *\n * ## Root event boundary\n *\n * The {@link PIXI.EventSystem#rootBoundary rootBoundary} handles events coming from the &lt;canvas /&gt;.\n * {@link PIXI.EventSystem} handles the normalization from native {@link https://dom.spec.whatwg.org/#event Events}\n * into {@link PIXI.FederatedEvent FederatedEvents}. The rootBoundary then does the hit-testing and event dispatch\n * for the upstream normalized event.\n *\n * ## Additional event boundaries\n *\n * An additional event boundary may be desired within an application's scene graph. For example, if a portion of the scene is\n * is flat with many children at one level - a spatial hash maybe needed to accelerate hit testing. In this scenario, the\n * container can be detached from the scene and glued using a custom event boundary.\n *\n * ```ts\n * import { Container } from '@pixi/display';\n * import { EventBoundary } from '@pixi/events';\n * import { SpatialHash } from 'pixi-spatial-hash';\n *\n * class HashedHitTestingEventBoundary\n * {\n *     private spatialHash: SpatialHash;\n *\n *     constructor(scene: Container, spatialHash: SpatialHash)\n *     {\n *         super(scene);\n *         this.spatialHash = spatialHash;\n *     }\n *\n *     hitTestRecursive(...)\n *     {\n *         // TODO: If target === this.rootTarget, then use spatial hash to get a\n *         // list of possible children that match the given (x,y) coordinates.\n *     }\n * }\n *\n * class VastScene extends DisplayObject\n * {\n *     protected eventBoundary: EventBoundary;\n *     protected scene: Container;\n *     protected spatialHash: SpatialHash;\n *\n *     constructor()\n *     {\n *         this.scene = new Container();\n *         this.spatialHash = new SpatialHash();\n *         this.eventBoundary = new HashedHitTestingEventBoundary(this.scene, this.spatialHash);\n *\n *         // Populate this.scene with a ton of children, while updating this.spatialHash\n *     }\n * }\n * ```\n * @memberof PIXI\n */\nexport class EventBoundary\n{\n    /**\n     * The root event-target residing below the event boundary.\n     *\n     * All events are dispatched trickling down and bubbling up to this `rootTarget`.\n     */\n    public rootTarget: DisplayObject;\n\n    /**\n     * Emits events after they were dispatched into the scene graph.\n     *\n     * This can be used for global events listening, regardless of the scene graph being used. It should\n     * not be used by interactive libraries for normal use.\n     *\n     * Special events that do not bubble all the way to the root target are not emitted from here,\n     * e.g. pointerenter, pointerleave, click.\n     */\n    public dispatch: utils.EventEmitter = new utils.EventEmitter();\n\n    /** The cursor preferred by the event targets underneath this boundary. */\n    public cursor: Cursor | string;\n\n    /**\n     * This flag would emit `pointermove`, `touchmove`, and `mousemove` events on all DisplayObjects.\n     *\n     * The `moveOnAll` semantics mirror those of earlier versions of PixiJS. This was disabled in favor of\n     * the Pointer Event API's approach.\n     */\n    public moveOnAll = false;\n\n    /** Enables the global move events. `globalpointermove`, `globaltouchmove`, and `globalmousemove` */\n    public enableGlobalMoveEvents = true;\n\n    /**\n     * Maps event types to forwarding handles for them.\n     *\n     * {@link PIXI.EventBoundary EventBoundary} provides mapping for \"pointerdown\", \"pointermove\",\n     * \"pointerout\", \"pointerleave\", \"pointerover\", \"pointerup\", and \"pointerupoutside\" by default.\n     * @see PIXI.EventBoundary#addEventMapping\n     */\n    protected mappingTable: Record<string, Array<{\n        fn: (e: FederatedEvent) => void,\n        priority: number\n    }>>;\n\n    /**\n     * State object for mapping methods.\n     * @see PIXI.EventBoundary#trackingData\n     */\n    protected mappingState: Record<string, any> = {\n        trackingData: {}\n    };\n\n    /**\n     * The event pool maps event constructors to an free pool of instances of those specific events.\n     * @see PIXI.EventBoundary#allocateEvent\n     * @see PIXI.EventBoundary#freeEvent\n     */\n    protected eventPool: Map<typeof FederatedEvent, FederatedEvent[]> = new Map();\n\n    /** Every interactive element gathered from the scene. Only used in `pointermove` */\n    private _allInteractiveElements: FederatedEventTarget[] = [];\n    /** Every element that passed the hit test. Only used in `pointermove` */\n    private _hitElements: FederatedEventTarget[] = [];\n    /** Whether or not to collect all the interactive elements from the scene. Enabled in `pointermove` */\n    private _isPointerMoveEvent = false;\n\n    /**\n     * @param rootTarget - The holder of the event boundary.\n     */\n    constructor(rootTarget?: DisplayObject)\n    {\n        this.rootTarget = rootTarget;\n\n        this.hitPruneFn = this.hitPruneFn.bind(this);\n        this.hitTestFn = this.hitTestFn.bind(this);\n        this.mapPointerDown = this.mapPointerDown.bind(this);\n        this.mapPointerMove = this.mapPointerMove.bind(this);\n        this.mapPointerOut = this.mapPointerOut.bind(this);\n        this.mapPointerOver = this.mapPointerOver.bind(this);\n        this.mapPointerUp = this.mapPointerUp.bind(this);\n        this.mapPointerUpOutside = this.mapPointerUpOutside.bind(this);\n        this.mapWheel = this.mapWheel.bind(this);\n\n        this.mappingTable = {};\n        this.addEventMapping('pointerdown', this.mapPointerDown);\n        this.addEventMapping('pointermove', this.mapPointerMove);\n        this.addEventMapping('pointerout', this.mapPointerOut);\n        this.addEventMapping('pointerleave', this.mapPointerOut);\n        this.addEventMapping('pointerover', this.mapPointerOver);\n        this.addEventMapping('pointerup', this.mapPointerUp);\n        this.addEventMapping('pointerupoutside', this.mapPointerUpOutside);\n        this.addEventMapping('wheel', this.mapWheel);\n    }\n\n    /**\n     * Adds an event mapping for the event `type` handled by `fn`.\n     *\n     * Event mappings can be used to implement additional or custom events. They take an event\n     * coming from the upstream scene (or directly from the {@link PIXI.EventSystem}) and dispatch new downstream events\n     * generally trickling down and bubbling up to {@link PIXI.EventBoundary.rootTarget this.rootTarget}.\n     *\n     * To modify the semantics of existing events, the built-in mapping methods of EventBoundary should be overridden\n     * instead.\n     * @param type - The type of upstream event to map.\n     * @param fn - The mapping method. The context of this function must be bound manually, if desired.\n     */\n    public addEventMapping(type: string, fn: (e: FederatedEvent) => void): void\n    {\n        if (!this.mappingTable[type])\n        {\n            this.mappingTable[type] = [];\n        }\n\n        this.mappingTable[type].push({\n            fn,\n            priority: 0,\n        });\n        this.mappingTable[type].sort((a, b) => a.priority - b.priority);\n    }\n\n    /**\n     * Dispatches the given event\n     * @param e\n     * @param type\n     */\n    public dispatchEvent(e: FederatedEvent, type?: string): void\n    {\n        e.propagationStopped = false;\n        e.propagationImmediatelyStopped = false;\n\n        this.propagate(e, type);\n        this.dispatch.emit(type || e.type, e);\n    }\n\n    /**\n     * Maps the given upstream event through the event boundary and propagates it downstream.\n     * @param e\n     */\n    public mapEvent(e: FederatedEvent): void\n    {\n        if (!this.rootTarget)\n        {\n            return;\n        }\n\n        const mappers = this.mappingTable[e.type];\n\n        if (mappers)\n        {\n            for (let i = 0, j = mappers.length; i < j; i++)\n            {\n                mappers[i].fn(e);\n            }\n        }\n        else\n        {\n            console.warn(`[EventBoundary]: Event mapping not defined for ${e.type}`);\n        }\n    }\n\n    /**\n     * Finds the DisplayObject that is the target of a event at the given coordinates.\n     *\n     * The passed (x,y) coordinates are in the world space above this event boundary.\n     * @param x\n     * @param y\n     */\n    public hitTest(\n        x: number,\n        y: number,\n    ): DisplayObject\n    {\n        EventsTicker.pauseUpdate = true;\n        // if we are using global move events, we need to hit test the whole scene graph\n        const useMove = this._isPointerMoveEvent && this.enableGlobalMoveEvents;\n        const fn = useMove ? 'hitTestMoveRecursive' : 'hitTestRecursive';\n        const invertedPath = this[fn](\n            this.rootTarget,\n            this.rootTarget.eventMode,\n            tempHitLocation.set(x, y),\n            this.hitTestFn,\n            this.hitPruneFn,\n        );\n\n        return invertedPath && invertedPath[0];\n    }\n\n    /**\n     * Propagate the passed event from from {@link PIXI.EventBoundary.rootTarget this.rootTarget} to its\n     * target {@code e.target}.\n     * @param e - The event to propagate.\n     * @param type\n     */\n    public propagate(e: FederatedEvent, type?: string): void\n    {\n        if (!e.target)\n        {\n            // This usually occurs when the scene graph is not interactive.\n            return;\n        }\n\n        const composedPath = e.composedPath();\n\n        // Capturing phase\n        e.eventPhase = e.CAPTURING_PHASE;\n\n        for (let i = 0, j = composedPath.length - 1; i < j; i++)\n        {\n            e.currentTarget = composedPath[i];\n\n            this.notifyTarget(e, type);\n\n            if (e.propagationStopped || e.propagationImmediatelyStopped) return;\n        }\n\n        // At target phase\n        e.eventPhase = e.AT_TARGET;\n        e.currentTarget = e.target;\n\n        this.notifyTarget(e, type);\n\n        if (e.propagationStopped || e.propagationImmediatelyStopped) return;\n\n        // Bubbling phase\n        e.eventPhase = e.BUBBLING_PHASE;\n\n        for (let i = composedPath.length - 2; i >= 0; i--)\n        {\n            e.currentTarget = composedPath[i];\n\n            this.notifyTarget(e, type);\n\n            if (e.propagationStopped || e.propagationImmediatelyStopped) return;\n        }\n    }\n\n    /**\n     * Emits the event {@code e} to all interactive display objects. The event is propagated in the bubbling phase always.\n     *\n     * This is used in the `globalpointermove` event.\n     * @param e - The emitted event.\n     * @param type - The listeners to notify.\n     * @param targets - The targets to notify.\n     */\n    public all(e: FederatedEvent, type?: string | string[], targets = this._allInteractiveElements): void\n    {\n        if (targets.length === 0) return;\n\n        e.eventPhase = e.BUBBLING_PHASE;\n\n        const events = Array.isArray(type) ? type : [type];\n\n        // loop through all interactive elements and notify them of the event\n        // loop through targets backwards\n        for (let i = targets.length - 1; i >= 0; i--)\n        {\n            events.forEach((event) =>\n            {\n                e.currentTarget = targets[i];\n                this.notifyTarget(e, event);\n            });\n        }\n    }\n\n    /**\n     * Finds the propagation path from {@link PIXI.EventBoundary.rootTarget rootTarget} to the passed\n     * {@code target}. The last element in the path is {@code target}.\n     * @param target\n     */\n    public propagationPath(target: FederatedEventTarget): FederatedEventTarget[]\n    {\n        const propagationPath = [target];\n\n        for (let i = 0; i < PROPAGATION_LIMIT && target !== this.rootTarget; i++)\n        {\n            if (!target.parent)\n            {\n                throw new Error('Cannot find propagation path to disconnected target');\n            }\n\n            propagationPath.push(target.parent);\n\n            target = target.parent;\n        }\n\n        propagationPath.reverse();\n\n        return propagationPath;\n    }\n\n    protected hitTestMoveRecursive(\n        currentTarget: DisplayObject,\n        eventMode: EventMode,\n        location: Point,\n        testFn: (object: DisplayObject, pt: Point) => boolean,\n        pruneFn?: (object: DisplayObject, pt: Point) => boolean,\n        ignore = false\n    ): DisplayObject[]\n    {\n        let shouldReturn = false;\n\n        // only bail out early if it is not interactive\n        if (this._interactivePrune(currentTarget)) return null;\n\n        if (currentTarget.eventMode === 'dynamic' || eventMode === 'dynamic')\n        {\n            EventsTicker.pauseUpdate = false;\n        }\n\n        if (currentTarget.interactiveChildren && currentTarget.children)\n        {\n            const children = currentTarget.children;\n\n            for (let i = children.length - 1; i >= 0; i--)\n            {\n                const child = children[i] as DisplayObject;\n\n                const nestedHit = this.hitTestMoveRecursive(\n                    child,\n                    this._isInteractive(eventMode) ? eventMode : child.eventMode,\n                    location,\n                    testFn,\n                    pruneFn,\n                    ignore || pruneFn(currentTarget, location)\n                );\n\n                if (nestedHit)\n                {\n                    // Its a good idea to check if a child has lost its parent.\n                    // this means it has been removed whilst looping so its best\n                    if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent)\n                    {\n                        continue;\n                    }\n\n                    // Only add the current hit-test target to the hit-test chain if the chain\n                    // has already started (i.e. the event target has been found) or if the current\n                    // target is interactive (i.e. it becomes the event target).\n                    const isInteractive = currentTarget.isInteractive();\n\n                    if (nestedHit.length > 0 || isInteractive)\n                    {\n                        if (isInteractive) this._allInteractiveElements.push(currentTarget);\n                        nestedHit.push(currentTarget);\n                    }\n\n                    // store all hit elements to be returned once we have traversed the whole tree\n                    if (this._hitElements.length === 0) this._hitElements = nestedHit;\n\n                    shouldReturn = true;\n                }\n            }\n        }\n\n        const isInteractiveMode = this._isInteractive(eventMode);\n        const isInteractiveTarget = currentTarget.isInteractive();\n\n        if (isInteractiveMode && isInteractiveTarget) this._allInteractiveElements.push(currentTarget);\n\n        // we don't carry on hit testing something once we have found a hit,\n        // now only care about gathering the interactive elements\n        if (ignore || this._hitElements.length > 0) return null;\n\n        if (shouldReturn) return this._hitElements as DisplayObject[];\n\n        // Finally, hit test this DisplayObject itself.\n        if (isInteractiveMode && (!pruneFn(currentTarget, location) && testFn(currentTarget, location)))\n        {\n            // The current hit-test target is the event's target only if it is interactive. Otherwise,\n            // the first interactive ancestor will be the event's target.\n            return isInteractiveTarget ? [currentTarget] : [];\n        }\n\n        return null;\n    }\n\n    /**\n     * Recursive implementation for {@link PIXI.EventBoundary.hitTest hitTest}.\n     * @param currentTarget - The DisplayObject that is to be hit tested.\n     * @param eventMode - The event mode for the `currentTarget` or one of its parents.\n     * @param location - The location that is being tested for overlap.\n     * @param testFn - Callback that determines whether the target passes hit testing. This callback\n     *  can assume that `pruneFn` failed to prune the display object.\n     * @param pruneFn - Callback that determiness whether the target and all of its children\n     *  cannot pass the hit test. It is used as a preliminary optimization to prune entire subtrees\n     *  of the scene graph.\n     * @returns An array holding the hit testing target and all its ancestors in order. The first element\n     *  is the target itself and the last is {@link PIXI.EventBoundary.rootTarget rootTarget}. This is the opposite\n     *  order w.r.t. the propagation path. If no hit testing target is found, null is returned.\n     */\n    protected hitTestRecursive(\n        currentTarget: DisplayObject,\n        eventMode: EventMode,\n        location: Point,\n        testFn: (object: DisplayObject, pt: Point) => boolean,\n        pruneFn?: (object: DisplayObject, pt: Point) => boolean\n    ): DisplayObject[]\n    {\n        // Attempt to prune this DisplayObject and its subtree as an optimization.\n        if (this._interactivePrune(currentTarget) || pruneFn(currentTarget, location))\n        {\n            return null;\n        }\n\n        if (currentTarget.eventMode === 'dynamic' || eventMode === 'dynamic')\n        {\n            EventsTicker.pauseUpdate = false;\n        }\n\n        // Find a child that passes the hit testing and return one, if any.\n        if (currentTarget.interactiveChildren && currentTarget.children)\n        {\n            const children = currentTarget.children;\n\n            for (let i = children.length - 1; i >= 0; i--)\n            {\n                const child = children[i] as DisplayObject;\n\n                const nestedHit = this.hitTestRecursive(\n                    child,\n                    this._isInteractive(eventMode) ? eventMode : child.eventMode,\n                    location,\n                    testFn,\n                    pruneFn\n                );\n\n                if (nestedHit)\n                {\n                    // Its a good idea to check if a child has lost its parent.\n                    // this means it has been removed whilst looping so its best\n                    if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent)\n                    {\n                        continue;\n                    }\n\n                    // Only add the current hit-test target to the hit-test chain if the chain\n                    // has already started (i.e. the event target has been found) or if the current\n                    // target is interactive (i.e. it becomes the event target).\n                    const isInteractive = currentTarget.isInteractive();\n\n                    if (nestedHit.length > 0 || isInteractive) nestedHit.push(currentTarget);\n\n                    return nestedHit;\n                }\n            }\n        }\n\n        const isInteractiveMode = this._isInteractive(eventMode);\n        const isInteractiveTarget = currentTarget.isInteractive();\n\n        // Finally, hit test this DisplayObject itself.\n        if (isInteractiveMode && testFn(currentTarget, location))\n        {\n            // The current hit-test target is the event's target only if it is interactive. Otherwise,\n            // the first interactive ancestor will be the event's target.\n            return isInteractiveTarget ? [currentTarget] : [];\n        }\n\n        return null;\n    }\n\n    private _isInteractive(int: EventMode): int is 'static' | 'dynamic'\n    {\n        return int === 'static' || int === 'dynamic';\n    }\n\n    private _interactivePrune(displayObject: DisplayObject): boolean\n    {\n        // If displayObject is a mask, invisible, or not renderable then it cannot be hit directly.\n        if (!displayObject || displayObject.isMask || !displayObject.visible || !displayObject.renderable)\n        {\n            return true;\n        }\n\n        // If this DisplayObject is none then it cannot be hit by anything.\n        if (displayObject.eventMode === 'none')\n        {\n            return true;\n        }\n\n        // If this DisplayObject is passive and it has no interactive children then it cannot be hit\n        if (displayObject.eventMode === 'passive' && !displayObject.interactiveChildren)\n        {\n            return true;\n        }\n\n        // If displayObject is a mask then it cannot be hit directly.\n        if (displayObject.isMask)\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    /**\n     * Checks whether the display object or any of its children cannot pass the hit test at all.\n     *\n     * {@link PIXI.EventBoundary}'s implementation uses the {@link PIXI.DisplayObject.hitArea hitArea}\n     * and {@link PIXI.DisplayObject._mask} for pruning.\n     * @param displayObject\n     * @param location\n     */\n    protected hitPruneFn(displayObject: DisplayObject, location: Point): boolean\n    {\n        if (displayObject.hitArea)\n        {\n            displayObject.worldTransform.applyInverse(location, tempLocalMapping);\n\n            if (!displayObject.hitArea.contains(tempLocalMapping.x, tempLocalMapping.y))\n            {\n                return true;\n            }\n        }\n\n        if (displayObject._mask)\n        {\n            const maskObject = ((displayObject._mask as any).isMaskData\n                ? (displayObject._mask as any).maskObject : displayObject._mask);\n\n            if (maskObject && !maskObject.containsPoint?.(location))\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Checks whether the display object passes hit testing for the given location.\n     * @param displayObject\n     * @param location\n     * @returns - Whether `displayObject` passes hit testing for `location`.\n     */\n    protected hitTestFn(displayObject: DisplayObject, location: Point): boolean\n    {\n        // If the displayObject is passive then it cannot be hit directly.\n        if (displayObject.eventMode === 'passive')\n        {\n            return false;\n        }\n\n        // If the display object failed pruning with a hitArea, then it must pass it.\n        if (displayObject.hitArea)\n        {\n            return true;\n        }\n\n        if ((displayObject as any).containsPoint)\n        {\n            return (displayObject as any).containsPoint(location) as boolean;\n        }\n\n        // TODO: Should we hit test based on bounds?\n\n        return false;\n    }\n\n    /**\n     * Notify all the listeners to the event's `currentTarget`.\n     *\n     * If the `currentTarget` contains the property `on<type>`, then it is called here,\n     * simulating the behavior from version 6.x and prior.\n     * @param e - The event passed to the target.\n     * @param type\n     */\n    protected notifyTarget(e: FederatedEvent, type?: string): void\n    {\n        type = type ?? e.type;\n\n        // call the `on${type}` for the current target if it exists\n        const handlerKey = `on${type}` as keyof IFederatedDisplayObject;\n\n        (e.currentTarget[handlerKey] as FederatedEventHandler<FederatedEvent>)?.(e);\n\n        const key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET ? `${type}capture` : type;\n\n        this.notifyListeners(e, key);\n\n        if (e.eventPhase === e.AT_TARGET)\n        {\n            this.notifyListeners(e, type);\n        }\n    }\n\n    /**\n     * Maps the upstream `pointerdown` events to a downstream `pointerdown` event.\n     *\n     * `touchstart`, `rightdown`, `mousedown` events are also dispatched for specific pointer types.\n     * @param from\n     */\n    protected mapPointerDown(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        const e = this.createPointerEvent(from);\n\n        this.dispatchEvent(e, 'pointerdown');\n\n        if (e.pointerType === 'touch')\n        {\n            this.dispatchEvent(e, 'touchstart');\n        }\n        else if (e.pointerType === 'mouse' || e.pointerType === 'pen')\n        {\n            const isRightButton = e.button === 2;\n\n            this.dispatchEvent(e, isRightButton ? 'rightdown' : 'mousedown');\n        }\n\n        const trackingData = this.trackingData(from.pointerId);\n\n        trackingData.pressTargetsByButton[from.button] = e.composedPath();\n\n        this.freeEvent(e);\n    }\n\n    /**\n     * Maps the upstream `pointermove` to downstream `pointerout`, `pointerover`, and `pointermove` events, in that order.\n     *\n     * The tracking data for the specific pointer has an updated `overTarget`. `mouseout`, `mouseover`,\n     * `mousemove`, and `touchmove` events are fired as well for specific pointer types.\n     * @param from - The upstream `pointermove` event.\n     */\n    protected mapPointerMove(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        this._allInteractiveElements.length = 0;\n        this._hitElements.length = 0;\n        this._isPointerMoveEvent = true;\n        const e = this.createPointerEvent(from);\n\n        this._isPointerMoveEvent = false;\n        const isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen';\n        const trackingData = this.trackingData(from.pointerId);\n        const outTarget = this.findMountedTarget(trackingData.overTargets);\n\n        // First pointerout/pointerleave\n        if (trackingData.overTargets?.length > 0 && outTarget !== e.target)\n        {\n            // pointerout always occurs on the overTarget when the pointer hovers over another element.\n            const outType = from.type === 'mousemove' ? 'mouseout' : 'pointerout';\n            const outEvent = this.createPointerEvent(from, outType, outTarget);\n\n            this.dispatchEvent(outEvent, 'pointerout');\n            if (isMouse) this.dispatchEvent(outEvent, 'mouseout');\n\n            // If the pointer exits overTarget and its descendants, then a pointerleave event is also fired. This event\n            // is dispatched to all ancestors that no longer capture the pointer.\n            if (!e.composedPath().includes(outTarget))\n            {\n                const leaveEvent = this.createPointerEvent(from, 'pointerleave', outTarget);\n\n                leaveEvent.eventPhase = leaveEvent.AT_TARGET;\n\n                while (leaveEvent.target && !e.composedPath().includes(leaveEvent.target))\n                {\n                    leaveEvent.currentTarget = leaveEvent.target;\n\n                    this.notifyTarget(leaveEvent);\n                    if (isMouse) this.notifyTarget(leaveEvent, 'mouseleave');\n\n                    leaveEvent.target = leaveEvent.target.parent;\n                }\n\n                this.freeEvent(leaveEvent);\n            }\n\n            this.freeEvent(outEvent);\n        }\n\n        // Then pointerover\n        if (outTarget !== e.target)\n        {\n            // pointerover always occurs on the new overTarget\n            const overType = from.type === 'mousemove' ? 'mouseover' : 'pointerover';\n            const overEvent = this.clonePointerEvent(e, overType);// clone faster\n\n            this.dispatchEvent(overEvent, 'pointerover');\n            if (isMouse) this.dispatchEvent(overEvent, 'mouseover');\n\n            // Probe whether the newly hovered DisplayObject is an ancestor of the original overTarget.\n            let overTargetAncestor = outTarget?.parent;\n\n            while (overTargetAncestor && overTargetAncestor !== this.rootTarget.parent)\n            {\n                if (overTargetAncestor === e.target) break;\n\n                overTargetAncestor = overTargetAncestor.parent;\n            }\n\n            // The pointer has entered a non-ancestor of the original overTarget. This means we need a pointerentered\n            // event.\n            const didPointerEnter = !overTargetAncestor || overTargetAncestor === this.rootTarget.parent;\n\n            if (didPointerEnter)\n            {\n                const enterEvent = this.clonePointerEvent(e, 'pointerenter');\n\n                enterEvent.eventPhase = enterEvent.AT_TARGET;\n\n                while (enterEvent.target\n                        && enterEvent.target !== outTarget\n                        && enterEvent.target !== this.rootTarget.parent)\n                {\n                    enterEvent.currentTarget = enterEvent.target;\n\n                    this.notifyTarget(enterEvent);\n                    if (isMouse) this.notifyTarget(enterEvent, 'mouseenter');\n\n                    enterEvent.target = enterEvent.target.parent;\n                }\n\n                this.freeEvent(enterEvent);\n            }\n\n            this.freeEvent(overEvent);\n        }\n\n        const allMethods: string[] = [];\n        const allowGlobalPointerEvents = this.enableGlobalMoveEvents ?? true;\n\n        /* eslint-disable @typescript-eslint/no-unused-expressions */\n        this.moveOnAll ? allMethods.push('pointermove') : this.dispatchEvent(e, 'pointermove');\n        allowGlobalPointerEvents && allMethods.push('globalpointermove');\n\n        // Then pointermove\n        if (e.pointerType === 'touch')\n        {\n            this.moveOnAll ? allMethods.splice(1, 0, 'touchmove') : this.dispatchEvent(e, 'touchmove');\n            allowGlobalPointerEvents && allMethods.push('globaltouchmove');\n        }\n\n        if (isMouse)\n        {\n            this.moveOnAll ? allMethods.splice(1, 0, 'mousemove') : this.dispatchEvent(e, 'mousemove');\n            allowGlobalPointerEvents && allMethods.push('globalmousemove');\n            this.cursor = e.target?.cursor;\n        }\n\n        if (allMethods.length > 0)\n        {\n            this.all(e, allMethods);\n        }\n        this._allInteractiveElements.length = 0;\n        this._hitElements.length = 0;\n        /* eslint-enable @typescript-eslint/no-unused-expressions */\n\n        trackingData.overTargets = e.composedPath();\n\n        this.freeEvent(e);\n    }\n\n    /**\n     * Maps the upstream `pointerover` to downstream `pointerover` and `pointerenter` events, in that order.\n     *\n     * The tracking data for the specific pointer gets a new `overTarget`.\n     * @param from - The upstream `pointerover` event.\n     */\n    protected mapPointerOver(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        const trackingData = this.trackingData(from.pointerId);\n        const e = this.createPointerEvent(from);\n        const isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen';\n\n        this.dispatchEvent(e, 'pointerover');\n        if (isMouse) this.dispatchEvent(e, 'mouseover');\n        if (e.pointerType === 'mouse') this.cursor = e.target?.cursor;\n\n        // pointerenter events must be fired since the pointer entered from upstream.\n        const enterEvent = this.clonePointerEvent(e, 'pointerenter');\n\n        enterEvent.eventPhase = enterEvent.AT_TARGET;\n\n        while (enterEvent.target && enterEvent.target !== this.rootTarget.parent)\n        {\n            enterEvent.currentTarget = enterEvent.target;\n\n            this.notifyTarget(enterEvent);\n            if (isMouse) this.notifyTarget(enterEvent, 'mouseenter');\n\n            enterEvent.target = enterEvent.target.parent;\n        }\n\n        trackingData.overTargets = e.composedPath();\n\n        this.freeEvent(e);\n        this.freeEvent(enterEvent);\n    }\n\n    /**\n     * Maps the upstream `pointerout` to downstream `pointerout`, `pointerleave` events, in that order.\n     *\n     * The tracking data for the specific pointer is cleared of a `overTarget`.\n     * @param from - The upstream `pointerout` event.\n     */\n    protected mapPointerOut(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        const trackingData = this.trackingData(from.pointerId);\n\n        if (trackingData.overTargets)\n        {\n            const isMouse = from.pointerType === 'mouse' || from.pointerType === 'pen';\n            const outTarget = this.findMountedTarget(trackingData.overTargets);\n\n            // pointerout first\n            const outEvent = this.createPointerEvent(from, 'pointerout', outTarget);\n\n            this.dispatchEvent(outEvent);\n            if (isMouse) this.dispatchEvent(outEvent, 'mouseout');\n\n            // pointerleave(s) are also dispatched b/c the pointer must've left rootTarget and its descendants to\n            // get an upstream pointerout event (upstream events do not know rootTarget has descendants).\n            const leaveEvent = this.createPointerEvent(from, 'pointerleave', outTarget);\n\n            leaveEvent.eventPhase = leaveEvent.AT_TARGET;\n\n            while (leaveEvent.target && leaveEvent.target !== this.rootTarget.parent)\n            {\n                leaveEvent.currentTarget = leaveEvent.target;\n\n                this.notifyTarget(leaveEvent);\n                if (isMouse) this.notifyTarget(leaveEvent, 'mouseleave');\n\n                leaveEvent.target = leaveEvent.target.parent;\n            }\n\n            trackingData.overTargets = null;\n\n            this.freeEvent(outEvent);\n            this.freeEvent(leaveEvent);\n        }\n\n        this.cursor = null;\n    }\n\n    /**\n     * Maps the upstream `pointerup` event to downstream `pointerup`, `pointerupoutside`,\n     * and `click`/`rightclick`/`pointertap` events, in that order.\n     *\n     * The `pointerupoutside` event bubbles from the original `pointerdown` target to the most specific\n     * ancestor of the `pointerdown` and `pointerup` targets, which is also the `click` event's target. `touchend`,\n     * `rightup`, `mouseup`, `touchendoutside`, `rightupoutside`, `mouseupoutside`, and `tap` are fired as well for\n     * specific pointer types.\n     * @param from - The upstream `pointerup` event.\n     */\n    protected mapPointerUp(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        const now = performance.now();\n        const e = this.createPointerEvent(from);\n\n        this.dispatchEvent(e, 'pointerup');\n\n        if (e.pointerType === 'touch')\n        {\n            this.dispatchEvent(e, 'touchend');\n        }\n        else if (e.pointerType === 'mouse' || e.pointerType === 'pen')\n        {\n            const isRightButton = e.button === 2;\n\n            this.dispatchEvent(e, isRightButton ? 'rightup' : 'mouseup');\n        }\n\n        const trackingData = this.trackingData(from.pointerId);\n        const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);\n\n        let clickTarget = pressTarget;\n\n        // pointerupoutside only bubbles. It only bubbles upto the parent that doesn't contain\n        // the pointerup location.\n        if (pressTarget && !e.composedPath().includes(pressTarget))\n        {\n            let currentTarget = pressTarget;\n\n            while (currentTarget && !e.composedPath().includes(currentTarget))\n            {\n                e.currentTarget = currentTarget;\n\n                this.notifyTarget(e, 'pointerupoutside');\n\n                if (e.pointerType === 'touch')\n                {\n                    this.notifyTarget(e, 'touchendoutside');\n                }\n                else if (e.pointerType === 'mouse' || e.pointerType === 'pen')\n                {\n                    const isRightButton = e.button === 2;\n\n                    this.notifyTarget(e, isRightButton ? 'rightupoutside' : 'mouseupoutside');\n                }\n\n                currentTarget = currentTarget.parent;\n            }\n\n            delete trackingData.pressTargetsByButton[from.button];\n\n            // currentTarget is the most specific ancestor holding both the pointerdown and pointerup\n            // targets. That is - it's our click target!\n            clickTarget = currentTarget;\n        }\n\n        // click!\n        if (clickTarget)\n        {\n            const clickEvent = this.clonePointerEvent(e, 'click');\n\n            clickEvent.target = clickTarget;\n            clickEvent.path = null;\n\n            if (!trackingData.clicksByButton[from.button])\n            {\n                trackingData.clicksByButton[from.button] = {\n                    clickCount: 0,\n                    target: clickEvent.target,\n                    timeStamp: now,\n                };\n            }\n\n            const clickHistory = trackingData.clicksByButton[from.button];\n\n            if (clickHistory.target === clickEvent.target\n                && now - clickHistory.timeStamp < 200)\n            {\n                ++clickHistory.clickCount;\n            }\n            else\n            {\n                clickHistory.clickCount = 1;\n            }\n\n            clickHistory.target = clickEvent.target;\n            clickHistory.timeStamp = now;\n\n            clickEvent.detail = clickHistory.clickCount;\n\n            if (clickEvent.pointerType === 'mouse')\n            {\n                const isRightButton = clickEvent.button === 2;\n\n                this.dispatchEvent(clickEvent, isRightButton ? 'rightclick' : 'click');\n            }\n            else if (clickEvent.pointerType === 'touch')\n            {\n                this.dispatchEvent(clickEvent, 'tap');\n            }\n\n            this.dispatchEvent(clickEvent, 'pointertap');\n\n            this.freeEvent(clickEvent);\n        }\n\n        this.freeEvent(e);\n    }\n\n    /**\n     * Maps the upstream `pointerupoutside` event to a downstream `pointerupoutside` event, bubbling from the original\n     * `pointerdown` target to `rootTarget`.\n     *\n     * (The most specific ancestor of the `pointerdown` event and the `pointerup` event must the\n     * `{@link PIXI.EventBoundary}'s root because the `pointerup` event occurred outside of the boundary.)\n     *\n     * `touchendoutside`, `mouseupoutside`, and `rightupoutside` events are fired as well for specific pointer\n     * types. The tracking data for the specific pointer is cleared of a `pressTarget`.\n     * @param from - The upstream `pointerupoutside` event.\n     */\n    protected mapPointerUpOutside(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent))\n        {\n            console.warn('EventBoundary cannot map a non-pointer event as a pointer event');\n\n            return;\n        }\n\n        const trackingData = this.trackingData(from.pointerId);\n        const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);\n        const e = this.createPointerEvent(from);\n\n        if (pressTarget)\n        {\n            let currentTarget = pressTarget;\n\n            while (currentTarget)\n            {\n                e.currentTarget = currentTarget;\n\n                this.notifyTarget(e, 'pointerupoutside');\n\n                if (e.pointerType === 'touch')\n                {\n                    this.notifyTarget(e, 'touchendoutside');\n                }\n                else if (e.pointerType === 'mouse' || e.pointerType === 'pen')\n                {\n                    this.notifyTarget(e, e.button === 2 ? 'rightupoutside' : 'mouseupoutside');\n                }\n\n                currentTarget = currentTarget.parent;\n            }\n\n            delete trackingData.pressTargetsByButton[from.button];\n        }\n\n        this.freeEvent(e);\n    }\n\n    /**\n     * Maps the upstream `wheel` event to a downstream `wheel` event.\n     * @param from - The upstream `wheel` event.\n     */\n    protected mapWheel(from: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedWheelEvent))\n        {\n            console.warn('EventBoundary cannot map a non-wheel event as a wheel event');\n\n            return;\n        }\n\n        const wheelEvent = this.createWheelEvent(from);\n\n        this.dispatchEvent(wheelEvent);\n        this.freeEvent(wheelEvent);\n    }\n\n    /**\n     * Finds the most specific event-target in the given propagation path that is still mounted in the scene graph.\n     *\n     * This is used to find the correct `pointerup` and `pointerout` target in the case that the original `pointerdown`\n     * or `pointerover` target was unmounted from the scene graph.\n     * @param propagationPath - The propagation path was valid in the past.\n     * @returns - The most specific event-target still mounted at the same location in the scene graph.\n     */\n    protected findMountedTarget(propagationPath: FederatedEventTarget[]): FederatedEventTarget\n    {\n        if (!propagationPath)\n        {\n            return null;\n        }\n\n        let currentTarget = propagationPath[0];\n\n        for (let i = 1; i < propagationPath.length; i++)\n        {\n            // Set currentTarget to the next target in the path only if it is still attached to the\n            // scene graph (i.e. parent still points to the expected ancestor).\n            if (propagationPath[i].parent === currentTarget)\n            {\n                currentTarget = propagationPath[i];\n            }\n            else\n            {\n                break;\n            }\n        }\n\n        return currentTarget;\n    }\n\n    /**\n     * Creates an event whose {@code originalEvent} is {@code from}, with an optional `type` and `target` override.\n     *\n     * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}.\n     * @param from - The {@code originalEvent} for the returned event.\n     * @param [type=from.type] - The type of the returned event.\n     * @param target - The target of the returned event.\n     */\n    protected createPointerEvent(\n        from: FederatedPointerEvent,\n        type?: string,\n        target?: FederatedEventTarget\n    ): FederatedPointerEvent\n    {\n        const event = this.allocateEvent(FederatedPointerEvent);\n\n        this.copyPointerData(from, event);\n        this.copyMouseData(from, event);\n        this.copyData(from, event);\n\n        event.nativeEvent = from.nativeEvent;\n        event.originalEvent = from;\n        event.target = target\n            ?? this.hitTest(event.global.x, event.global.y) as FederatedEventTarget\n            ?? this._hitElements[0];\n\n        if (typeof type === 'string')\n        {\n            event.type = type;\n        }\n\n        return event;\n    }\n\n    /**\n     * Creates a wheel event whose {@code originalEvent} is {@code from}.\n     *\n     * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}.\n     * @param from - The upstream wheel event.\n     */\n    protected createWheelEvent(from: FederatedWheelEvent): FederatedWheelEvent\n    {\n        const event = this.allocateEvent(FederatedWheelEvent);\n\n        this.copyWheelData(from, event);\n        this.copyMouseData(from, event);\n        this.copyData(from, event);\n\n        event.nativeEvent = from.nativeEvent;\n        event.originalEvent = from;\n        event.target = this.hitTest(event.global.x, event.global.y);\n\n        return event;\n    }\n\n    /**\n     * Clones the event {@code from}, with an optional {@code type} override.\n     *\n     * The event is allocated using {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}.\n     * @param from - The event to clone.\n     * @param [type=from.type] - The type of the returned event.\n     */\n    protected clonePointerEvent(from: FederatedPointerEvent, type?: string): FederatedPointerEvent\n    {\n        const event = this.allocateEvent(FederatedPointerEvent);\n\n        event.nativeEvent = from.nativeEvent;\n        event.originalEvent = from.originalEvent;\n\n        this.copyPointerData(from, event);\n        this.copyMouseData(from, event);\n        this.copyData(from, event);\n\n        // copy propagation path for perf\n        event.target = from.target;\n        event.path = from.composedPath().slice();\n        event.type = type ?? event.type;\n\n        return event;\n    }\n\n    /**\n     * Copies wheel {@link PIXI.FederatedWheelEvent} data from {@code from} into {@code to}.\n     *\n     * The following properties are copied:\n     * + deltaMode\n     * + deltaX\n     * + deltaY\n     * + deltaZ\n     * @param from\n     * @param to\n     */\n    protected copyWheelData(from: FederatedWheelEvent, to: FederatedWheelEvent): void\n    {\n        to.deltaMode = from.deltaMode;\n        to.deltaX = from.deltaX;\n        to.deltaY = from.deltaY;\n        to.deltaZ = from.deltaZ;\n    }\n\n    /**\n     * Copies pointer {@link PIXI.FederatedPointerEvent} data from {@code from} into {@code to}.\n     *\n     * The following properties are copied:\n     * + pointerId\n     * + width\n     * + height\n     * + isPrimary\n     * + pointerType\n     * + pressure\n     * + tangentialPressure\n     * + tiltX\n     * + tiltY\n     * @param from\n     * @param to\n     */\n    protected copyPointerData(from: FederatedEvent, to: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedPointerEvent && to instanceof FederatedPointerEvent)) return;\n\n        to.pointerId = from.pointerId;\n        to.width = from.width;\n        to.height = from.height;\n        to.isPrimary = from.isPrimary;\n        to.pointerType = from.pointerType;\n        to.pressure = from.pressure;\n        to.tangentialPressure = from.tangentialPressure;\n        to.tiltX = from.tiltX;\n        to.tiltY = from.tiltY;\n        to.twist = from.twist;\n    }\n\n    /**\n     * Copies mouse {@link PIXI.FederatedMouseEvent} data from {@code from} to {@code to}.\n     *\n     * The following properties are copied:\n     * + altKey\n     * + button\n     * + buttons\n     * + clientX\n     * + clientY\n     * + metaKey\n     * + movementX\n     * + movementY\n     * + pageX\n     * + pageY\n     * + x\n     * + y\n     * + screen\n     * + shiftKey\n     * + global\n     * @param from\n     * @param to\n     */\n    protected copyMouseData(from: FederatedEvent, to: FederatedEvent): void\n    {\n        if (!(from instanceof FederatedMouseEvent && to instanceof FederatedMouseEvent)) return;\n\n        to.altKey = from.altKey;\n        to.button = from.button;\n        to.buttons = from.buttons;\n        to.client.copyFrom(from.client);\n        to.ctrlKey = from.ctrlKey;\n        to.metaKey = from.metaKey;\n        to.movement.copyFrom(from.movement);\n        to.screen.copyFrom(from.screen);\n        to.shiftKey = from.shiftKey;\n        to.global.copyFrom(from.global);\n    }\n\n    /**\n     * Copies base {@link PIXI.FederatedEvent} data from {@code from} into {@code to}.\n     *\n     * The following properties are copied:\n     * + isTrusted\n     * + srcElement\n     * + timeStamp\n     * + type\n     * @param from - The event to copy data from.\n     * @param to - The event to copy data into.\n     */\n    protected copyData(from: FederatedEvent, to: FederatedEvent): void\n    {\n        to.isTrusted = from.isTrusted;\n        to.srcElement = from.srcElement;\n        to.timeStamp = performance.now();\n        to.type = from.type;\n        to.detail = from.detail;\n        to.view = from.view;\n        to.which = from.which;\n        to.layer.copyFrom(from.layer);\n        to.page.copyFrom(from.page);\n    }\n\n    /**\n     * @param id - The pointer ID.\n     * @returns The tracking data stored for the given pointer. If no data exists, a blank\n     *  state will be created.\n     */\n    protected trackingData(id: number): TrackingData\n    {\n        if (!this.mappingState.trackingData[id])\n        {\n            this.mappingState.trackingData[id] = {\n                pressTargetsByButton: {},\n                clicksByButton: {},\n                overTarget: null\n            };\n        }\n\n        return this.mappingState.trackingData[id];\n    }\n\n    /**\n     * Allocate a specific type of event from {@link PIXI.EventBoundary#eventPool this.eventPool}.\n     *\n     * This allocation is constructor-agnostic, as long as it only takes one argument - this event\n     * boundary.\n     * @param constructor - The event's constructor.\n     */\n    protected allocateEvent<T extends FederatedEvent>(\n        constructor: { new(boundary: EventBoundary): T }\n    ): T\n    {\n        if (!this.eventPool.has(constructor as any))\n        {\n            this.eventPool.set(constructor as any, []);\n        }\n\n        const event = this.eventPool.get(constructor as any).pop() as T\n            || new constructor(this);\n\n        event.eventPhase = event.NONE;\n        event.currentTarget = null;\n        event.path = null;\n        event.target = null;\n\n        return event;\n    }\n\n    /**\n     * Frees the event and puts it back into the event pool.\n     *\n     * It is illegal to reuse the event until it is allocated again, using `this.allocateEvent`.\n     *\n     * It is also advised that events not allocated from {@link PIXI.EventBoundary#allocateEvent this.allocateEvent}\n     * not be freed. This is because of the possibility that the same event is freed twice, which can cause\n     * it to be allocated twice & result in overwriting.\n     * @param event - The event to be freed.\n     * @throws Error if the event is managed by another event boundary.\n     */\n    protected freeEvent<T extends FederatedEvent>(event: T): void\n    {\n        if (event.manager !== this) throw new Error('It is illegal to free an event not managed by this EventBoundary!');\n\n        const constructor = event.constructor;\n\n        if (!this.eventPool.has(constructor as any))\n        {\n            this.eventPool.set(constructor as any, []);\n        }\n\n        this.eventPool.get(constructor as any).push(event);\n    }\n\n    /**\n     * Similar to {@link PIXI.EventEmitter.emit}, except it stops if the `propagationImmediatelyStopped` flag\n     * is set on the event.\n     * @param e - The event to call each listener with.\n     * @param type - The event key.\n     */\n    private notifyListeners(e: FederatedEvent, type: string): void\n    {\n        const listeners = ((e.currentTarget as any)._events as EmitterListeners)[type];\n\n        if (!listeners) return;\n        if (!e.currentTarget.isInteractive()) return;\n\n        if ('fn' in listeners)\n        {\n            if (listeners.once) e.currentTarget.removeListener(type, listeners.fn, undefined, true);\n            listeners.fn.call(listeners.context, e);\n        }\n        else\n        {\n            for (\n                let i = 0, j = listeners.length;\n                i < j && !e.propagationImmediatelyStopped;\n                i++)\n            {\n                if (listeners[i].once) e.currentTarget.removeListener(type, listeners[i].fn, undefined, true);\n                listeners[i].fn.call(listeners[i].context, e);\n            }\n        }\n    }\n}\n"],"names":[],"mappings":"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"}