"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.visitBipartiteIterableTreeWithState = exports.visitBipartiteIterableTree = exports.visitIterableTreeWithState = exports.visitIterableTree = exports.Skip = void 0;
exports.Skip = Symbol("Skip");
/**
 * Visit iterable tree.
 *
 * @remarks
 * Non-recursive depth first traversal.
 */
function visitIterableTree(root, visitor) {
    const queue = [[root]];
    let next;
    while ((next = queue.pop())) {
        for (const child of next) {
            if (visitor(child) !== exports.Skip) {
                queue.push(child);
            }
        }
    }
}
exports.visitIterableTree = visitIterableTree;
/**
 * Visit iterable tree.
 * Allows state to be computed in parents and passed to children.
 *
 * @remarks
 * Non-recursive depth first traversal.
 */
function visitIterableTreeWithState(root, initial, visitor) {
    const queue = [[initial, root]];
    let next;
    while ((next = queue.pop())) {
        const [state, nestItem] = next;
        for (const child of nestItem) {
            const result = visitor(child, state);
            if (result !== exports.Skip) {
                queue.push([result, child]);
            }
        }
    }
}
exports.visitIterableTreeWithState = visitIterableTreeWithState;
/**
 * Visit bipartite iterable tree.
 *
 * @remarks
 * Non-recursive depth first traversal.
 *
 * Particularly useful for processing trees with their alternating node and field levels.
 */
function visitBipartiteIterableTree(root, visitorA, visitorB) {
    const queueA = [root];
    let nextA;
    while ((nextA = queueA.pop())) {
        if (visitorA(nextA) !== exports.Skip) {
            for (const nextB of nextA) {
                if (visitorB(nextB) !== exports.Skip) {
                    for (const child of nextB) {
                        queueA.push(child);
                    }
                }
            }
        }
    }
}
exports.visitBipartiteIterableTree = visitBipartiteIterableTree;
/**
 * Visit bipartite iterable tree.
 * Allows state to be computed in parents and passed to children.
 *
 * @remarks
 * Non-recursive depth first traversal.
 *
 * Particularly useful for processing trees with their alternating node and field levels.
 *
 * @privateRemarks
 * Other traversal cases, like ones passing data up (via map or reduce patterns) could be supported by extending this or adding more utilities.
 * Such utility functions really only provide an improvement of hand coding each cases if the non-recessiveness is required.
 * Since supporting very deeps trees hasn't been a priority, such visitors are also not a priority, and are thus not included here for now.
 */
function visitBipartiteIterableTreeWithState(root, fromAbove, visitorA, visitorB) {
    const queueA = [[root, fromAbove]];
    let next;
    while ((next = queueA.pop())) {
        const result = visitorA(...next);
        if (result !== exports.Skip) {
            for (const nextB of next[0]) {
                const resultB = visitorB(nextB, result);
                if (resultB !== exports.Skip) {
                    for (const child of nextB) {
                        queueA.push([child, resultB]);
                    }
                }
            }
        }
    }
}
exports.visitBipartiteIterableTreeWithState = visitBipartiteIterableTreeWithState;
//# sourceMappingURL=navigation.js.map