{
  "definitions": [
    {
      "callable": true,
      "callees": [],
      "callers": [
        {
          "file": "domain/converters/learning.converter.ts",
          "name": "layoutLearning",
          "source": {
            "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-converter-ts",
            "json": "https://banes-lab.com/json/source/tree/domain/converters/learning.converter.ts",
            "label": "domain/converters/learning.converter.ts",
            "markdown": "https://banes-lab.com/source/tree/domain/converters/learning.converter.ts.md",
            "ref": "anatomy:file-domain-converters-learning-converter-ts"
          }
        }
      ],
      "exported": false,
      "flow": "leaf",
      "kind": "lexical_declaration",
      "line": 114,
      "name": "placeStops",
      "signature": "const placeStops = function placeStops(block: Sized, x: number, y: number, flipped: boolean): readonly LaidStop[] {"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [
        {
          "file": "domain/converters/learning.converter.ts",
          "name": "layoutLearning",
          "source": {
            "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-converter-ts",
            "json": "https://banes-lab.com/json/source/tree/domain/converters/learning.converter.ts",
            "label": "domain/converters/learning.converter.ts",
            "markdown": "https://banes-lab.com/source/tree/domain/converters/learning.converter.ts.md",
            "ref": "anatomy:file-domain-converters-learning-converter-ts"
          }
        }
      ],
      "exported": false,
      "flow": "leaf",
      "kind": "lexical_declaration",
      "line": 131,
      "name": "shiftBlock",
      "signature": "const shiftBlock = function shiftBlock(block: LaidBlock, dx: number, dy: number): LaidBlock {"
    },
    {
      "callable": true,
      "callees": [
        {
          "file": "domain/converters/learning.converter.ts",
          "name": "placeStops",
          "source": {
            "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-converter-ts",
            "json": "https://banes-lab.com/json/source/tree/domain/converters/learning.converter.ts",
            "label": "domain/converters/learning.converter.ts",
            "markdown": "https://banes-lab.com/source/tree/domain/converters/learning.converter.ts.md",
            "ref": "anatomy:file-domain-converters-learning-converter-ts"
          }
        },
        {
          "file": "domain/converters/learning.converter.ts",
          "name": "shiftBlock",
          "source": {
            "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-converter-ts",
            "json": "https://banes-lab.com/json/source/tree/domain/converters/learning.converter.ts",
            "label": "domain/converters/learning.converter.ts",
            "markdown": "https://banes-lab.com/source/tree/domain/converters/learning.converter.ts.md",
            "ref": "anatomy:file-domain-converters-learning-converter-ts"
          }
        }
      ],
      "callers": [],
      "exported": true,
      "flow": "entry",
      "kind": "lexical_declaration",
      "line": 156,
      "name": "layoutLearning",
      "signature": "export const layoutLearning = function layoutLearning(blocks: readonly LearningBlock[]): LearningModel {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "interface_declaration",
      "line": 17,
      "name": "Sized",
      "signature": "interface Sized {"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 28,
      "name": "wrapLabel",
      "signature": "const wrapLabel = function wrapLabel(text: string): readonly string[] {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 30,
      "name": "row",
      "signature": "let row = \"\";"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 47,
      "name": "widthOf",
      "signature": "export const widthOf = function widthOf(rows: readonly string[]): number {"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 51,
      "name": "sizeBlock",
      "signature": "const sizeBlock = function sizeBlock(block: LearningBlock): Sized {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 52,
      "name": "measured",
      "signature": "const measured = block.stops.map((stop) => {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 53,
      "name": "rows",
      "signature": "const rows = wrapLabel(stop.label);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 67,
      "name": "widest",
      "signature": "const widest = measured.reduce((held, stop) => Math.max(held, stop.width), widthOf([block.label]) + PAD_X * 2);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 68,
      "name": "stops",
      "signature": "const stops = measured.map((stop) => ({ ...stop, width: widest }));"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 69,
      "name": "stacked",
      "signature": "const stacked = stops.reduce((held, stop) => held + stop.height + NODE_GAP, BLOCK_HEAD + BLOCK_PAD);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 70,
      "name": "link",
      "signature": "const link = linkFor(block.owner);"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 83,
      "name": "cellOf",
      "signature": "const cellOf = function cellOf(index: number, side: number): { readonly x: number; readonly y: number } {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 86,
      "name": "rest",
      "signature": "let rest = index;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 87,
      "name": "step",
      "signature": "for (let step = 1; step < side; step *= 2) {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 88,
      "name": "rx",
      "signature": "const rx = 1 & Math.floor(rest / 2);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 89,
      "name": "ry",
      "signature": "const ry = 1 & (rest ^ rx);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 95,
      "name": "swap",
      "signature": "const swap = x;"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 106,
      "name": "sideFor",
      "signature": "const sideFor = function sideFor(count: number): number {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 115,
      "name": "order",
      "signature": "const order = flipped ? [...block.stops].reverse() : block.stops;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 116,
      "name": "inner",
      "signature": "let inner = y + BLOCK_HEAD + BLOCK_PAD;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 118,
      "name": "laid",
      "signature": "const laid = {"
    },
    {
      "callable": true,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 148,
      "name": "entryY",
      "signature": "const entryY = function entryY(before: LaidBlock | undefined, block: Sized, x: number, cy: number): number {"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": false,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 152,
      "name": "aside",
      "signature": "const aside = x >= before.x + before.width || x + block.width <= before.x;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 157,
      "name": "sized",
      "signature": "const sized = blocks.map(sizeBlock);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 158,
      "name": "cell",
      "signature": "const cell = sized.reduce((held, block) => Math.max(held, block.width, block.height), 0) + SIDE_GAP;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 159,
      "name": "side",
      "signature": "const side = sideFor(sized.length);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 160,
      "name": "placed",
      "signature": "const placed: LaidBlock[] = [];"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 162,
      "name": "spot",
      "signature": "const spot = cellOf(index, side);"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 163,
      "name": "cx",
      "signature": "const cx = spot.x * cell + cell / 2;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 164,
      "name": "cy",
      "signature": "const cy = spot.y * cell + cell / 2;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 165,
      "name": "x",
      "signature": "const x = cx - block.width / 2;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 166,
      "name": "y",
      "signature": "const y = cy - block.height / 2;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 167,
      "name": "flipped",
      "signature": "const flipped = entryY(placed.at(-1), block, x, cy) > cy;"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 170,
      "name": "left",
      "signature": "const left = Math.min(...placed.map((block) => block.x));"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 171,
      "name": "top",
      "signature": "const top = Math.min(...placed.map((block) => block.y));"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 172,
      "name": "right",
      "signature": "const right = Math.max(...placed.map((block) => block.x + block.width));"
    },
    {
      "callable": false,
      "callees": [],
      "callers": [],
      "exported": true,
      "flow": "isolated",
      "kind": "lexical_declaration",
      "line": 173,
      "name": "bottom",
      "signature": "const bottom = Math.max(...placed.map((block) => block.y + block.height));"
    }
  ],
  "document": null,
  "findings": [],
  "generated": false,
  "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-converter-ts",
  "language": "typescript",
  "layer": "processing",
  "name": "learning.converter.ts",
  "path": "domain/converters/learning.converter.ts",
  "ref": "anatomy:file-domain-converters-learning-converter-ts",
  "relations": [
    {
      "links": [
        {
          "href": "https://banes-lab.com/anatomy/tree#folder-domain-converters",
          "json": "https://banes-lab.com/json/anatomy/tree/folder-domain-converters",
          "label": "domain/converters",
          "markdown": "https://banes-lab.com/anatomy/tree/folder-domain-converters.md",
          "ref": "chapter:/anatomy/tree#folder-domain-converters"
        }
      ],
      "relation": "contained-in"
    },
    {
      "links": [
        {
          "href": "https://banes-lab.com/anatomy/tree#folder-domain-converters",
          "json": "https://banes-lab.com/json/anatomy/tree/folder-domain-converters",
          "label": "domain/converters",
          "markdown": "https://banes-lab.com/anatomy/tree/folder-domain-converters.md",
          "ref": "chapter:/anatomy/tree#folder-domain-converters"
        }
      ],
      "relation": "linked-from"
    }
  ],
  "slots": {
    "concern": "converter",
    "subject": "learning",
    "variant": null
  },
  "stats": {
    "bytes": 5782,
    "callable": 9,
    "definitions": 40,
    "edges": 2,
    "exported": 16,
    "files": 1,
    "findings": {},
    "flows": {
      "leaf": 2,
      "entry": 1,
      "isolated": 37
    },
    "lines": {
      "blank": 10,
      "code": 169,
      "total": 179
    }
  },
  "summary": "169 lines of code and 40 definitions.",
  "text": "https://banes-lab.com/source/tree/domain/converters/learning.converter.ts.txt",
  "tree": "tree",
  "siblings": {
    "next": {
      "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-learning-fragment-converter-ts",
      "json": "https://banes-lab.com/json/source/tree/domain/converters/learning.fragment.converter.ts",
      "label": "domain/converters/learning.fragment.converter.ts",
      "markdown": "https://banes-lab.com/source/tree/domain/converters/learning.fragment.converter.ts.md",
      "ref": "anatomy:file-domain-converters-learning-fragment-converter-ts"
    },
    "previous": {
      "href": "https://banes-lab.com/anatomy/tree#file-domain-converters-kind-converter-ts",
      "json": "https://banes-lab.com/json/source/tree/domain/converters/kind.converter.ts",
      "label": "domain/converters/kind.converter.ts",
      "markdown": "https://banes-lab.com/source/tree/domain/converters/kind.converter.ts.md",
      "ref": "anatomy:file-domain-converters-kind-converter-ts"
    }
  },
  "up": {
    "href": null,
    "json": "https://banes-lab.com/json/api/source/tree/domain/converters",
    "label": "domain/converters",
    "markdown": "https://banes-lab.com/api/source/tree/domain/converters.md",
    "ref": "api:source/tree/domain/converters"
  }
}
