import { StepInfoNode } from "../model/tactic/Tactic" export function addStepNode( root: StepInfoNode, parent: StepInfoNode, child: StepInfoNode, ): StepInfoNode { if (root.id === parent.id) { return { ...root, children: root.children.concat(child), } } return { ...root, children: root.children.map((c) => addStepNode(c, parent, child)), } } export function getStepName(root: StepInfoNode, step: number): string { let ord = 1 const nodes = [root] while (nodes.length > 0) { const node = nodes.pop()! if (node.id === step) break ord++ nodes.push(...[...node.children].reverse()) } return ord.toString() } export function getStepNode( root: StepInfoNode, stepId: number, ): StepInfoNode | undefined { if (root.id === stepId) return root for (const child of root.children) { const result = getStepNode(child, stepId) if (result) return result } } export function removeStepNode( root: StepInfoNode, targetId: number, ): StepInfoNode | undefined { const path = getPathTo(root, targetId) path.reverse() const [removedNode, ...pathToRoot] = path let child = removedNode for (const node of pathToRoot) { child = { id: node.id, children: node.children.flatMap((c) => { if (c.id === removedNode.id) return [] else if (c.id === child.id) { return [child] } return [c] }), } } return child } export function getPathTo( root: StepInfoNode, targetId: number, ): StepInfoNode[] { if (root.id === targetId) return [root] for (const child of root.children) { const subPath = getPathTo(child, targetId) if (subPath.length > 0) return [root, ...subPath] } return [] } /** * Returns an available identifier that is not already present into the given node tree * @param root */ export function getAvailableId(root: StepInfoNode): number { const acc = (root: StepInfoNode): number => Math.max(root.id, ...root.children.map(acc)) return acc(root) + 1 } export function getParent( root: StepInfoNode, node: StepInfoNode, ): StepInfoNode | null { if (root.children.find((n) => n.id === node.id)) return root for (const child of root.children) { const result = getParent(child, node) if (result != null) { return result } } return null }