@foblex/flow 17.8.3 → 17.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,9 @@
1
- import { FConnectorBase } from '../../../../f-connectors';
1
+ import { EFConnectableSide, FConnectorBase } from '../../../../f-connectors';
2
+ export type TCalculateMode = EFConnectableSide.CALCULATE | EFConnectableSide.CALCULATE_HORIZONTAL | EFConnectableSide.CALCULATE_VERTICAL;
3
+ export declare const CALCULATE_MODES: EFConnectableSide[];
2
4
  export declare class CalculateConnectableSideByConnectedPositionsRequest {
3
5
  readonly connector: FConnectorBase;
6
+ readonly mode: TCalculateMode;
4
7
  static readonly fToken: unique symbol;
5
- constructor(connector: FConnectorBase);
8
+ constructor(connector: FConnectorBase, mode: TCalculateMode);
6
9
  }
@@ -4,42 +4,45 @@ import { EFConnectableSide } from '../../../../f-connectors';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
6
6
  * Execution that calculates the connectable side for a connector
7
- * based on the positions of its connected connectors.
7
+ * based on positions of connected connectors and allowed sides.
8
8
  */
9
9
  export declare class CalculateConnectableSideByConnectedPositions implements IExecution<CalculateConnectableSideByConnectedPositionsRequest, EFConnectableSide> {
10
10
  private readonly _mediator;
11
11
  /**
12
- * Handles the request to calculate the connectable side for a connector
13
- * based on the positions of its connected connectors.
12
+ * Entry point (hot path). Avoids intermediate arrays and redundant allocations.
14
13
  *
15
- * @param request - Contains the connector host element and its connected connectors.
16
- * @returns {EFConnectableSide} - The calculated connectable side.
14
+ * @param request - Contains the connector and optionally allowed sides.
15
+ * @returns {EFConnectableSide} - The chosen connectable side.
17
16
  */
18
- handle({ connector, }: CalculateConnectableSideByConnectedPositionsRequest): EFConnectableSide;
17
+ handle({ connector, mode, }: CalculateConnectableSideByConnectedPositionsRequest): EFConnectableSide;
19
18
  /**
20
- * Extracts the gravity centers of connected connectors, excluding the current connector.
21
- *
22
- * @param selfHost - The host element of the current connector.
23
- * @param connected - The list of connected connectors.
24
- * @returns {Array<{x: number, y: number}>} - An array of gravity center coordinates.
19
+ * Accumulates sum of gravity centers and count, excluding the current host.
20
+ * Single pass, minimal allocations.
25
21
  */
26
- private _getConnectedCenters;
22
+ private _accumulateConnectedCenters;
27
23
  /**
28
- * Calculates the average point (center of mass) from a set of points.
29
- *
30
- * @param points - An array of point objects with x and y coordinates.
31
- * @returns {{x: number, y: number}} - The average x and y coordinate.
24
+ * Converts allowed sides array to a compact bit mask.
25
+ * If not provided or empty -> all sides allowed.
32
26
  */
33
- private _calculateAveragePoint;
27
+ private _toSideMask;
34
28
  /**
35
- * Determines the connectable side of the current connector relative to the
36
- * average position of its connected connectors.
37
- *
38
- * @param self - The gravity center of the current connector.
39
- * @param avg - The average gravity center of connected connectors.
40
- * @returns {EFConnectableSide} - The chosen side (LEFT, RIGHT, TOP, BOTTOM).
29
+ * Determines final side using ideal side first; if disallowed, picks best fallback.
30
+ * Inputs are numbers to avoid object wrappers on hot path.
41
31
  */
42
32
  private _determineSide;
33
+ /**
34
+ * Picks the "ideal" side based on vector (dx, dy) with hysteresis.
35
+ */
36
+ private _pickIdealSide;
37
+ /**
38
+ * Quick membership check via bit mask.
39
+ */
40
+ private _isAllowed;
41
+ /**
42
+ * Picks the best available side from allowed mask by maximizing directional score.
43
+ * No intermediate objects, constant-time operations.
44
+ */
45
+ private _pickFallbackSide;
43
46
  static ɵfac: i0.ɵɵFactoryDeclaration<CalculateConnectableSideByConnectedPositions, never>;
44
47
  static ɵprov: i0.ɵɵInjectableDeclaration<CalculateConnectableSideByConnectedPositions>;
45
48
  }
@@ -4,56 +4,25 @@ import * as i0 from "@angular/core";
4
4
  /**
5
5
  * Execution that calculates connectable sides for all connectors of a node.
6
6
  *
7
- * Responsibility:
8
- * - For each connector, decide the effective connectable side according to:
9
- * - AUTO -> by internal position relative to node host
10
- * - CALCULATE -> by positions of connected connectors
11
- * - explicit -> use the user-defined side as-is
12
- * - For each `toConnector` whose user side is CALCULATE, recalculate it as well.
7
+ * Performance goals:
8
+ * - Single-pass loops (no `forEach`).
9
+ * - Unique target recomputation (avoid repeated mediator calls for the same target).
10
+ * - Fast checks for "calculate" modes (bit mask instead of `includes`).
13
11
  */
14
12
  export declare class CalculateNodeConnectorsConnectableSides implements IExecution<CalculateNodeConnectorsConnectableSidesRequest, void> {
15
13
  private readonly _mediator;
16
14
  /**
17
15
  * Orchestrates side calculation for all connectors of the given node.
18
- *
19
- * @param request.node - Node whose connectors should be recalculated.
16
+ * Two-phase approach:
17
+ * 1) Update each connector's own side.
18
+ * 2) Collect unique `toConnector` with calculate modes and recompute once.
20
19
  */
21
20
  handle({ node }: CalculateNodeConnectorsConnectableSidesRequest): void;
22
21
  /**
23
- * Calculates and assigns the connectable side for a single connector.
24
- *
25
- * @param connector - The connector being updated.
22
+ * Fast resolver for a single connector.
23
+ * Uses switch and avoids array operations.
26
24
  */
27
- private _updateConnectorSide;
28
- /**
29
- * Recalculates connectable sides for all `toConnector` items that are marked as CALCULATE.
30
- *
31
- * @param source - The source connector whose outgoing connections should be processed.
32
- */
33
- private _updateConnectedTargets;
34
- /**
35
- * Resolves the effective side for a connector according to its user preference.
36
- *
37
- * @param connector - The connector to resolve side for.
38
- * @returns {EFConnectableSide} - The resolved side.
39
- */
40
- private _resolveSideForConnector;
41
- /**
42
- * Calculates side using the connector's internal position relative to the node host.
43
- * Delegates to `CalculateConnectableSideByInternalPositionRequest`.
44
- *
45
- * @param connector - Current connector.
46
- * @returns {EFConnectableSide}
47
- */
48
- private _resolveSideByInternalPosition;
49
- /**
50
- * Calculates side using average positions of connectors connected to the given connector.
51
- * Delegates to `CalculateConnectableSideByConnectedPositionsRequest`.
52
- *
53
- * @param connector - Current connector.
54
- * @returns {EFConnectableSide}
55
- */
56
- private _resolveSideByConnectedPositions;
25
+ private _resolveSideForConnectorFast;
57
26
  static ɵfac: i0.ɵɵFactoryDeclaration<CalculateNodeConnectorsConnectableSides, never>;
58
27
  static ɵprov: i0.ɵɵInjectableDeclaration<CalculateNodeConnectorsConnectableSides>;
59
28
  }
@@ -14,4 +14,4 @@ import { CalculateConnectableSideByConnectedPositions, CalculateConnectableSideB
14
14
  /**
15
15
  * This file exports all the node-related executions that can be used in the F-Flow domain.
16
16
  */
17
- export declare const F_NODE_FEATURES: (typeof AddNodeToStore | typeof CalculateConnectableSideByConnectedPositions | typeof CalculateConnectableSideByInternalPosition | typeof CalculateInputConnections | typeof CalculateNodeConnectorsConnectableSides | typeof CalculateNodesBoundingBox | typeof CalculateNodesBoundingBoxNormalizedPosition | typeof CalculateOutputConnections | typeof FitToChildNodesAndGroups | typeof GetChildNodeIds | typeof GetNodePadding | typeof GetNodes | typeof GetParentNodes | typeof UpdateNodeWhenStateOrSizeChanged | typeof RemoveNodeFromStore)[];
17
+ export declare const F_NODE_FEATURES: (typeof CalculateConnectableSideByConnectedPositions | typeof CalculateNodeConnectorsConnectableSides | typeof AddNodeToStore | typeof CalculateConnectableSideByInternalPosition | typeof CalculateInputConnections | typeof CalculateNodesBoundingBox | typeof CalculateNodesBoundingBoxNormalizedPosition | typeof CalculateOutputConnections | typeof FitToChildNodesAndGroups | typeof GetChildNodeIds | typeof GetNodePadding | typeof GetNodes | typeof GetParentNodes | typeof UpdateNodeWhenStateOrSizeChanged | typeof RemoveNodeFromStore)[];
@@ -10,4 +10,4 @@ import { GetNormalizedConnectorRectExecution } from "./get-normalized-connector-
10
10
  * draggable elements, flow, line alignment, nodes, selection, zoom,
11
11
  * and various utility executions.
12
12
  */
13
- export declare const COMMON_PROVIDERS: (typeof import("./f-node").AddNodeToStore | typeof import("./f-node").CalculateConnectableSideByConnectedPositions | typeof import("./f-node").CalculateConnectableSideByInternalPosition | typeof import("./f-node").CalculateInputConnections | typeof import("./f-node").CalculateNodeConnectorsConnectableSides | typeof import("./f-node").CalculateNodesBoundingBoxNormalizedPosition | typeof import("./f-node").CalculateOutputConnections | typeof import("./f-node").FitToChildNodesAndGroups | typeof import("./f-node").GetChildNodeIds | typeof import("./f-node").GetNodePadding | typeof import("./f-node").GetParentNodes | typeof import("./f-node").UpdateNodeWhenStateOrSizeChanged | typeof import("./f-node").RemoveNodeFromStore | typeof import("./f-canvas").AddCanvasToStoreExecution | typeof import("./f-canvas").CenterGroupOrNodeExecution | typeof import("./f-canvas").FitToFlowExecution | typeof import("./f-canvas").InputCanvasPositionExecution | typeof import("./f-canvas").InputCanvasScaleExecution | typeof import("./f-canvas").RedrawCanvasWithAnimationExecution | typeof import("./f-canvas").ResetScaleAndCenterExecution | typeof import("./f-canvas").UpdateScaleExecution | typeof import("./f-connection").AddConnectionForCreateToStoreExecution | typeof import("./f-connection").AddConnectionMarkerToStoreExecution | typeof import("./f-connection").AddConnectionToStoreExecution | typeof import("./f-connection").AddSnapConnectionToStoreExecution | typeof import("./f-connection").CreateConnectionMarkersExecution | typeof import("./f-connection").CalculateConnectionLineByBehavior | typeof import("./f-connection").RemoveConnectionFromStoreExecution | typeof import("./f-connection").RemoveConnectionMarkerFromStoreExecution | typeof import("./f-background").AddBackgroundToStoreExecution | typeof import("./f-background").AddPatternToBackgroundExecution | typeof import("./f-background").RemoveBackgroundFromStoreExecution | typeof import("./f-background").SetBackgroundTransformExecution | typeof import("./f-connectors").AddInputToStore | typeof import("./f-connectors").AddOutletToStore | typeof import("./f-connectors").AddOutputToStore | typeof import("./f-connectors").CalculateClosestConnector | typeof import("./f-connectors").FindConnectableConnectorUsingPriorityAndPositionExecution | typeof import("./f-connectors").GetAllCanBeConnectedSourceConnectorsAndRectsExecution | typeof import("./f-connectors").GetAllCanBeConnectedInputsAndRectsExecution | typeof import("./f-connectors").GetConnectorAndRect | typeof import("./f-connectors").MarkConnectableConnectors | typeof import("./f-connectors").RemoveInputFromStore | typeof import("./f-connectors").RemoveOutletFromStoreExecution | typeof import("./f-connectors").RemoveOutputFromStoreExecution | typeof import("./f-connectors").UnmarkConnectableConnectors | typeof import("./f-draggable").AddDndToStoreExecution | typeof import("./f-draggable").OnPointerMoveExecution | typeof import("./f-flow").AddFlowToStoreExecution | typeof import("./f-flow").GetFlowStateNodesExecution | typeof import("./f-line-alignment").AddLineAlignmentToStoreExecution | typeof GetElementRoundedRectExecution | typeof import("./f-selection").SelectExecution | typeof import("./f-selection").SelectAndUpdateNodeLayerExecution | typeof import("./f-zoom").AddZoomToStoreExecution | typeof import("./f-zoom").SetZoomExecution | typeof GetDeepChildrenNodesAndGroupsExecution | typeof GetNormalizedConnectorRectExecution | typeof GetNormalizedElementRectExecution | typeof GetNormalizedPointExecution | typeof UpdateItemAndChildrenLayersExecution | typeof MoveFrontElementsBeforeTargetElementExecution)[];
13
+ export declare const COMMON_PROVIDERS: (typeof import("./f-node").CalculateConnectableSideByConnectedPositions | typeof import("./f-node").CalculateNodeConnectorsConnectableSides | typeof GetElementRoundedRectExecution | typeof import("./f-canvas").AddCanvasToStoreExecution | typeof import("./f-canvas").CenterGroupOrNodeExecution | typeof import("./f-canvas").FitToFlowExecution | typeof import("./f-canvas").InputCanvasPositionExecution | typeof import("./f-canvas").InputCanvasScaleExecution | typeof import("./f-canvas").RedrawCanvasWithAnimationExecution | typeof import("./f-canvas").ResetScaleAndCenterExecution | typeof import("./f-canvas").UpdateScaleExecution | typeof import("./f-connection").AddConnectionForCreateToStoreExecution | typeof import("./f-connection").AddConnectionMarkerToStoreExecution | typeof import("./f-connection").AddConnectionToStoreExecution | typeof import("./f-connection").AddSnapConnectionToStoreExecution | typeof import("./f-connection").CreateConnectionMarkersExecution | typeof import("./f-connection").CalculateConnectionLineByBehavior | typeof import("./f-connection").RemoveConnectionFromStoreExecution | typeof import("./f-connection").RemoveConnectionMarkerFromStoreExecution | typeof import("./f-background").AddBackgroundToStoreExecution | typeof import("./f-background").AddPatternToBackgroundExecution | typeof import("./f-background").RemoveBackgroundFromStoreExecution | typeof import("./f-background").SetBackgroundTransformExecution | typeof import("./f-connectors").AddInputToStore | typeof import("./f-connectors").AddOutletToStore | typeof import("./f-connectors").AddOutputToStore | typeof import("./f-connectors").CalculateClosestConnector | typeof import("./f-connectors").FindConnectableConnectorUsingPriorityAndPositionExecution | typeof import("./f-connectors").GetAllCanBeConnectedSourceConnectorsAndRectsExecution | typeof import("./f-connectors").GetAllCanBeConnectedInputsAndRectsExecution | typeof import("./f-connectors").GetConnectorAndRect | typeof import("./f-connectors").MarkConnectableConnectors | typeof import("./f-connectors").RemoveInputFromStore | typeof import("./f-connectors").RemoveOutletFromStoreExecution | typeof import("./f-connectors").RemoveOutputFromStoreExecution | typeof import("./f-connectors").UnmarkConnectableConnectors | typeof import("./f-draggable").AddDndToStoreExecution | typeof import("./f-draggable").OnPointerMoveExecution | typeof import("./f-flow").AddFlowToStoreExecution | typeof import("./f-flow").GetFlowStateNodesExecution | typeof import("./f-line-alignment").AddLineAlignmentToStoreExecution | typeof import("./f-node").AddNodeToStore | typeof import("./f-node").CalculateConnectableSideByInternalPosition | typeof import("./f-node").CalculateInputConnections | typeof import("./f-node").CalculateNodesBoundingBoxNormalizedPosition | typeof import("./f-node").CalculateOutputConnections | typeof import("./f-node").FitToChildNodesAndGroups | typeof import("./f-node").GetChildNodeIds | typeof import("./f-node").GetNodePadding | typeof import("./f-node").GetParentNodes | typeof import("./f-node").UpdateNodeWhenStateOrSizeChanged | typeof import("./f-node").RemoveNodeFromStore | typeof import("./f-selection").SelectExecution | typeof import("./f-selection").SelectAndUpdateNodeLayerExecution | typeof import("./f-zoom").AddZoomToStoreExecution | typeof import("./f-zoom").SetZoomExecution | typeof GetDeepChildrenNodesAndGroupsExecution | typeof GetNormalizedConnectorRectExecution | typeof GetNormalizedElementRectExecution | typeof GetNormalizedPointExecution | typeof UpdateItemAndChildrenLayersExecution | typeof MoveFrontElementsBeforeTargetElementExecution)[];
@@ -1,8 +1,16 @@
1
+ import { EFConnectableSide } from '../../../../f-connectors';
2
+ export const CALCULATE_MODES = [
3
+ EFConnectableSide.CALCULATE,
4
+ EFConnectableSide.CALCULATE_HORIZONTAL,
5
+ EFConnectableSide.CALCULATE_VERTICAL,
6
+ ];
1
7
  export class CalculateConnectableSideByConnectedPositionsRequest {
2
8
  connector;
9
+ mode;
3
10
  static fToken = Symbol('CalculateConnectableSideByConnectedPositionsRequest');
4
- constructor(connector) {
11
+ constructor(connector, mode) {
5
12
  this.connector = connector;
13
+ this.mode = mode;
6
14
  }
7
15
  }
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy1yZXF1ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZi1mbG93L3NyYy9kb21haW4vZi1ub2RlL2NhbGN1bGF0ZS1ub2RlLWNvbm5lY3RvcnMtY29ubmVjdGFibGUtc2lkZXMvY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy9jYWxjdWxhdGUtY29ubmVjdGFibGUtc2lkZS1ieS1jb25uZWN0ZWQtcG9zaXRpb25zLXJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLG1EQUFtRDtJQUVsQztJQUQ1QixNQUFNLENBQVUsTUFBTSxHQUFHLE1BQU0sQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO0lBQ3ZGLFlBQTRCLFNBQXlCO1FBQXpCLGNBQVMsR0FBVCxTQUFTLENBQWdCO0lBQUcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZDb25uZWN0b3JCYXNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vZi1jb25uZWN0b3JzJztcblxuZXhwb3J0IGNsYXNzIENhbGN1bGF0ZUNvbm5lY3RhYmxlU2lkZUJ5Q29ubmVjdGVkUG9zaXRpb25zUmVxdWVzdCB7XG4gIHN0YXRpYyByZWFkb25seSBmVG9rZW4gPSBTeW1ib2woJ0NhbGN1bGF0ZUNvbm5lY3RhYmxlU2lkZUJ5Q29ubmVjdGVkUG9zaXRpb25zUmVxdWVzdCcpO1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgY29ubmVjdG9yOiBGQ29ubmVjdG9yQmFzZSkge31cbn1cbiJdfQ==
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy1yZXF1ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZi1mbG93L3NyYy9kb21haW4vZi1ub2RlL2NhbGN1bGF0ZS1ub2RlLWNvbm5lY3RvcnMtY29ubmVjdGFibGUtc2lkZXMvY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy9jYWxjdWxhdGUtY29ubmVjdGFibGUtc2lkZS1ieS1jb25uZWN0ZWQtcG9zaXRpb25zLXJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFrQixNQUFNLDBCQUEwQixDQUFDO0FBTzdFLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRztJQUM3QixpQkFBaUIsQ0FBQyxTQUFTO0lBQzNCLGlCQUFpQixDQUFDLG9CQUFvQjtJQUN0QyxpQkFBaUIsQ0FBQyxrQkFBa0I7Q0FDckMsQ0FBQztBQUVGLE1BQU0sT0FBTyxtREFBbUQ7SUFHNUM7SUFDQTtJQUhsQixNQUFNLENBQVUsTUFBTSxHQUFHLE1BQU0sQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO0lBQ3ZGLFlBQ2tCLFNBQXlCLEVBQ3pCLElBQW9CO1FBRHBCLGNBQVMsR0FBVCxTQUFTLENBQWdCO1FBQ3pCLFNBQUksR0FBSixJQUFJLENBQWdCO0lBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFRkNvbm5lY3RhYmxlU2lkZSwgRkNvbm5lY3RvckJhc2UgfSBmcm9tICcuLi8uLi8uLi8uLi9mLWNvbm5lY3RvcnMnO1xuXG5leHBvcnQgdHlwZSBUQ2FsY3VsYXRlTW9kZSA9XG4gIHwgRUZDb25uZWN0YWJsZVNpZGUuQ0FMQ1VMQVRFXG4gIHwgRUZDb25uZWN0YWJsZVNpZGUuQ0FMQ1VMQVRFX0hPUklaT05UQUxcbiAgfCBFRkNvbm5lY3RhYmxlU2lkZS5DQUxDVUxBVEVfVkVSVElDQUw7XG5cbmV4cG9ydCBjb25zdCBDQUxDVUxBVEVfTU9ERVMgPSBbXG4gIEVGQ29ubmVjdGFibGVTaWRlLkNBTENVTEFURSxcbiAgRUZDb25uZWN0YWJsZVNpZGUuQ0FMQ1VMQVRFX0hPUklaT05UQUwsXG4gIEVGQ29ubmVjdGFibGVTaWRlLkNBTENVTEFURV9WRVJUSUNBTCxcbl07XG5cbmV4cG9ydCBjbGFzcyBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3Qge1xuICBzdGF0aWMgcmVhZG9ubHkgZlRva2VuID0gU3ltYm9sKCdDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QnKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3RvcjogRkNvbm5lY3RvckJhc2UsXG4gICAgcHVibGljIHJlYWRvbmx5IG1vZGU6IFRDYWxjdWxhdGVNb2RlLFxuICApIHt9XG59XG4iXX0=
@@ -3,82 +3,171 @@ import { inject, Injectable } from '@angular/core';
3
3
  import { FExecutionRegister, FMediator } from '@foblex/mediator';
4
4
  import { CalculateConnectableSideByConnectedPositionsRequest } from './calculate-connectable-side-by-connected-positions-request';
5
5
  import { EFConnectableSide } from '../../../../f-connectors';
6
- import { PointExtensions, RectExtensions } from '@foblex/2d';
6
+ import { RectExtensions } from '@foblex/2d';
7
7
  import { CalculateConnectableSideByInternalPositionRequest } from '../calculate-connectable-side-by-internal-position';
8
8
  import * as i0 from "@angular/core";
9
+ const SNAP_EPS = 2;
10
+ const CALCULATE_SIDES = {
11
+ [EFConnectableSide.CALCULATE]: [
12
+ EFConnectableSide.TOP,
13
+ EFConnectableSide.BOTTOM,
14
+ EFConnectableSide.LEFT,
15
+ EFConnectableSide.RIGHT,
16
+ ],
17
+ [EFConnectableSide.CALCULATE_HORIZONTAL]: [EFConnectableSide.LEFT, EFConnectableSide.RIGHT],
18
+ [EFConnectableSide.CALCULATE_VERTICAL]: [EFConnectableSide.TOP, EFConnectableSide.BOTTOM],
19
+ };
9
20
  /**
10
21
  * Execution that calculates the connectable side for a connector
11
- * based on the positions of its connected connectors.
22
+ * based on positions of connected connectors and allowed sides.
12
23
  */
13
24
  let CalculateConnectableSideByConnectedPositions = class CalculateConnectableSideByConnectedPositions {
14
25
  _mediator = inject(FMediator);
15
26
  /**
16
- * Handles the request to calculate the connectable side for a connector
17
- * based on the positions of its connected connectors.
27
+ * Entry point (hot path). Avoids intermediate arrays and redundant allocations.
18
28
  *
19
- * @param request - Contains the connector host element and its connected connectors.
20
- * @returns {EFConnectableSide} - The calculated connectable side.
29
+ * @param request - Contains the connector and optionally allowed sides.
30
+ * @returns {EFConnectableSide} - The chosen connectable side.
21
31
  */
22
- handle({ connector, }) {
32
+ handle({ connector, mode, }) {
23
33
  const selfCenter = RectExtensions.fromElement(connector.hostElement).gravityCenter;
24
- const targetCenters = this._getConnectedCenters(connector.hostElement, connector.toConnector);
25
- if (!targetCenters.length) {
34
+ const acc = this._accumulateConnectedCenters(connector.hostElement, connector.toConnector);
35
+ if (acc.count === 0) {
26
36
  return this._mediator.execute(new CalculateConnectableSideByInternalPositionRequest(connector));
27
37
  }
28
- const avg = this._calculateAveragePoint(targetCenters);
29
- return this._determineSide(selfCenter, avg);
38
+ const avgX = acc.sumX / acc.count;
39
+ const avgY = acc.sumY / acc.count;
40
+ const mask = this._toSideMask(CALCULATE_SIDES[mode]);
41
+ return this._determineSide(selfCenter.x, selfCenter.y, avgX, avgY, mask);
30
42
  }
31
43
  /**
32
- * Extracts the gravity centers of connected connectors, excluding the current connector.
33
- *
34
- * @param selfHost - The host element of the current connector.
35
- * @param connected - The list of connected connectors.
36
- * @returns {Array<{x: number, y: number}>} - An array of gravity center coordinates.
44
+ * Accumulates sum of gravity centers and count, excluding the current host.
45
+ * Single pass, minimal allocations.
37
46
  */
38
- _getConnectedCenters(selfHost, connected) {
39
- return (connected ?? [])
40
- .map((c) => c?.hostElement)
41
- .filter((el) => !!el && el !== selfHost)
42
- .map((el) => RectExtensions.fromElement(el).gravityCenter);
47
+ _accumulateConnectedCenters(selfHost, connected) {
48
+ let sumX = 0;
49
+ let sumY = 0;
50
+ let count = 0;
51
+ if (connected && connected.length) {
52
+ for (let i = 0; i < connected.length; i++) {
53
+ const el = connected[i]?.hostElement;
54
+ if (!el || el === selfHost)
55
+ continue;
56
+ const c = RectExtensions.fromElement(el).gravityCenter;
57
+ sumX += c.x;
58
+ sumY += c.y;
59
+ count++;
60
+ }
61
+ }
62
+ return { sumX, sumY, count };
43
63
  }
44
64
  /**
45
- * Calculates the average point (center of mass) from a set of points.
46
- *
47
- * @param points - An array of point objects with x and y coordinates.
48
- * @returns {{x: number, y: number}} - The average x and y coordinate.
65
+ * Converts allowed sides array to a compact bit mask.
66
+ * If not provided or empty -> all sides allowed.
49
67
  */
50
- _calculateAveragePoint(points) {
51
- const sum = points.reduce((result, p) => {
52
- result.x += p.x;
53
- result.y += p.y;
54
- return result;
55
- }, PointExtensions.initialize());
56
- return {
57
- x: sum.x / points.length,
58
- y: sum.y / points.length,
59
- };
68
+ _toSideMask(allowed) {
69
+ if (!allowed || allowed.length === 0)
70
+ return 15 /* SideMask.ALL */;
71
+ let mask = 0 /* SideMask.NONE */;
72
+ for (let i = 0; i < allowed.length; i++) {
73
+ switch (allowed[i]) {
74
+ case EFConnectableSide.LEFT:
75
+ mask |= 1 /* SideMask.LEFT */;
76
+ break;
77
+ case EFConnectableSide.RIGHT:
78
+ mask |= 2 /* SideMask.RIGHT */;
79
+ break;
80
+ case EFConnectableSide.TOP:
81
+ mask |= 4 /* SideMask.TOP */;
82
+ break;
83
+ case EFConnectableSide.BOTTOM:
84
+ mask |= 8 /* SideMask.BOTTOM */;
85
+ break;
86
+ }
87
+ }
88
+ return mask || 15 /* SideMask.ALL */;
60
89
  }
61
90
  /**
62
- * Determines the connectable side of the current connector relative to the
63
- * average position of its connected connectors.
64
- *
65
- * @param self - The gravity center of the current connector.
66
- * @param avg - The average gravity center of connected connectors.
67
- * @returns {EFConnectableSide} - The chosen side (LEFT, RIGHT, TOP, BOTTOM).
91
+ * Determines final side using ideal side first; if disallowed, picks best fallback.
92
+ * Inputs are numbers to avoid object wrappers on hot path.
68
93
  */
69
- _determineSide(self, avg) {
70
- const dx = avg.x - self.x;
71
- const dy = avg.y - self.y;
72
- const snapEps = 2; // px — hysteresis threshold to avoid side-flipping near diagonals
73
- if (Math.abs(dx) - Math.abs(dy) > snapEps) {
94
+ _determineSide(selfX, selfY, avgX, avgY, allowedMask) {
95
+ const dx = avgX - selfX;
96
+ const dy = avgY - selfY;
97
+ const ideal = this._pickIdealSide(dx, dy);
98
+ if (this._isAllowed(ideal, allowedMask)) {
99
+ return ideal;
100
+ }
101
+ return this._pickFallbackSide(dx, dy, allowedMask, ideal);
102
+ }
103
+ /**
104
+ * Picks the "ideal" side based on vector (dx, dy) with hysteresis.
105
+ */
106
+ _pickIdealSide(dx, dy) {
107
+ const ax = dx < 0 ? -dx : dx;
108
+ const ay = dy < 0 ? -dy : dy;
109
+ if (ax - ay > SNAP_EPS) {
74
110
  return dx < 0 ? EFConnectableSide.LEFT : EFConnectableSide.RIGHT;
75
111
  }
76
- if (Math.abs(dy) - Math.abs(dx) > snapEps) {
112
+ if (ay - ax > SNAP_EPS) {
77
113
  return dy < 0 ? EFConnectableSide.TOP : EFConnectableSide.BOTTOM;
78
114
  }
79
- // When differences are nearly equal, prefer vertical orientation for stability
80
115
  return dy < 0 ? EFConnectableSide.TOP : EFConnectableSide.BOTTOM;
81
116
  }
117
+ /**
118
+ * Quick membership check via bit mask.
119
+ */
120
+ _isAllowed(side, mask) {
121
+ switch (side) {
122
+ case EFConnectableSide.LEFT:
123
+ return (mask & 1 /* SideMask.LEFT */) !== 0;
124
+ case EFConnectableSide.RIGHT:
125
+ return (mask & 2 /* SideMask.RIGHT */) !== 0;
126
+ case EFConnectableSide.TOP:
127
+ return (mask & 4 /* SideMask.TOP */) !== 0;
128
+ case EFConnectableSide.BOTTOM:
129
+ return (mask & 8 /* SideMask.BOTTOM */) !== 0;
130
+ default:
131
+ return true;
132
+ }
133
+ }
134
+ /**
135
+ * Picks the best available side from allowed mask by maximizing directional score.
136
+ * No intermediate objects, constant-time operations.
137
+ */
138
+ _pickFallbackSide(dx, dy, allowedMask, ideal) {
139
+ let bestSide = ideal;
140
+ let bestScore = -Infinity;
141
+ if (allowedMask & 2 /* SideMask.RIGHT */) {
142
+ const s = dx;
143
+ if (s > bestScore) {
144
+ bestScore = s;
145
+ bestSide = EFConnectableSide.RIGHT;
146
+ }
147
+ }
148
+ if (allowedMask & 1 /* SideMask.LEFT */) {
149
+ const s = -dx;
150
+ if (s > bestScore) {
151
+ bestScore = s;
152
+ bestSide = EFConnectableSide.LEFT;
153
+ }
154
+ }
155
+ if (allowedMask & 8 /* SideMask.BOTTOM */) {
156
+ const s = dy;
157
+ if (s > bestScore) {
158
+ bestScore = s;
159
+ bestSide = EFConnectableSide.BOTTOM;
160
+ }
161
+ }
162
+ if (allowedMask & 4 /* SideMask.TOP */) {
163
+ const s = -dy;
164
+ if (s > bestScore) {
165
+ bestScore = s;
166
+ bestSide = EFConnectableSide.TOP;
167
+ }
168
+ }
169
+ return bestSide;
170
+ }
82
171
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CalculateConnectableSideByConnectedPositions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
83
172
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CalculateConnectableSideByConnectedPositions });
84
173
  };
@@ -89,4 +178,4 @@ export { CalculateConnectableSideByConnectedPositions };
89
178
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CalculateConnectableSideByConnectedPositions, decorators: [{
90
179
  type: Injectable
91
180
  }] });
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2YtZmxvdy9zcmMvZG9tYWluL2Ytbm9kZS9jYWxjdWxhdGUtbm9kZS1jb25uZWN0b3JzLWNvbm5lY3RhYmxlLXNpZGVzL2NhbGN1bGF0ZS1jb25uZWN0YWJsZS1zaWRlLWJ5LWNvbm5lY3RlZC1wb3NpdGlvbnMvY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBYyxNQUFNLGtCQUFrQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxtREFBbUQsRUFBRSxNQUFNLDZEQUE2RCxDQUFDO0FBQ2xJLE9BQU8sRUFBRSxpQkFBaUIsRUFBa0IsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RSxPQUFPLEVBQVUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNyRSxPQUFPLEVBQUUsaURBQWlELEVBQUUsTUFBTSxvREFBb0QsQ0FBQzs7QUFFdkg7OztHQUdHO0FBR0ksSUFBTSw0Q0FBNEMsR0FBbEQsTUFBTSw0Q0FBNEM7SUFHdEMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUUvQzs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsRUFDWixTQUFTLEdBQzJDO1FBQ3BELE1BQU0sVUFBVSxHQUFHLGNBQWMsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDLGFBQWEsQ0FBQztRQUNuRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxT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QixDQUFDLG1EQUFtRCxDQUFDO0dBQzNELDRDQUE0QyxDQTRGeEQ7OzRGQTVGWSw0Q0FBNEM7a0JBRnhELFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZFeGVjdXRpb25SZWdpc3RlciwgRk1lZGlhdG9yLCBJRXhlY3V0aW9uIH0gZnJvbSAnQGZvYmxleC9tZWRpYXRvcic7XG5pbXBvcnQgeyBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QgfSBmcm9tICcuL2NhbGN1bGF0ZS1jb25uZWN0YWJsZS1zaWRlLWJ5LWNvbm5lY3RlZC1wb3NpdGlvbnMtcmVxdWVzdCc7XG5pbXBvcnQgeyBFRkNvbm5lY3RhYmxlU2lkZSwgRkNvbm5lY3RvckJhc2UgfSBmcm9tICcuLi8uLi8uLi8uLi9mLWNvbm5lY3RvcnMnO1xuaW1wb3J0IHsgSVBvaW50LCBQb2ludEV4dGVuc2lvbnMsIFJlY3RFeHRlbnNpb25zIH0gZnJvbSAnQGZvYmxleC8yZCc7XG5pbXBvcnQgeyBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUludGVybmFsUG9zaXRpb25SZXF1ZXN0IH0gZnJvbSAnLi4vY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktaW50ZXJuYWwtcG9zaXRpb24nO1xuXG4vKipcbiAqIEV4ZWN1dGlvbiB0aGF0IGNhbGN1bGF0ZXMgdGhlIGNvbm5lY3RhYmxlIHNpZGUgZm9yIGEgY29ubmVjdG9yXG4gKiBiYXNlZCBvbiB0aGUgcG9zaXRpb25zIG9mIGl0cyBjb25uZWN0ZWQgY29ubmVjdG9ycy5cbiAqL1xuQEluamVjdGFibGUoKVxuQEZFeGVjdXRpb25SZWdpc3RlcihDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QpXG5leHBvcnQgY2xhc3MgQ2FsY3VsYXRlQ29ubmVjdGFibGVTaWRlQnlDb25uZWN0ZWRQb3NpdGlvbnNcbiAgaW1wbGVtZW50cyBJRXhlY3V0aW9uPENhbGN1bGF0ZUNvbm5lY3RhYmxlU2lkZUJ5Q29ubmVjdGVkUG9zaXRpb25zUmVxdWVzdCwgRUZDb25uZWN0YWJsZVNpZGU+XG57XG4gIHByaXZhdGUgcmVhZG9ubHkgX21lZGlhdG9yID0gaW5qZWN0KEZNZWRpYXRvcik7XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHJlcXVlc3QgdG8gY2FsY3VsYXRlIHRoZSBjb25uZWN0YWJsZSBzaWRlIGZvciBhIGNvbm5lY3RvclxuICAgKiBiYXNlZCBvbiB0aGUgcG9zaXRpb25zIG9mIGl0cyBjb25uZWN0ZWQgY29ubmVjdG9ycy5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVlc3QgLSBDb250YWlucyB0aGUgY29ubmVjdG9yIGhvc3QgZWxlbWVudCBhbmQgaXRzIGNvbm5lY3RlZCBjb25uZWN0b3JzLlxuICAgKiBAcmV0dXJucyB7RUZDb25uZWN0YWJsZVNpZGV9IC0gVGhlIGNhbGN1bGF0ZWQgY29ubmVjdGFibGUgc2lkZS5cbiAgICovXG4gIHB1YmxpYyBoYW5kbGUoe1xuICAgIGNvbm5lY3RvcixcbiAgfTogQ2FsY3VsYXRlQ29ubmVjdGFibGVTaWRlQnlDb25uZWN0ZWRQb3NpdGlvbnNSZXF1ZXN0KTogRUZDb25uZWN0YWJsZVNpZGUge1xuICAgIGNvbnN0IHNlbGZDZW50ZXIgPSBSZWN0RXh0ZW5zaW9ucy5mcm9tRWxlbWVudChjb25uZWN0b3IuaG9zdEVsZW1lbnQpLmdyYXZpdHlDZW50ZXI7XG4gICAgY29uc3QgdGFyZ2V0Q2VudGVycyA9IHRoaXMuX2dldENvbm5lY3RlZENlbnRlcnMoY29ubmVjdG9yLmhvc3RFbGVtZW50LCBjb25uZWN0b3IudG9Db25uZWN0b3IpO1xuXG4gICAgaWYgKCF0YXJnZXRDZW50ZXJzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuX21lZGlhdG9yLmV4ZWN1dGUoXG4gICAgICAgIG5ldyBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUludGVybmFsUG9zaXRpb25SZXF1ZXN0KGNvbm5lY3RvciksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGF2ZyA9IHRoaXMuX2NhbGN1bGF0ZUF2ZXJhZ2VQb2ludCh0YXJnZXRDZW50ZXJzKTtcblxuICAgIHJldHVybiB0aGlzLl9kZXRlcm1pbmVTaWRlKHNlbGZDZW50ZXIsIGF2Zyk7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdHMgdGhlIGdyYXZpdHkgY2VudGVycyBvZiBjb25uZWN0ZWQgY29ubmVjdG9ycywgZXhjbHVkaW5nIHRoZSBjdXJyZW50IGNvbm5lY3Rvci5cbiAgICpcbiAgICogQHBhcmFtIHNlbGZIb3N0IC0gVGhlIGhvc3QgZWxlbWVudCBvZiB0aGUgY3VycmVudCBjb25uZWN0b3IuXG4gICAqIEBwYXJhbSBjb25uZWN0ZWQgLSBUaGUgbGlzdCBvZiBjb25uZWN0ZWQgY29ubmVjdG9ycy5cbiAgICogQHJldHVybnMge0FycmF5PHt4OiBudW1iZXIsIHk6IG51bWJlcn0+fSAtIEFuIGFycmF5IG9mIGdyYXZpdHkgY2VudGVyIGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0Q29ubmVjdGVkQ2VudGVycyhcbiAgICBzZWxmSG9zdDogSFRNTEVsZW1lbnQgfCBTVkdFbGVtZW50LFxuICAgIGNvbm5lY3RlZDogRkNvbm5lY3RvckJhc2VbXSxcbiAgKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9W10ge1xuICAgIHJldHVybiAoY29ubmVjdGVkID8/IFtdKVxuICAgICAgLm1hcCgoYykgPT4gYz8uaG9zdEVsZW1lbnQpXG4gICAgICAuZmlsdGVyKChlbCk6IGVsIGlzIEhUTUxFbGVtZW50IHwgU1ZHRWxlbWVudCA9PiAhIWVsICYmIGVsICE9PSBzZWxmSG9zdClcbiAgICAgIC5tYXAoKGVsKSA9PiBSZWN0RXh0ZW5zaW9ucy5mcm9tRWxlbWVudChlbCkuZ3Jhdml0eUNlbnRlcik7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgYXZlcmFnZSBwb2ludCAoY2VudGVyIG9mIG1hc3MpIGZyb20gYSBzZXQgb2YgcG9pbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gcG9pbnRzIC0gQW4gYXJyYXkgb2YgcG9pbnQgb2JqZWN0cyB3aXRoIHggYW5kIHkgY29vcmRpbmF0ZXMuXG4gICAqIEByZXR1cm5zIHt7eDogbnVtYmVyLCB5OiBudW1iZXJ9fSAtIFRoZSBhdmVyYWdlIHggYW5kIHkgY29vcmRpbmF0ZS5cbiAgICovXG4gIHByaXZhdGUgX2NhbGN1bGF0ZUF2ZXJhZ2VQb2ludChwb2ludHM6IElQb2ludFtdKTogSVBvaW50IHtcbiAgICBjb25zdCBzdW0gPSBwb2ludHMucmVkdWNlKChyZXN1bHQ6IElQb2ludCwgcDogSVBvaW50KSA9PiB7XG4gICAgICByZXN1bHQueCArPSBwLng7XG4gICAgICByZXN1bHQueSArPSBwLnk7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwgUG9pbnRFeHRlbnNpb25zLmluaXRpYWxpemUoKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogc3VtLnggLyBwb2ludHMubGVuZ3RoLFxuICAgICAgeTogc3VtLnkgLyBwb2ludHMubGVuZ3RoLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgY29ubmVjdGFibGUgc2lkZSBvZiB0aGUgY3VycmVudCBjb25uZWN0b3IgcmVsYXRpdmUgdG8gdGhlXG4gICAqIGF2ZXJhZ2UgcG9zaXRpb24gb2YgaXRzIGNvbm5lY3RlZCBjb25uZWN0b3JzLlxuICAgKlxuICAgKiBAcGFyYW0gc2VsZiAtIFRoZSBncmF2aXR5IGNlbnRlciBvZiB0aGUgY3VycmVudCBjb25uZWN0b3IuXG4gICAqIEBwYXJhbSBhdmcgLSBUaGUgYXZlcmFnZSBncmF2aXR5IGNlbnRlciBvZiBjb25uZWN0ZWQgY29ubmVjdG9ycy5cbiAgICogQHJldHVybnMge0VGQ29ubmVjdGFibGVTaWRlfSAtIFRoZSBjaG9zZW4gc2lkZSAoTEVGVCwgUklHSFQsIFRPUCwgQk9UVE9NKS5cbiAgICovXG4gIHByaXZhdGUgX2RldGVybWluZVNpZGUoXG4gICAgc2VsZjogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LFxuICAgIGF2ZzogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LFxuICApOiBFRkNvbm5lY3RhYmxlU2lkZSB7XG4gICAgY29uc3QgZHggPSBhdmcueCAtIHNlbGYueDtcbiAgICBjb25zdCBkeSA9IGF2Zy55IC0gc2VsZi55O1xuICAgIGNvbnN0IHNuYXBFcHMgPSAyOyAvLyBweCDigJQgaHlzdGVyZXNpcyB0aHJlc2hvbGQgdG8gYXZvaWQgc2lkZS1mbGlwcGluZyBuZWFyIGRpYWdvbmFsc1xuXG4gICAgaWYgKE1hdGguYWJzKGR4KSAtIE1hdGguYWJzKGR5KSA+IHNuYXBFcHMpIHtcbiAgICAgIHJldHVybiBkeCA8IDAgPyBFRkNvbm5lY3RhYmxlU2lkZS5MRUZUIDogRUZDb25uZWN0YWJsZVNpZGUuUklHSFQ7XG4gICAgfVxuICAgIGlmIChNYXRoLmFicyhkeSkgLSBNYXRoLmFicyhkeCkgPiBzbmFwRXBzKSB7XG4gICAgICByZXR1cm4gZHkgPCAwID8gRUZDb25uZWN0YWJsZVNpZGUuVE9QIDogRUZDb25uZWN0YWJsZVNpZGUuQk9UVE9NO1xuICAgIH1cblxuICAgIC8vIFdoZW4gZGlmZmVyZW5jZXMgYXJlIG5lYXJseSBlcXVhbCwgcHJlZmVyIHZlcnRpY2FsIG9yaWVudGF0aW9uIGZvciBzdGFiaWxpdHlcbiAgICByZXR1cm4gZHkgPCAwID8gRUZDb25uZWN0YWJsZVNpZGUuVE9QIDogRUZDb25uZWN0YWJsZVNpZGUuQk9UVE9NO1xuICB9XG59XG4iXX0=
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2YtZmxvdy9zcmMvZG9tYWluL2Ytbm9kZS9jYWxjdWxhdGUtbm9kZS1jb25uZWN0b3JzLWNvbm5lY3RhYmxlLXNpZGVzL2NhbGN1bGF0ZS1jb25uZWN0YWJsZS1zaWRlLWJ5LWNvbm5lY3RlZC1wb3NpdGlvbnMvY2FsY3VsYXRlLWNvbm5lY3RhYmxlLXNpZGUtYnktY29ubmVjdGVkLXBvc2l0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFNBQVMsRUFBYyxNQUFNLGtCQUFrQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxtREFBbUQsRUFBRSxNQUFNLDZEQUE2RCxDQUFDO0FBQ2xJLE9BQU8sRUFBRSxpQkFBaUIsRUFBa0IsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxpREFBaUQsRUFBRSxNQUFNLG9EQUFvRCxDQUFDOztBQUV2SCxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFXbkIsTUFBTSxlQUFlLEdBQUc7SUFDdEIsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUM3QixpQkFBaUIsQ0FBQyxHQUFHO1FBQ3JCLGlCQUFpQixDQUFDLE1BQU07UUFDeEIsaUJBQWlCLENBQUMsSUFBSTtRQUN0QixpQkFBaUIsQ0FBQyxLQUFLO0tBQ3hCO0lBQ0QsQ0FBQyxpQkFBaUIsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLEtBQUssQ0FBQztJQUMzRixDQUFD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RnhELFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZFeGVjdXRpb25SZWdpc3RlciwgRk1lZGlhdG9yLCBJRXhlY3V0aW9uIH0gZnJvbSAnQGZvYmxleC9tZWRpYXRvcic7XG5pbXBvcnQgeyBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QgfSBmcm9tICcuL2NhbGN1bGF0ZS1jb25uZWN0YWJsZS1zaWRlLWJ5LWNvbm5lY3RlZC1wb3NpdGlvbnMtcmVxdWVzdCc7XG5pbXBvcnQgeyBFRkNvbm5lY3RhYmxlU2lkZSwgRkNvbm5lY3RvckJhc2UgfSBmcm9tICcuLi8uLi8uLi8uLi9mLWNvbm5lY3RvcnMnO1xuaW1wb3J0IHsgUmVjdEV4dGVuc2lvbnMgfSBmcm9tICdAZm9ibGV4LzJkJztcbmltcG9ydCB7IENhbGN1bGF0ZUNvbm5lY3RhYmxlU2lkZUJ5SW50ZXJuYWxQb3NpdGlvblJlcXVlc3QgfSBmcm9tICcuLi9jYWxjdWxhdGUtY29ubmVjdGFibGUtc2lkZS1ieS1pbnRlcm5hbC1wb3NpdGlvbic7XG5cbmNvbnN0IFNOQVBfRVBTID0gMjtcblxuY29uc3QgZW51bSBTaWRlTWFzayB7XG4gIE5PTkUgPSAwLFxuICBMRUZUID0gMSA8PCAwLFxuICBSSUdIVCA9IDEgPDwgMSxcbiAgVE9QID0gMSA8PCAyLFxuICBCT1RUT00gPSAxIDw8IDMsXG4gIEFMTCA9ICgxIDw8IDQpIC0gMSxcbn1cblxuY29uc3QgQ0FMQ1VMQVRFX1NJREVTID0ge1xuICBbRUZDb25uZWN0YWJsZVNpZGUuQ0FMQ1VMQVRFXTogW1xuICAgIEVGQ29ubmVjdGFibGVTaWRlLlRPUCxcbiAgICBFRkNvbm5lY3RhYmxlU2lkZS5CT1RUT00sXG4gICAgRUZDb25uZWN0YWJsZVNpZGUuTEVGVCxcbiAgICBFRkNvbm5lY3RhYmxlU2lkZS5SSUdIVCxcbiAgXSxcbiAgW0VGQ29ubmVjdGFibGVTaWRlLkNBTENVTEFURV9IT1JJWk9OVEFMXTogW0VGQ29ubmVjdGFibGVTaWRlLkxFRlQsIEVGQ29ubmVjdGFibGVTaWRlLlJJR0hUXSxcbiAgW0VGQ29ubmVjdGFibGVTaWRlLkNBTENVTEFURV9WRVJUSUNBTF06IFtFRkNvbm5lY3RhYmxlU2lkZS5UT1AsIEVGQ29ubmVjdGFibGVTaWRlLkJPVFRPTV0sXG59O1xuXG4vKipcbiAqIEV4ZWN1dGlvbiB0aGF0IGNhbGN1bGF0ZXMgdGhlIGNvbm5lY3RhYmxlIHNpZGUgZm9yIGEgY29ubmVjdG9yXG4gKiBiYXNlZCBvbiBwb3NpdGlvbnMgb2YgY29ubmVjdGVkIGNvbm5lY3RvcnMgYW5kIGFsbG93ZWQgc2lkZXMuXG4gKi9cbkBJbmplY3RhYmxlKClcbkBGRXhlY3V0aW9uUmVnaXN0ZXIoQ2FsY3VsYXRlQ29ubmVjdGFibGVTaWRlQnlDb25uZWN0ZWRQb3NpdGlvbnNSZXF1ZXN0KVxuZXhwb3J0IGNsYXNzIENhbGN1bGF0ZUNvbm5lY3RhYmxlU2lkZUJ5Q29ubmVjdGVkUG9zaXRpb25zXG4gIGltcGxlbWVudHMgSUV4ZWN1dGlvbjxDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QsIEVGQ29ubmVjdGFibGVTaWRlPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IF9tZWRpYXRvciA9IGluamVjdChGTWVkaWF0b3IpO1xuXG4gIC8qKlxuICAgKiBFbnRyeSBwb2ludCAoaG90IHBhdGgpLiBBdm9pZHMgaW50ZXJtZWRpYXRlIGFycmF5cyBhbmQgcmVkdW5kYW50IGFsbG9jYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWVzdCAtIENvbnRhaW5zIHRoZSBjb25uZWN0b3IgYW5kIG9wdGlvbmFsbHkgYWxsb3dlZCBzaWRlcy5cbiAgICogQHJldHVybnMge0VGQ29ubmVjdGFibGVTaWRlfSAtIFRoZSBjaG9zZW4gY29ubmVjdGFibGUgc2lkZS5cbiAgICovXG4gIHB1YmxpYyBoYW5kbGUoe1xuICAgIGNvbm5lY3RvcixcbiAgICBtb2RlLFxuICB9OiBDYWxjdWxhdGVDb25uZWN0YWJsZVNpZGVCeUNvbm5lY3RlZFBvc2l0aW9uc1JlcXVlc3QpOiBFRkNvbm5lY3RhYmxlU2lkZSB7XG4gICAgY29uc3Qgc2VsZkNlbnRlciA9IFJlY3RFeHRlbnNpb25zLmZyb21FbGVtZW50KGNvbm5lY3Rvci5ob3N0RWxlbWVudCkuZ3Jhdml0eUNlbnRlcjtcblxuICAgIGNvbnN0IGFjYyA9IHRoaXMuX2FjY3VtdWxhdGVDb25uZWN0ZWRDZW50ZXJzKGNvbm5lY3Rvci5ob3N0RWxlbWVudCwgY29ubmVjdG9yLnRvQ29ubmVjdG9yKTtcblxuICAgIGlmIChhY2MuY291bnQgPT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzLl9tZWRpYXRvci5leGVjdXRlKFxuICAgICAgICBuZXcgQ2FsY3VsYXRlQ29ubmVjdGFibGVTaWRlQnlJbnRlcm5hbFBvc2l0aW9uUmVxdWVzdChjb25uZWN0b3IpLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBhdmdYID0gYWNjLnN1bVggLyBhY2MuY291bnQ7XG4gICAgY29uc3QgYXZnWSA9IGFjYy5zdW1ZIC8gYWNjLmNvdW50O1xuXG4gICAgY29uc3QgbWFzayA9IHRoaXMuX3RvU2lkZU1hc2soQ0FMQ1VMQVRFX1NJREVTW21vZGVdKTtcblxuICAgIHJldHVybiB0aGlzLl9kZXRlcm1pbmVTaWRlKHNlbGZDZW50ZXIueCwgc2VsZkNlbnRlci55LCBhdmdYLCBhdmdZLCBtYXNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY2N1bXVsYXRlcyBzdW0gb2YgZ3Jhdml0eSBjZW50ZXJzIGFuZCBjb3VudCwgZXhjbHVkaW5nIHRoZSBjdXJyZW50IGhvc3QuXG4gICAqIFNpbmdsZSBwYXNzLCBtaW5pbWFsIGFsbG9jYXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBfYWNjdW11bGF0ZUNvbm5lY3RlZENlbnRlcnMoXG4gICAgc2VsZkhvc3Q6IEhUTUxFbGVtZW50IHwgU1ZHRWxlbWVudCxcbiAgICBjb25uZWN0ZWQ6IEZDb25uZWN0b3JCYXNlW10gfCBudWxsIHwgdW5kZWZpbmVkLFxuICApOiB7IHN1bVg6IG51bWJlcjsgc3VtWTogbnVtYmVyOyBjb3VudDogbnVtYmVyIH0ge1xuICAgIGxldCBzdW1YID0gMDtcbiAgICBsZXQgc3VtWSA9IDA7XG4gICAgbGV0IGNvdW50ID0gMDtcblxuICAgIGlmIChjb25uZWN0ZWQgJiYgY29ubmVjdGVkLmxlbmd0aCkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25uZWN0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZWwgPSBjb25uZWN0ZWRbaV0/Lmhvc3RFbGVtZW50IGFzIEhUTUxFbGVtZW50IHwgU1ZHRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFlbCB8fCBlbCA9PT0gc2VsZkhvc3QpIGNvbnRpbnVlO1xuXG4gICAgICAgIGNvbnN0IGMgPSBSZWN0RXh0ZW5zaW9ucy5mcm9tRWxlbWVudChlbCkuZ3Jhdml0eUNlbnRlcjtcbiAgICAgICAgc3VtWCArPSBjLng7XG4gICAgICAgIHN1bVkgKz0gYy55O1xuICAgICAgICBjb3VudCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHN1bVgsIHN1bVksIGNvdW50IH07XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYWxsb3dlZCBzaWRlcyBhcnJheSB0byBhIGNvbXBhY3QgYml0IG1hc2suXG4gICAqIElmIG5vdCBwcm92aWRlZCBvciBlbXB0eSAtPiBhbGwgc2lkZXMgYWxsb3dlZC5cbiAgICovXG4gIHByaXZhdGUgX3RvU2lkZU1hc2soYWxsb3dlZD86IEVGQ29ubmVjdGFibGVTaWRlW10pOiBTaWRlTWFzayB7XG4gICAgaWYgKCFhbGxvd2VkIHx8IGFsbG93ZWQubGVuZ3RoID09PSAwKSByZXR1cm4gU2lkZU1hc2suQUxMO1xuXG4gICAgbGV0IG1hc2sgPSBTaWRlTWFzay5OT05FO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWxsb3dlZC5sZW5ndGg7IGkrKykge1xuICAgICAgc3dpdGNoIChhbGxvd2VkW2ldKSB7XG4gICAgICAgIGNhc2UgRUZDb25uZWN0YWJsZVNpZGUuTEVGVDpcbiAgICAgICAgICBtYXNrIHw9IFNpZGVNYXNrLkxFRlQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgRUZDb25uZWN0YWJsZVNpZGUuUklHSFQ6XG4gICAgICAgICAgbWFzayB8PSBTaWRlTWFzay5SSUdIVDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBFRkNvbm5lY3RhYmxlU2lkZS5UT1A6XG4gICAgICAgICAgbWFzayB8PSBTaWRlTWFzay5UT1A7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgRUZDb25uZWN0YWJsZVNpZGUuQk9UVE9NOlxuICAgICAgICAgIG1hc2sgfD0gU2lkZU1hc2suQk9UVE9NO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtYXNrIHx8IFNpZGVNYXNrLkFMTDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGZpbmFsIHNpZGUgdXNpbmcgaWRlYWwgc2lkZSBmaXJzdDsgaWYgZGlzYWxsb3dlZCwgcGlja3MgYmVzdCBmYWxsYmFjay5cbiAgICogSW5wdXRzIGFyZSBudW1iZXJzIHRvIGF2b2lkIG9iamVjdCB3cmFwcGVycyBvbiBob3QgcGF0aC5cbiAgICovXG4gIHByaXZhdGUgX2RldGVybWluZVNpZGUoXG4gICAgc2VsZlg6IG51bWJlcixcbiAgICBzZWxmWTogbnVtYmVyLFxuICAgIGF2Z1g6IG51bWJlcixcbiAgICBhdmdZOiBudW1iZXIsXG4gICAgYWxsb3dlZE1hc2s6IFNpZGVNYXNrLFxuICApOiBFRkNvbm5lY3RhYmxlU2lkZSB7XG4gICAgY29uc3QgZHggPSBhdmdYIC0gc2VsZlg7XG4gICAgY29uc3QgZHkgPSBhdmdZIC0gc2VsZlk7XG5cbiAgICBjb25zdCBpZGVhbCA9IHRoaXMuX3BpY2tJZGVhbFNpZGUoZHgsIGR5KTtcblxuICAgIGlmICh0aGlzLl9pc0FsbG93ZWQoaWRlYWwsIGFsbG93ZWRNYXNrKSkge1xuICAgICAgcmV0dXJuIGlkZWFsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9waWNrRmFsbGJhY2tTaWRlKGR4LCBkeSwgYWxsb3dlZE1hc2ssIGlkZWFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQaWNrcyB0aGUgXCJpZGVhbFwiIHNpZGUgYmFzZWQgb24gdmVjdG9yIChkeCwgZHkpIHdpdGggaHlzdGVyZXNpcy5cbiAgICovXG4gIHByaXZhdGUgX3BpY2tJZGVhbFNpZGUoZHg6IG51bWJlciwgZHk6IG51bWJlcik6IEVGQ29ubmVjdGFibGVTaWRlIHtcbiAgICBjb25zdCBheCA9IGR4IDwgMCA/IC1keCA6IGR4O1xuICAgIGNvbnN0IGF5ID0gZHkgPCAwID8gLWR5IDogZHk7XG5cbiAgICBpZiAoYXggLSBheSA+IFNOQVBfRVBTKSB7XG4gICAgICByZXR1cm4gZHggPCAwID8gRUZDb25uZWN0YWJsZVNpZGUuTEVGVCA6IEVGQ29ubmVjdGFibGVTaWRlLlJJR0hUO1xuICAgIH1cbiAgICBpZiAoYXkgLSBheCA+IFNOQVBfRVBTKSB7XG4gICAgICByZXR1cm4gZHkgPCAwID8gRUZDb25uZWN0YWJsZVNpZGUuVE9QIDogRUZDb25uZWN0YWJsZVNpZGUuQk9UVE9NO1xuICAgIH1cblxuICAgIHJldHVybiBkeSA8IDAgPyBFRkNvbm5lY3RhYmxlU2lkZS5UT1AgOiBFRkNvbm5lY3RhYmxlU2lkZS5CT1RUT007XG4gIH1cblxuICAvKipcbiAgICogUXVpY2sgbWVtYmVyc2hpcCBjaGVjayB2aWEgYml0IG1hc2suXG4gICAqL1xuICBwcml2YXRlIF9pc0FsbG93ZWQoc2lkZTogRUZDb25uZWN0YWJsZVNpZGUsIG1hc2s6IFNpZGVNYXNrKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChzaWRlKSB7XG4gICAgICBjYXNlIEVGQ29ubmVjdGFibGVTaWRlLkxFRlQ6XG4gICAgICAgIHJldHVybiAobWFzayAmIFNpZGVNYXNrLkxFRlQpICE9PSAwO1xuICAgICAgY2FzZSBFRkNvbm5lY3RhYmxlU2lkZS5SSUdIVDpcbiAgICAgICAgcmV0dXJuIChtYXNrICYgU2lkZU1hc2suUklHSFQpICE9PSAwO1xuICAgICAgY2FzZSBFRkNvbm5lY3RhYmxlU2lkZS5UT1A6XG4gICAgICAgIHJldHVybiAobWFzayAmIFNpZGVNYXNrLlRPUCkgIT09IDA7XG4gICAgICBjYXNlIEVGQ29ubmVjdGFibGVTaWRlLkJPVFRPTTpcbiAgICAgICAgcmV0dXJuIChtYXNrICYgU2lkZU1hc2suQk9UVE9NKSAhPT0gMDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQaWNrcyB0aGUgYmVzdCBhdmFpbGFibGUgc2lkZSBmcm9tIGFsbG93ZWQgbWFzayBieSBtYXhpbWl6aW5nIGRpcmVjdGlvbmFsIHNjb3JlLlxuICAgKiBObyBpbnRlcm1lZGlhdGUgb2JqZWN0cywgY29uc3RhbnQtdGltZSBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBfcGlja0ZhbGxiYWNrU2lkZShcbiAgICBkeDogbnVtYmVyLFxuICAgIGR5OiBudW1iZXIsXG4gICAgYWxsb3dlZE1hc2s6IFNpZGVNYXNrLFxuICAgIGlkZWFsOiBFRkNvbm5lY3RhYmxlU2lkZSxcbiAgKTogRUZDb25uZWN0YWJsZVNpZGUge1xuICAgIGxldCBiZXN0U2lkZTogRUZDb25uZWN0YWJsZVNpZGUgPSBpZGVhbDtcbiAgICBsZXQgYmVzdFNjb3JlID0gLUluZmluaXR5O1xuXG4gICAgaWYgKGFsbG93ZWRNYXNrICYgU2lkZU1hc2suUklHSFQpIHtcbiAgICAgIGNvbnN0IHMgPSBkeDtcbiAgICAgIGlmIChzID4gYmVzdFNjb3JlKSB7XG4gICAgICAgIGJlc3RTY29yZSA9IHM7XG4gICAgICAgIGJlc3RTaWRlID0gRUZDb25uZWN0YWJsZVNpZGUuUklHSFQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChhbGxvd2VkTWFzayAmIFNpZGVNYXNrLkxFRlQpIHtcbiAgICAgIGNvbnN0IHMgPSAtZHg7XG4gICAgICBpZiAocyA+IGJlc3RTY29yZSkge1xuICAgICAgICBiZXN0U2NvcmUgPSBzO1xuICAgICAgICBiZXN0U2lkZSA9IEVGQ29ubmVjdGFibGVTaWRlLkxFRlQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChhbGxvd2VkTWFzayAmIFNpZGVNYXNrLkJPVFRPTSkge1xuICAgICAgY29uc3QgcyA9IGR5O1xuICAgICAgaWYgKHMgPiBiZXN0U2NvcmUpIHtcbiAgICAgICAgYmVzdFNjb3JlID0gcztcbiAgICAgICAgYmVzdFNpZGUgPSBFRkNvbm5lY3RhYmxlU2lkZS5CT1RUT007XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChhbGxvd2VkTWFzayAmIFNpZGVNYXNrLlRPUCkge1xuICAgICAgY29uc3QgcyA9IC1keTtcbiAgICAgIGlmIChzID4gYmVzdFNjb3JlKSB7XG4gICAgICAgIGJlc3RTY29yZSA9IHM7XG4gICAgICAgIGJlc3RTaWRlID0gRUZDb25uZWN0YWJsZVNpZGUuVE9QO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBiZXN0U2lkZTtcbiAgfVxufVxuIl19