{
  "name": "lazer",
  "patches": {
    "@/00-lazer-shot": {
      "links": {
        "B1NtYfXK8": {
          "id": "B1NtYfXK8",
          "input": {
            "nodeId": "rkPOYz7YU",
            "pinKey": "SJDbf_YUV"
          },
          "output": {
            "nodeId": "ryqBYMmtL",
            "pinKey": "r1DL6CFU4"
          }
        },
        "B1Qe7JXSI": {
          "id": "B1Qe7JXSI",
          "input": {
            "nodeId": "SJgcQsafrU",
            "pinKey": "SJDbf_YUV"
          },
          "output": {
            "nodeId": "rJAJXyQBL",
            "pinKey": "HJDI8YYUN"
          }
        },
        "B1Qf46fQFL": {
          "id": "B1Qf46fQFL",
          "input": {
            "nodeId": "H1WGNTfQtL",
            "pinKey": "SJDbf_YUV"
          },
          "output": {
            "nodeId": "BkMGVazmYI",
            "pinKey": "rylSGPt8E"
          }
        },
        "B1Rd7QmFI": {
          "id": "B1Rd7QmFI",
          "input": {
            "nodeId": "ryqBYMmtL",
            "pinKey": "B11QT1qLN"
          },
          "output": {
            "nodeId": "H1WGNTfQtL",
            "pinKey": "BkPGzdFI4"
          }
        },
        "BJMxXy7r8": {
          "id": "BJMxXy7r8",
          "input": {
            "nodeId": "rJAJXyQBL",
            "pinKey": "Skj7ItY8V"
          },
          "output": {
            "nodeId": "By5msaMBI",
            "pinKey": "rylSGPt8E"
          }
        },
        "BJa__G7K8": {
          "id": "BJa__G7K8",
          "input": {
            "nodeId": "ryO9DGQKL",
            "pinKey": "rJg00Nhe-"
          },
          "output": {
            "nodeId": "Syu_ufmKU",
            "pinKey": "SyBtREhlW"
          }
        },
        "BJyiI7mFL": {
          "id": "BJyiI7mFL",
          "input": {
            "nodeId": "HJ4srXmKI",
            "pinKey": "BJ3X9hAXE"
          },
          "output": {
            "nodeId": "BySCr7XKU",
            "pinKey": "rkV5H2XkE"
          }
        },
        "BkA5Qs6MHL": {
          "id": "BkA5Qs6MHL",
          "input": {
            "nodeId": "BkSqQoaMHL",
            "pinKey": "r1H7MwK8E"
          },
          "output": {
            "nodeId": "BJ4c7s6GH8",
            "pinKey": "Bk4gU0drwJ-"
          }
        },
        "BkHgXi9FL": {
          "id": "BkHgXi9FL",
          "input": {
            "nodeId": "BySCr7XKU",
            "pinKey": "B1GhbmCDX"
          },
          "output": {
            "nodeId": "BkblQsqtL",
            "pinKey": "HJeaTzjcKU"
          }
        },
        "Bkj8DmmF8": {
          "id": "Bkj8DmmF8",
          "input": {
            "nodeId": "H1qiozmtI",
            "pinKey": "BkXo6sVbN"
          },
          "output": {
            "nodeId": "Hk88DQXYL",
            "pinKey": "rkV5H2XkE"
          }
        },
        "BkoRoMQY8": {
          "id": "BkoRoMQY8",
          "input": {
            "nodeId": "r1C-cGmt8",
            "pinKey": "BJ3X9hAXE"
          },
          "output": {
            "nodeId": "rkjwsMXtI",
            "pinKey": "Bkzec3074"
          }
        },
        "ByASYf7KU": {
          "id": "ByASYf7KU",
          "input": {
            "nodeId": "ryqBYMmtL",
            "pinKey": "S1gH6CKIN"
          },
          "output": {
            "nodeId": "BJERHfmYU",
            "pinKey": "SJl_mc7yV"
          }
        },
        "ByHzNTfQtU": {
          "id": "ByHzNTfQtU",
          "input": {
            "nodeId": "BkMGVazmYI",
            "pinKey": "S1mxGvKUN"
          },
          "output": {
            "nodeId": "BJG46f7FI",
            "pinKey": "__out__"
          }
        },
        "ByeeitMXKL": {
          "id": "ByeeitMXKL",
          "input": {
            "nodeId": "ryqBYMmtL",
            "pinKey": "HJIQ6AY8E"
          },
          "output": {
            "nodeId": "HyxjtfmtL",
            "pinKey": "__out__"
          }
        },
        "H1NGNaMmtL": {
          "id": "H1NGNaMmtL",
          "input": {
            "nodeId": "H1WGNTfQtL",
            "pinKey": "Sy6LZuYIE"
          },
          "output": {
            "nodeId": "HklGEafQYU",
            "pinKey": "__out__"
          }
        },
        "H1fPrXXQY8": {
          "id": "H1fPrXXQY8",
          "input": {
            "nodeId": "HkUXXmXtU",
            "pinKey": "ByU7LRuSPkW"
          },
          "output": {
            "nodeId": "rJ-PHmmXt8",
            "pinKey": "__out__"
          }
        },
        "HJWh8X7FL": {
          "id": "HJWh8X7FL",
          "input": {
            "nodeId": "Hy_lB7QKI",
            "pinKey": "BJ3X9hAXE"
          },
          "output": {
            "nodeId": "BJOIU7XFU",
            "pinKey": "rkV5H2XkE"
          }
        },
        "HJeU7MYcvU": {
          "id": "HJeU7MYcvU",
          "input": {
            "nodeId": "B1W9QsTzSL",
            "pinKey": "r1n7kPYIN"
          },
          "output": {
            "nodeId": "rkUXztqPL",
            "pinKey": "__out__"
          }
        },
        "HJt97jTGHI": {
          "id": "HJt97jTGHI",
          "input": {
            "nodeId": "By5msaMBI",
            "pinKey": "r1H7MwK8E"
          },
          "output": {
            "nodeId": "B1W9QsTzSL",
            "pinKey": "SJricUK8V"
          }
        },
        "Hk113z7tI": {
          "id": "Hk113z7tI",
          "input": {
            "nodeId": "r1C-cGmt8",
            "pinKey": "BJn2q3CQ4-$1"
          },
          "output": {
            "nodeId": "H1qiozmtI",
            "pinKey": "Bkzec3074"
          }
        },
        "HkOgEXmKL": {
          "id": "HkOgEXmKL",
          "input": {
            "nodeId": "HkIeNXmKU",
            "pinKey": "ByU7LRuSPkW"
          },
          "output": {
            "nodeId": "HkUXXmXtU",
            "pinKey": "ByHmL0uHPk-"
          }
        },
        "HklAxfFqw8": {
          "id": "HklAxfFqw8",
          "input": {
            "nodeId": "By5msaMBI",
            "pinKey": "S1mxGvKUN"
          },
          "output": {
            "nodeId": "By0eMYcvI",
            "pinKey": "__out__"
          }
        },
        "Hy7xYM7t8": {
          "id": "Hy7xYM7t8",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "rktQN2FZN"
          },
          "output": {
            "nodeId": "BJz-OGmFL",
            "pinKey": "HktZUCdrPkZ"
          }
        },
        "HyBs8XQYU": {
          "id": "HyBs8XQYU",
          "input": {
            "nodeId": "HJ4srXmKI",
            "pinKey": "BJn2q3CQ4"
          },
          "output": {
            "nodeId": "S1HfLmmK8",
            "pinKey": "rkV5H2XkE"
          }
        },
        "Hyg_MMKqPU": {
          "id": "Hyg_MMKqPU",
          "input": {
            "nodeId": "B1IcQspfrI",
            "pinKey": "Sy6LZuYIE"
          },
          "output": {
            "nodeId": "ByOGzYqDL",
            "pinKey": "__out__"
          }
        },
        "S19C_GQYL": {
          "id": "S19C_GQYL",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "HkEhLHLJE"
          },
          "output": {
            "nodeId": "BJoMuzQtL",
            "pinKey": "HktZUCdrPkZ"
          }
        },
        "S1_HdfQFL": {
          "id": "S1_HdfQFL",
          "input": {
            "nodeId": "Hky9PzmKI",
            "pinKey": "rJg00Nhe-"
          },
          "output": {
            "nodeId": "HkgdwfXt8",
            "pinKey": "SyBtREhlW"
          }
        },
        "S1cH_GmYU": {
          "id": "S1cH_GmYU",
          "input": {
            "nodeId": "BJoMuzQtL",
            "pinKey": "HJjZLRdBw1-"
          },
          "output": {
            "nodeId": "HkgdwfXt8",
            "pinKey": "SyBtREhlW"
          }
        },
        "S1eg5mj6fH8": {
          "id": "S1eg5mj6fH8",
          "input": {
            "nodeId": "B1IcQspfrI",
            "pinKey": "SJDbf_YUV"
          },
          "output": {
            "nodeId": "BkSqQoaMHL",
            "pinKey": "rylSGPt8E"
          }
        },
        "SJ7GcfQKI": {
          "id": "SJ7GcfQKI",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "rk7w8SIkN"
          },
          "output": {
            "nodeId": "r1C-cGmt8",
            "pinKey": "SJVu9h0XV"
          }
        },
        "SJgD4zt5w8": {
          "id": "SJgD4zt5w8",
          "input": {
            "nodeId": "BkSqQoaMHL",
            "pinKey": "S1mxGvKUN"
          },
          "output": {
            "nodeId": "HJwVGK9vI",
            "pinKey": "__out__"
          }
        },
        "SJlktfmKL": {
          "id": "SJlktfmKL",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "rytiIB8kE"
          },
          "output": {
            "nodeId": "Hky9PzmKI",
            "pinKey": "B19RYS3lW"
          }
        },
        "SJxHNV7Xt8": {
          "id": "SJxHNV7Xt8",
          "input": {
            "nodeId": "BkSN4m7KL",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "B1IcQspfrI",
            "pinKey": "BkPGzdFI4"
          }
        },
        "SJyhBXmKU": {
          "id": "SJyhBXmKU",
          "input": {
            "nodeId": "rkjwsMXtI",
            "pinKey": "BkXo6sVbN"
          },
          "output": {
            "nodeId": "HJ4srXmKI",
            "pinKey": "SJVu9h0XV"
          }
        },
        "Sk3jUQQKU": {
          "id": "Sk3jUQQKU",
          "input": {
            "nodeId": "HJ4srXmKI",
            "pinKey": "BJn2q3CQ4-$2"
          },
          "output": {
            "nodeId": "HJsV8XXKL",
            "pinKey": "rkV5H2XkE"
          }
        },
        "SkJY_G7YU": {
          "id": "SkJY_G7YU",
          "input": {
            "nodeId": "BJz-OGmFL",
            "pinKey": "HJjZLRdBw1-"
          },
          "output": {
            "nodeId": "Syu_ufmKU",
            "pinKey": "SyBtREhlW"
          }
        },
        "Skeda-tqPI": {
          "id": "Skeda-tqPI",
          "input": {
            "nodeId": "HJd6-FcPL",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "H1MqQj6MSU",
            "pinKey": "ryH6tSt8N"
          }
        },
        "SkqiIX7YU": {
          "id": "SkqiIX7YU",
          "input": {
            "nodeId": "HJ4srXmKI",
            "pinKey": "BJn2q3CQ4-$1"
          },
          "output": {
            "nodeId": "By1EI7mtU",
            "pinKey": "rkV5H2XkE"
          }
        },
        "SkxwUfmt8": {
          "id": "SkxwUfmt8",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "Bk22ISLyV"
          },
          "output": {
            "nodeId": "SyMIUz7K8",
            "pinKey": "BJ--G1tI-"
          }
        },
        "SyMVBXQmYL": {
          "id": "SyMVBXQmYL",
          "input": {
            "nodeId": "HkUXXmXtU",
            "pinKey": "ryv7IRdSP1b"
          },
          "output": {
            "nodeId": "SkbVBmXmt8",
            "pinKey": "__out__"
          }
        },
        "SygES7mXtU": {
          "id": "SygES7mXtU",
          "input": {
            "nodeId": "H1VB77QtU",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "HkgdwfXt8",
            "pinKey": "BkGpcpcJQ"
          }
        },
        "r1HnImmFL": {
          "id": "r1HnImmFL",
          "input": {
            "nodeId": "Hy_lB7QKI",
            "pinKey": "BJn2q3CQ4-$1"
          },
          "output": {
            "nodeId": "rJZYIm7KU",
            "pinKey": "rkV5H2XkE"
          }
        },
        "r1lR5KG7KI": {
          "id": "r1lR5KG7KI",
          "input": {
            "nodeId": "rkPOYz7YU",
            "pinKey": "Sy6LZuYIE"
          },
          "output": {
            "nodeId": "r10cKGQKU",
            "pinKey": "__out__"
          }
        },
        "r1xZNmQYI": {
          "id": "r1xZNmQYI",
          "input": {
            "nodeId": "BkMGVazmYI",
            "pinKey": "r1H7MwK8E"
          },
          "output": {
            "nodeId": "HkIeNXmKU",
            "pinKey": "ByHmL0uHPk-"
          }
        },
        "rJGrNEQmFU": {
          "id": "rJGrNEQmFU",
          "input": {
            "nodeId": "HkIeNXmKU",
            "pinKey": "ryv7IRdSP1b"
          },
          "output": {
            "nodeId": "BybrNVmmFL",
            "pinKey": "__out__"
          }
        },
        "rJaCiz7tI": {
          "id": "rJaCiz7tI",
          "input": {
            "nodeId": "r1C-cGmt8",
            "pinKey": "BJn2q3CQ4"
          },
          "output": {
            "nodeId": "BJBsjfmYU",
            "pinKey": "Bkzec3074"
          }
        },
        "rJbxKMmYU": {
          "id": "rJbxKMmYU",
          "input": {
            "nodeId": "BJERHfmYU",
            "pinKey": "B19c8SUJV"
          },
          "output": {
            "nodeId": "ryO9DGQKL",
            "pinKey": "B19RYS3lW"
          }
        },
        "rkX287XYI": {
          "id": "rkX287XYI",
          "input": {
            "nodeId": "Hy_lB7QKI",
            "pinKey": "BJn2q3CQ4"
          },
          "output": {
            "nodeId": "r1I_L77FL",
            "pinKey": "rkV5H2XkE"
          }
        },
        "rkePB777tL": {
          "id": "rkePB777tL",
          "input": {
            "nodeId": "B1PrmXmKL",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "Syu_ufmKU",
            "pinKey": "BkGpcpcJQ"
          }
        },
        "rkhMrXXFI": {
          "id": "rkhMrXXFI",
          "input": {
            "nodeId": "BJBsjfmYU",
            "pinKey": "BkXo6sVbN"
          },
          "output": {
            "nodeId": "Hy_lB7QKI",
            "pinKey": "SJVu9h0XV"
          }
        },
        "rkl7mMKcPI": {
          "id": "rkl7mMKcPI",
          "input": {
            "nodeId": "rJAJXyQBL",
            "pinKey": "rkPrUKFIV"
          },
          "output": {
            "nodeId": "S1XmMF9DI",
            "pinKey": "__out__"
          }
        },
        "ryeCA-FqvU": {
          "id": "ryeCA-FqvU",
          "input": {
            "nodeId": "SJgcQsafrU",
            "pinKey": "Sy6LZuYIE"
          },
          "output": {
            "nodeId": "HyRC-t5D8",
            "pinKey": "__out__"
          }
        }
      },
      "nodes": {
        "B1IcQspfrI": {
          "id": "B1IcQspfrI",
          "position": {
            "x": 17,
            "y": -25,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/send-buffer-to-display"
        },
        "B1PrmXmKL": {
          "id": "B1PrmXmKL",
          "label": "D_X",
          "position": {
            "x": 18,
            "y": -22,
            "units": "slots"
          },
          "type": "xod/patch-nodes/to-bus"
        },
        "B1W9QsTzSL": {
          "id": "B1W9QsTzSL",
          "label": "Boot-Display",
          "position": {
            "x": 11,
            "y": -27,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/init"
        },
        "BJ4c7s6GH8": {
          "boundLiterals": {
            "SkSuD6LMb": "On Boot",
            "Skre8ROSv1-": "7"
          },
          "id": "BJ4c7s6GH8",
          "position": {
            "x": 10,
            "y": -25,
            "units": "slots"
          },
          "type": "xod/core/delay"
        },
        "BJBsjfmYU": {
          "boundLiterals": {
            "Bkf6piNZE": "\"\\257 Speed\""
          },
          "id": "BJBsjfmYU",
          "label": "SPEED",
          "position": {
            "x": 6,
            "y": -22,
            "units": "slots"
          },
          "type": "@/branch-menu-item"
        },
        "BJERHfmYU": {
          "boundLiterals": {
            "SJqEaMIVN": "\"Settings\"",
            "ryAVpML4V": "\"\\257 Start 01\""
          },
          "id": "BJERHfmYU",
          "label": "CONTROLLER",
          "position": {
            "x": 9,
            "y": -20,
            "units": "slots"
          },
          "type": "@/menu-controller"
        },
        "BJG46f7FI": {
          "id": "BJG46f7FI",
          "label": "DEV",
          "position": {
            "x": 2,
            "y": -19,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "BJOIU7XFU": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Speed:01\""
          },
          "id": "BJOIU7XFU",
          "label": "SPEED_01",
          "position": {
            "x": 6,
            "y": -27,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "BJoMuzQtL": {
          "boundLiterals": {
            "SJqZ8COrDkW": "0.2"
          },
          "id": "BJoMuzQtL",
          "label": "LES_Y",
          "position": {
            "x": 11,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/core/less"
        },
        "BJz-OGmFL": {
          "boundLiterals": {
            "SJqZ8COrDkW": "0.2"
          },
          "id": "BJz-OGmFL",
          "label": "LES_X",
          "position": {
            "x": 18,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/core/less"
        },
        "BkMGVazmYI": {
          "id": "BkMGVazmYI",
          "label": "Clear",
          "position": {
            "x": 2,
            "y": -18,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/clear-display"
        },
        "BkSN4m7KL": {
          "id": "BkSN4m7KL",
          "label": "DONE",
          "position": {
            "x": 17,
            "y": -24,
            "units": "slots"
          },
          "type": "xod/patch-nodes/to-bus"
        },
        "BkSqQoaMHL": {
          "id": "BkSqQoaMHL",
          "position": {
            "x": 15,
            "y": -25,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/clear-display"
        },
        "BkblQsqtL": {
          "id": "BkblQsqtL",
          "label": "clon-1",
          "position": {
            "x": 0,
            "y": -27,
            "units": "slots"
          },
          "type": "@/flash-string-clon-1"
        },
        "By0eMYcvI": {
          "id": "By0eMYcvI",
          "label": "DEV",
          "position": {
            "x": 10,
            "y": -27,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "By1EI7mtU": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Mode:03\""
          },
          "id": "By1EI7mtU",
          "label": "MODE_03",
          "position": {
            "x": 2,
            "y": -25,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "By5msaMBI": {
          "id": "By5msaMBI",
          "label": "Clear",
          "position": {
            "x": 10,
            "y": -26,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/clear-display"
        },
        "ByOGzYqDL": {
          "id": "ByOGzYqDL",
          "label": "DEV",
          "position": {
            "x": 17,
            "y": -26,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "BySCr7XKU": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Mode:01\""
          },
          "id": "BySCr7XKU",
          "label": "MODE_01",
          "position": {
            "x": 2,
            "y": -27,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "BybrNVmmFL": {
          "id": "BybrNVmmFL",
          "label": "DONE",
          "position": {
            "x": 0,
            "y": -19,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "H1MqQj6MSU": {
          "boundLiterals": {
            "BJgxWIFUV": "32"
          },
          "id": "H1MqQj6MSU",
          "label": "Display",
          "position": {
            "x": 14,
            "y": -29,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/ssd1306-oled-i2c-device"
        },
        "H1VB77QtU": {
          "id": "H1VB77QtU",
          "label": "D_Y",
          "position": {
            "x": 14,
            "y": -22,
            "units": "slots"
          },
          "type": "xod/patch-nodes/to-bus"
        },
        "H1WGNTfQtL": {
          "id": "H1WGNTfQtL",
          "position": {
            "x": 4,
            "y": -18,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/send-buffer-to-display"
        },
        "H1qiozmtI": {
          "boundLiterals": {
            "Bkf6piNZE": "\"\\257 Start\""
          },
          "id": "H1qiozmtI",
          "label": "START",
          "position": {
            "x": 10,
            "y": -22,
            "units": "slots"
          },
          "type": "@/branch-menu-item"
        },
        "HJ4srXmKI": {
          "arityLevel": 3,
          "id": "HJ4srXmKI",
          "label": "SUB-MODE",
          "position": {
            "x": 2,
            "y": -23,
            "units": "slots"
          },
          "type": "@/concat-menu"
        },
        "HJd6-FcPL": {
          "id": "HJd6-FcPL",
          "label": "DEV",
          "position": {
            "x": 14,
            "y": -28,
            "units": "slots"
          },
          "type": "xod/patch-nodes/to-bus"
        },
        "HJsV8XXKL": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Mode:04\""
          },
          "id": "HJsV8XXKL",
          "label": "MODE_04",
          "position": {
            "x": 2,
            "y": -24,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "HJwVGK9vI": {
          "id": "HJwVGK9vI",
          "label": "DEV",
          "position": {
            "x": 15,
            "y": -26,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "Hk88DQXYL": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\257 Start 02\""
          },
          "id": "Hk88DQXYL",
          "label": "GO",
          "position": {
            "x": 10,
            "y": -23,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "HkIeNXmKU": {
          "id": "HkIeNXmKU",
          "position": {
            "x": 0,
            "y": -18,
            "units": "slots"
          },
          "type": "xod/core/any"
        },
        "HkUXXmXtU": {
          "id": "HkUXXmXtU",
          "position": {
            "x": 1,
            "y": -20,
            "units": "slots"
          },
          "type": "xod/core/any"
        },
        "HkgdwfXt8": {
          "boundLiterals": {
            "SkuhqCqym": "A1"
          },
          "id": "HkgdwfXt8",
          "label": "JOY_Y",
          "position": {
            "x": 13,
            "y": -23,
            "units": "slots"
          },
          "type": "xod/gpio/analog-read"
        },
        "HklGEafQYU": {
          "id": "HklGEafQYU",
          "label": "DEV",
          "position": {
            "x": 4,
            "y": -19,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "Hky9PzmKI": {
          "boundLiterals": {
            "HJbACN3gb": "0.9"
          },
          "id": "Hky9PzmKI",
          "label": "GTR_Y",
          "position": {
            "x": 13,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/core/greater"
        },
        "HyRC-t5D8": {
          "id": "HyRC-t5D8",
          "label": "DEV",
          "position": {
            "x": 17,
            "y": -27,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "Hy_lB7QKI": {
          "arityLevel": 2,
          "id": "Hy_lB7QKI",
          "label": "SUB-SPEED",
          "position": {
            "x": 6,
            "y": -24,
            "units": "slots"
          },
          "type": "@/concat-menu"
        },
        "HyxjtfmtL": {
          "id": "HyxjtfmtL",
          "label": "DEV",
          "position": {
            "x": 6,
            "y": -19,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "S1HfLmmK8": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Mode:02\""
          },
          "id": "S1HfLmmK8",
          "label": "MODE_02",
          "position": {
            "x": 2,
            "y": -26,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "S1XmMF9DI": {
          "id": "S1XmMF9DI",
          "label": "DEV",
          "position": {
            "x": 14,
            "y": -27,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "SJgcQsafrU": {
          "id": "SJgcQsafrU",
          "position": {
            "x": 17,
            "y": -26,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/send-buffer-to-display"
        },
        "SkbVBmXmt8": {
          "id": "SkbVBmXmt8",
          "label": "D_X",
          "position": {
            "x": 1,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "SyMIUz7K8": {
          "boundLiterals": {
            "ByNiWkt8Z": "D3"
          },
          "id": "SyMIUz7K8",
          "label": "PRS",
          "position": {
            "x": 15,
            "y": -23,
            "units": "slots"
          },
          "type": "xod/common-hardware/button"
        },
        "Syu_ufmKU": {
          "id": "Syu_ufmKU",
          "label": "JOY_X",
          "position": {
            "x": 17,
            "y": -23,
            "units": "slots"
          },
          "type": "xod/gpio/analog-read"
        },
        "r10cKGQKU": {
          "id": "r10cKGQKU",
          "label": "DEV",
          "position": {
            "x": 14,
            "y": -19,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "r1C-cGmt8": {
          "arityLevel": 2,
          "id": "r1C-cGmt8",
          "label": "MAIN",
          "position": {
            "x": 8,
            "y": -21,
            "units": "slots"
          },
          "type": "@/concat-menu"
        },
        "r1I_L77FL": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Speed:02\""
          },
          "id": "r1I_L77FL",
          "label": "SPEED_02",
          "position": {
            "x": 6,
            "y": -26,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "rJ-PHmmXt8": {
          "id": "rJ-PHmmXt8",
          "label": "D_Y",
          "position": {
            "x": 2,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "rJAJXyQBL": {
          "id": "rJAJXyQBL",
          "label": "Draw-Logo",
          "position": {
            "x": 13,
            "y": -26,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/draw-xod-logo"
        },
        "rJZYIm7KU": {
          "boundLiterals": {
            "B1GhbmCDX": "\"\\256 Speed:02\""
          },
          "id": "rJZYIm7KU",
          "label": "SPEED_02",
          "position": {
            "x": 6,
            "y": -25,
            "units": "slots"
          },
          "type": "@/leaf-menu-item"
        },
        "rkPOYz7YU": {
          "id": "rkPOYz7YU",
          "position": {
            "x": 14,
            "y": -18,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/send-buffer-to-display"
        },
        "rkUXztqPL": {
          "id": "rkUXztqPL",
          "label": "DEV",
          "position": {
            "x": 11,
            "y": -28,
            "units": "slots"
          },
          "type": "xod/patch-nodes/from-bus"
        },
        "rkjwsMXtI": {
          "boundLiterals": {
            "Bkf6piNZE": "\"\\257 Mode\""
          },
          "id": "rkjwsMXtI",
          "label": "MODE",
          "position": {
            "x": 2,
            "y": -22,
            "units": "slots"
          },
          "type": "@/branch-menu-item"
        },
        "ryO9DGQKL": {
          "boundLiterals": {
            "HJbACN3gb": "0.9"
          },
          "id": "ryO9DGQKL",
          "label": "GTR_X",
          "position": {
            "x": 16,
            "y": -21,
            "units": "slots"
          },
          "type": "xod/core/greater"
        },
        "ryqBYMmtL": {
          "boundLiterals": {
            "Bkw-6yqI4": "10",
            "rJgOsycUN": "False"
          },
          "id": "ryqBYMmtL",
          "position": {
            "x": 6,
            "y": -18,
            "units": "slots"
          },
          "type": "wayland/ssd1306-oled-i2c/draw-text"
        }
      },
      "path": "@/00-lazer-shot"
    },
    "@/branch-menu-item": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\n/* include the base class type of a Menu item */\n\nnamespace menu_base = ____menu_base;\nusing menu_base_t = menu_base::MenuBase;\n\n/* A wrapper for a raw BiDirectionalList that allows a Branch-type\n   menu to retain/manage location state when the user is paging thru its\n   sub-menus */\n\ntemplate <typename MenuBase>\nclass SubMenuIterator {\n  public:\n   SubMenuIterator() = default;\n\n  explicit SubMenuIterator(menu_base::BiDirectionalList<MenuBase*> sub_menus) :\n                     sub_menu_ptr_list_(sub_menus), length_(xod::length(sub_menus)) {}\n\n  menu_base::BiDirectionalList<MenuBase*> menu_ptr_list() const {\n    return sub_menu_ptr_list_;\n  }\n\n  SubMenuIterator<MenuBase>& operator++() {\n    if (cursor_ < length_ - 1) ++cursor_;\n    return *this;\n  }\n\n  SubMenuIterator<MenuBase>& operator--() {\n    if (cursor_ > 0) --cursor_;\n    return *this;\n  }\n\n  MenuBase* current_menu_ptr() {\n    auto it = sub_menu_ptr_list_.iterate();\n    for (uint8_t i = 0; i < cursor_; ++i) { ++it; }\n    return *it;\n  }\n\n  void reset() {\n    cursor_ = 0;\n  }\n\n  private:\n    menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list_;\n    uint8_t length_ = 0;\n    uint8_t cursor_ = 0;\n};\n\n\n/* An interface class for a Branch-type menu page which inherits the default\n   MenuInterface methods plus additional Branch-type specific methods to allow \n   navigation thru its sub-menus. */\n\ntemplate <typename MenuBase, template <typename> class BranchMenuImpl>\nclass BranchMenuInterface : public menu_base::MenuInterface<MenuBase, BranchMenuImpl> {\n public:\n    MenuBase* sub_menu_ptr() {\n        return static_cast<BranchMenuImpl<MenuBase>*>(this)->sub_menu_ptr_();\n    }\n\n    MenuBase* next() {\n        return static_cast<BranchMenuImpl<MenuBase>*>(this)->next_();\n    }\n\n    MenuBase* prev() {\n        return static_cast<BranchMenuImpl<MenuBase>*>(this)->prev_();\n    }\n\n    BranchMenuImpl<MenuBase>* parent() {\n        return static_cast<BranchMenuImpl<MenuBase>*>(this)->parent_();\n    }\n\n    void set_parent(BranchMenuImpl<MenuBase>* parent) {\n        static_cast<BranchMenuImpl<MenuBase>*>(this)->set_parent_(parent);\n    }\n};\n\n/* an implementation of a Branch-type menu page satisfying the requirements\n  from the above interface. */\n\ntemplate <typename MenuBase>\nclass BranchMenuImpl final\n    : public BranchMenuInterface<MenuBase, BranchMenuImpl>,\n      public MenuBase {\n  friend class menu_base::MenuInterface<MenuBase, BranchMenuImpl>;\n  friend class BranchMenuInterface<MenuBase, BranchMenuImpl>;\n\n public:\n  constexpr BranchMenuImpl()\n      : MenuBase(0),\n        menu_text_lines_view_(PlainListView<XString>(nullptr, 0)) {}\n\n  BranchMenuImpl(menu_base::BiDirectionalList<MenuBase*> sub_menu_ptr_list,\n                 XString menu_text_1, XString menu_text_2, Number user_id)\n      : MenuBase(user_id),\n        menu_text_{menu_text_1, menu_text_2},\n        menu_text_lines_view_(PlainListView<XString>(menu_text_, 2)),\n        sub_menu_it_(SubMenuIterator<MenuBase>(sub_menu_ptr_list))\n        {}\n\n protected:\n  List<XString> text_() override {\n    menu_text_lines_view_ = PlainListView<XString>(menu_text_, 2);\n    return List<XString>(&menu_text_lines_view_);\n  }\n\n  MenuBase* invoke_(Number /* param */) override {\n      sub_menu_it_.reset();\n      return this;\n  }\n\n  MenuBase* sub_menu_ptr_() {\n      return sub_menu_it_.current_menu_ptr();\n  }\n\n  MenuBase* next_() {\n      ++sub_menu_it_;\n      return sub_menu_it_.current_menu_ptr();\n  }\n\n  MenuBase* prev_() {\n      --sub_menu_it_;\n      return sub_menu_it_.current_menu_ptr();\n  }\n\n  BranchMenuImpl<MenuBase>* parent_() const {\n    return parent_ptr_;\n  }\n\n  void set_parent_(BranchMenuImpl<MenuBase>* parent) {\n      parent_ptr_ = parent;\n  }\n\n private:\n  XString menu_text_[2];\n  PlainListView<XString> menu_text_lines_view_;\n  SubMenuIterator<MenuBase> sub_menu_it_;\n  BranchMenuImpl<MenuBase>* parent_ptr_ = nullptr;\n};\n\n/* The state for this node contains an instance of a Branch-type menu class\n   plus a ListView, so that the node can output a List-type wrapper holding its\n   pointer, so that its pointer can be appended into further lists of Menu-type\n   pointers to allow automatic construction of a tree-like data structure. */\n\nstruct State {\n  BranchMenuImpl<menu_base_t> branch_menu;\n  menu_base_t* branch_menu_ptr;\n  menu_base::BiDirectionalPlainListView<menu_base_t*> branch_menu_ptr_view =\n      menu_base::BiDirectionalPlainListView<menu_base_t*>(&branch_menu_ptr, 1);\n};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(Context ctx) {\n  if (isSettingUp()) {\n    using menu_base::BiDirectionalList;\n    auto state = getState(ctx);\n    auto in = getValue<input_IN>(ctx);\n    auto text1 = getValue<input_LINE1>(ctx);\n    auto text2 = getValue<input_LINE2>(ctx);\n    auto id = getValue<input_ID>(ctx);\n    state->branch_menu = BranchMenuImpl<menu_base_t>(in, text1, text2, id);\n    state->branch_menu_ptr = &state->branch_menu;\n    emitValue<output_OUT>(ctx, menu_base::BiDirectionalList<menu_base_t*>(&state->branch_menu_ptr_view));\n  }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "BkXo6sVbN": {
          "id": "BkXo6sVbN",
          "label": "IN",
          "position": {
            "x": 2,
            "y": 0,
            "units": "slots"
          },
          "type": "@/input-leaf-menu-item-impl"
        },
        "Bkf6piNZE": {
          "boundLiterals": {
            "__out__": "\"\""
          },
          "id": "Bkf6piNZE",
          "label": "LINE1",
          "position": {
            "x": 4,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "Bkzec3074": {
          "id": "Bkzec3074",
          "position": {
            "x": 2,
            "y": 2,
            "units": "slots"
          },
          "type": "@/output-leaf-menu-item-impl"
        },
        "HJdTo7L44": {
          "boundLiterals": {
            "__out__": "\"\""
          },
          "id": "HJdTo7L44",
          "label": "LINE2",
          "position": {
            "x": 6,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "SkCj0j4bN": {
          "id": "SkCj0j4bN",
          "label": "ID",
          "position": {
            "x": 8,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-byte"
        },
        "rJGEai7k4": {
          "id": "rJGEai7k4",
          "position": {
            "x": 2,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        }
      },
      "path": "@/branch-menu-item"
    },
    "@/concat-menu": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\nnamespace menu_base = ____menu_base;\nusing menu_base_t = menu_base::MenuBase;\n\n/* A derived type of BiDirectionalListView, used to concatenate two\n   bi-directional lists and iterate forward and backwards over both\n   as a single unit. This can also be instantiated recursively. See\n   e.g. the XOD standard library class \"ConcatListView\"*/\n\ntemplate <typename T>\nclass BiDirectionalConcatListView : public menu_base::BiDirectionalListView<T> {\n public:\n  class Cursor : public menu_base::BiDirectionalCursor<T> {\n   public:\n     Cursor(const BiDirectionalConcatListView<T>* owner)\n        : _left(std::move(owner->_left.biterate())),\n          _right(std::move(owner->_right.biterate())),\n          _owner(owner) {}\n\n    bool isValid() const override { return _left && _right; }\n\n    bool value(T* out) const override {\n      return _cursor < _owner->_length_left ? _left.value(out) : _right.value(out);\n    }\n\n    void next() override {\n      const auto total = _owner->_length_left + _owner->_length_right;\n      if (_cursor < _owner->_length_left - 1) {\n        ++_left;\n      } else if (_cursor >= _owner->_length_left - 1 && _cursor < total) {\n        if (_cursor != _owner->_length_left - 1) {\n          ++_right;\n        }\n      }\n      ++_cursor;\n    }\n\n    void prev() override {\n      const auto total = _owner->_length_left + _owner->_length_right;\n      if (_cursor > _owner->_length_left - 1 && _cursor != total - _owner->_length_right) {\n        --_right;\n      } else if (_cursor <= _owner->_length_left - 1) {\n        --_left;\n      }\n      if (_cursor) {\n        --_cursor;\n      }\n    }\n\n   private:\n    menu_base::BiDirectionalIterator<T> _left;\n    menu_base::BiDirectionalIterator<T> _right;\n    const BiDirectionalConcatListView<T>* _owner;\n    size_t _cursor = 0;\n  };\n\n public:\n  BiDirectionalConcatListView() = default;\n\n  BiDirectionalConcatListView(menu_base::BiDirectionalList<T> left,\n                              menu_base::BiDirectionalList<T> right)\n      : _left(left), _right(right), _length_left(length(left)), _length_right(length(right)) {}\n\n  BiDirectionalConcatListView& operator=(\n      const BiDirectionalConcatListView& rhs) {\n    _left = rhs._left;\n    _right = rhs._right;\n    _length_left = rhs._length_left;\n    _length_right = rhs._length_right;\n    return *this;\n  }\n\n  Iterator<T> iterate() const override {\n     return Iterator<T>(new Cursor(this));\n  }\n\n  menu_base::BiDirectionalIterator<T> biterate() const override {\n    return menu_base::BiDirectionalIterator<T>(new Cursor(this));\n  }\n\n private:\n  friend class Cursor;\n  menu_base::BiDirectionalList<T> _left;\n  menu_base::BiDirectionalList<T> _right;\n  size_t _length_left;\n  size_t _length_right;\n};\n\n/* The state for this node contains a BiDirectionalConcatListView\n   of over the two BiDirectionalLists of menu_base_t-type pointers\n   it accepts as  inputs. This node is employed variadically so there\n   will be an additional BiDirectionalConcatListView-containing state\n   genearted for each additional input created beyond the first two. */\n\nstruct State {\n    BiDirectionalConcatListView<menu_base_t*> menu_ptr_list_view;\n};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(Context ctx) {\n    if(isSettingUp()) {\n        using menu_base::BiDirectionalList;\n        auto state = getState(ctx);\n        const auto in1 = getValue<input_IN1>(ctx);\n        const auto in2 = getValue<input_IN2>(ctx);\n        //create a new concat-view join the incoming lists once on startup,\n        //the outputs remain static after that\n        state->menu_ptr_list_view = BiDirectionalConcatListView<menu_base_t*>(in1, in2);\n        //output is a list that can be further concatenated\n        emitValue<output_OUT>(ctx, BiDirectionalList<menu_base_t*>(&state->menu_ptr_list_view));\n    }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "BJ3X9hAXE": {
          "id": "BJ3X9hAXE",
          "position": {
            "x": 0,
            "y": 0,
            "units": "slots"
          },
          "type": "@/input-leaf-menu-item-impl"
        },
        "BJn2q3CQ4": {
          "id": "BJn2q3CQ4",
          "position": {
            "x": 2,
            "y": 0,
            "units": "slots"
          },
          "type": "@/input-leaf-menu-item-impl"
        },
        "SJVu9h0XV": {
          "id": "SJVu9h0XV",
          "position": {
            "x": 0,
            "y": 2,
            "units": "slots"
          },
          "type": "@/output-leaf-menu-item-impl"
        },
        "rkJ1j3CXN": {
          "id": "rkJ1j3CXN",
          "position": {
            "x": 2,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/variadic-1"
        },
        "rkgG25nRQV": {
          "id": "rkgG25nRQV",
          "position": {
            "x": 0,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        }
      },
      "path": "@/concat-menu"
    },
    "@/flash-string": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\nclass FlashStringView : public ListView<char> {\n public:\n  class Cursor : public detail::Cursor<char> {\n   public:\n    Cursor(PGM_P str) : _ptr(str) {}\n\n    bool isValid() const override {\n      return static_cast<bool>(static_cast<char>(pgm_read_byte(_ptr)));\n    }\n\n    bool value(char* out) const override {\n      *out = static_cast<char>(pgm_read_byte(_ptr));\n      return static_cast<bool>(*out);\n    }\n\n    void next() override { ++_ptr; }\n\n   private:\n    PGM_P _ptr;\n  };\n\n public:\n  FlashStringView(PGM_P str = nullptr) : _str(str) {}\n  FlashStringView(const __FlashStringHelper* str)\n      : _str(reinterpret_cast<const char PROGMEM*>(str)) {}\n\n  FlashStringView& operator=(const FlashStringView& rhs) {\n    _str = rhs._str;\n    return *this;\n  }\n\n  virtual Iterator<char> iterate() const override {\n    return _str ? Iterator<char>(new Cursor(_str)) : Iterator<char>::nil();\n  }\n\n private:\n  friend class Cursor;\n  const char* PROGMEM _str;\n};\n\n\nclass XStringFlashString : public XString {\n public:\n  XStringFlashString(PGM_P str) : XString(&_view), _view(str) {}\n\n  XStringFlashString(const __FlashStringHelper* str)\n      : XString(&_view), _view(str) {}\n\n private:\n  FlashStringView _view;\n};\n\nstruct State {\n};\n\n{{ GENERATED_CODE }}\n\nconst char text[] PROGMEM = \"XOD Menus 1.1\";\nstatic XStringFlashString out_text = XStringFlashString(text);\n\nvoid evaluate(Context ctx) {\n    if (isSettingUp()) {\n        emitValue<output_TXT>(ctx, out_text);\n    }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "BktKGEgNV": {
          "id": "BktKGEgNV",
          "position": {
            "x": 1,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        },
        "By79MNlVN": {
          "id": "By79MNlVN",
          "label": "TXT",
          "position": {
            "x": 1,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        }
      },
      "path": "@/flash-string"
    },
    "@/flash-string-clon-1": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\nclass FlashStringView : public ListView<char> {\n public:\n  class Cursor : public detail::Cursor<char> {\n   public:\n    Cursor(PGM_P str) : _ptr(str) {}\n\n    bool isValid() const override {\n      return static_cast<bool>(static_cast<char>(pgm_read_byte(_ptr)));\n    }\n\n    bool value(char* out) const override {\n      *out = static_cast<char>(pgm_read_byte(_ptr));\n      return static_cast<bool>(*out);\n    }\n\n    void next() override { ++_ptr; }\n\n   private:\n    PGM_P _ptr;\n  };\n\n public:\n  FlashStringView(PGM_P str = nullptr) : _str(str) {}\n  FlashStringView(const __FlashStringHelper* str)\n      : _str(reinterpret_cast<const char PROGMEM*>(str)) {}\n\n  FlashStringView& operator=(const FlashStringView& rhs) {\n    _str = rhs._str;\n    return *this;\n  }\n\n  virtual Iterator<char> iterate() const override {\n    return _str ? Iterator<char>(new Cursor(_str)) : Iterator<char>::nil();\n  }\n\n private:\n  friend class Cursor;\n  const char* PROGMEM _str;\n};\n\n\nclass XStringFlashString : public XString {\n public:\n  XStringFlashString(PGM_P str) : XString(&_view), _view(str) {}\n\n  XStringFlashString(const __FlashStringHelper* str)\n      : XString(&_view), _view(str) {}\n\n private:\n  FlashStringView _view;\n};\n\nstruct State {\n};\n\n{{ GENERATED_CODE }}\n\nconst char text[] PROGMEM = \"\\256 Mode:01\";\nstatic XStringFlashString out_text = XStringFlashString(text);\n\nvoid evaluate(Context ctx) {\n    if (isSettingUp()) {\n        emitValue<output_TXT>(ctx, out_text);\n    }\n}\n",
          "encoding": "utf-8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "HJeaTzjcKU": {
          "id": "HJeaTzjcKU",
          "label": "TXT",
          "position": {
            "x": 0,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        },
        "HyTTMjqFL": {
          "id": "HyTTMjqFL",
          "position": {
            "x": 0,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        }
      },
      "path": "@/flash-string-clon-1"
    },
    "@/leaf-menu-item": {
      "links": {
        "B1Urv3t5Q": {
          "id": "B1Urv3t5Q",
          "input": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "rkcHexR_Q"
          },
          "output": {
            "nodeId": "B163hQvYm",
            "pinKey": "HkN7geRd7"
          }
        },
        "BJj1pm79X": {
          "id": "BJj1pm79X",
          "input": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "Bya62QQqX"
          },
          "output": {
            "nodeId": "B1GhbmCDX",
            "pinKey": "__out__"
          }
        },
        "H1K6zUGy4": {
          "id": "H1K6zUGy4",
          "input": {
            "nodeId": "rkEaM8MJE",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "S1DiGLzJE"
          }
        },
        "HJxOPhK5X": {
          "id": "HJxOPhK5X",
          "input": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "HJ1gU3t57"
          },
          "output": {
            "nodeId": "Hk87v3tcQ",
            "pinKey": "__out__"
          }
        },
        "SJw9BnQ1N": {
          "id": "SJw9BnQ1N",
          "input": {
            "nodeId": "rkV5H2XkE",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "HkEPSnX14"
          }
        },
        "r1YJT7X5X": {
          "id": "r1YJT7X5X",
          "input": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "SkC-G70PX"
          },
          "output": {
            "nodeId": "SyBpf7AvQ",
            "pinKey": "__out__"
          }
        },
        "rJQAZIMJV": {
          "id": "rJQAZIMJV",
          "input": {
            "nodeId": "SJh6WIM14",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "By6Qz7RvX",
            "pinKey": "SJPj-UMyV"
          }
        }
      },
      "nodes": {
        "B163hQvYm": {
          "id": "B163hQvYm",
          "position": {
            "x": 2,
            "y": 1,
            "units": "slots"
          },
          "type": "@/menu-base"
        },
        "B1GhbmCDX": {
          "id": "B1GhbmCDX",
          "label": "LINE1",
          "position": {
            "x": 3,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "By6Qz7RvX": {
          "id": "By6Qz7RvX",
          "position": {
            "x": 2,
            "y": 2,
            "units": "slots"
          },
          "type": "@/leaf-menu-item-impl"
        },
        "Hk87v3tcQ": {
          "id": "Hk87v3tcQ",
          "label": "ID",
          "position": {
            "x": 5,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-byte"
        },
        "SJh6WIM14": {
          "id": "SJh6WIM14",
          "label": "INVOKED",
          "position": {
            "x": 4,
            "y": 3,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "SyBpf7AvQ": {
          "id": "SyBpf7AvQ",
          "label": "LINE2",
          "position": {
            "x": 4,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "rkEaM8MJE": {
          "id": "rkEaM8MJE",
          "label": "PARAM",
          "position": {
            "x": 3,
            "y": 3,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-number"
        },
        "rkV5H2XkE": {
          "id": "rkV5H2XkE",
          "position": {
            "x": 2,
            "y": 3,
            "units": "slots"
          },
          "type": "@/output-leaf-menu-item-impl"
        }
      },
      "path": "@/leaf-menu-item"
    },
    "@/leaf-menu-item-impl": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\nnamespace menu_base = ____menu_base;\nusing menu_base_t = menu_base::MenuBase;\n\nusing Type = menu_base::BiDirectionalList<menu_base_t*>;\n\nstruct State {\n    menu_base::LeafMenuImpl<menu_base_t> leaf_menu;\n    menu_base::BiDirectionalPlainListView<menu_base_t*> leaf_menu_view =\n    menu_base::BiDirectionalPlainListView<menu_base_t*>(nullptr, 0);\n};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(Context ctx) {\n    auto state = getState(ctx);\n    auto line1 = getValue<input_LINE1>(ctx);\n    auto line2 = getValue<input_LINE2>(ctx);\n\n    if (isSettingUp())\n    {\n        using menu_base::BiDirectionalPlainListView;\n        using menu_base::BiDirectionalList;\n        using menu_base::LeafMenuImpl;\n\n        const auto user_id = getValue<input_ID>(ctx);\n        const auto menu_base_p2p = getValue<input_MENU_PTR>(ctx);\n        state->leaf_menu_view = menu_base::BiDirectionalPlainListView<menu_base_t*>(menu_base_p2p, 1);\n        state->leaf_menu = LeafMenuImpl<menu_base_t>(line1, line2, user_id);\n        *menu_base_p2p = &state->leaf_menu;\n        emitValue<output_OUT>(ctx,  menu_base::BiDirectionalList<menu_base_t*>(&state->leaf_menu_view));\n        setTimeout(ctx, 10);\n    }\n\n    if (isTimedOut(ctx)) {\n        state->leaf_menu.set_text(line1, line2);\n        Number out;\n        auto invoked = state->leaf_menu.update(&out);\n        if (invoked) {\n         emitValue<output_INVOKED>(ctx, 1);\n         emitValue<output_PARAM>(ctx, out);\n        }\n        setTimeout(ctx, 10);\n    }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "BkHbbicYU": {
          "id": "BkHbbicYU",
          "position": {
            "x": 1,
            "y": 12.176191161927722,
            "units": "slots"
          },
          "type": "xod/patch-nodes/utility"
        },
        "Bya62QQqX": {
          "id": "Bya62QQqX",
          "label": "LINE1",
          "position": {
            "x": 3,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "HJ1gU3t57": {
          "id": "HJ1gU3t57",
          "label": "ID",
          "position": {
            "x": 7,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-byte"
        },
        "HkEPSnX14": {
          "id": "HkEPSnX14",
          "position": {
            "x": 1,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-self"
        },
        "S1DiGLzJE": {
          "id": "S1DiGLzJE",
          "label": "PARAM",
          "position": {
            "x": 4,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-number"
        },
        "SJPj-UMyV": {
          "id": "SJPj-UMyV",
          "label": "INVOKED",
          "position": {
            "x": 7,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "SkC-G70PX": {
          "id": "SkC-G70PX",
          "label": "LINE2",
          "position": {
            "x": 5,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "rkcHexR_Q": {
          "id": "rkcHexR_Q",
          "label": "MENU_PTR",
          "position": {
            "x": 1,
            "y": 0,
            "units": "slots"
          },
          "type": "@/input-menu-base"
        },
        "rkuxfm0v7": {
          "id": "rkuxfm0v7",
          "position": {
            "x": 1,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        }
      },
      "path": "@/leaf-menu-item-impl"
    },
    "@/menu-base": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\n/* Base classes for a BiDirectionalCursor oover a ListView,\n   this adds the required virtual method \"prev\" for iterating in\n   reverse-order, in addition to inheriting \"next\" */\ntemplate <typename T>\nclass BiDirectionalCursor : public detail::Cursor<T> {\n public:\n  virtual void prev() = 0;\n};\n\ntemplate <typename T>\nclass BiDirectionalNilCursor : public BiDirectionalCursor<T> {\n  bool isValid() const { return false; }\n  bool value(T*) const { return false; }\n  void next() {}\n  void prev() {}\n};\n\n/* Reverse iterator implementation */\n\ntemplate <typename T>\nclass ReverseIterator {\n public:\n  static Iterator<T> nil() { return Iterator<T>(new detail::NilCursor<T>()); }\n\n  explicit ReverseIterator(BiDirectionalCursor<T>* cursor) : _cursor(cursor) {}\n\n  ReverseIterator(const ReverseIterator<T>&) = delete;\n  ReverseIterator& operator=(const ReverseIterator<T>&) = delete;\n  ReverseIterator(ReverseIterator<T>&& other) : _cursor(other._cursor) {\n    other._cursor = nullptr;\n  }\n\n  ReverseIterator& operator=(ReverseIterator<T>&& other) {\n    auto tmp = _cursor;\n    _cursor = other._cursor;\n    other._cursor = tmp;\n    return *this;\n  }\n\n  operator bool() const { return _cursor->isValid(); }\n\n  bool value(T* out) const { return _cursor->value(out); }\n\n  T operator*() const {\n    T out;\n    _cursor->value(&out);\n    return out;\n  }\n\n  ReverseIterator& operator--() {\n    _cursor->prev();\n    return *this;\n  }\n\n private:\n  BiDirectionalCursor<T>* _cursor;\n};\n\ntemplate <typename T>\nclass BiDirectionalIterator;\n\n/* A ListView which can return a bi-directional iterator\n   via the \"biterate\" method, compare with the XOD library\n   class \"ListView\" and \"iterate\" method. */\n\ntemplate <typename T>\nclass BiDirectionalListView : public ListView<T> {\n public:\n  virtual BiDirectionalIterator<T> biterate() const = 0;\n\n protected:\n  BiDirectionalListView() = default;\n};\n\ntemplate <typename T>\nclass BiDirectionalList : public List<T> {\n public:\n  constexpr BiDirectionalList() = default;\n\n  explicit BiDirectionalList(const BiDirectionalListView<T>* view)\n      : List<T>(view), _view(view) {}\n\n  BiDirectionalIterator<T> biterate() const {\n    return _view ? _view->biterate() : BiDirectionalIterator<T>::nil();\n  }\n\n private:\n   const BiDirectionalListView<T>* _view = nullptr;\n};\n\n/* A bi-directional iterator which functions similar to the XOD\n   library class \"Iterator\" but can be iterated through forwards\n   and backwards. Both forward-iterating past the end of the\n   underlying container/array and backwards past the starting\n   element will invalidate the iterator, and the user-defined\n   conversion to bool will return false. */\n\ntemplate <typename T>\nclass BiDirectionalIterator {\n public:\n  static BiDirectionalIterator<T> nil() {\n    return BiDirectionalIterator<T>(new BiDirectionalNilCursor<T>());\n  }\n\n  BiDirectionalIterator(BiDirectionalCursor<T>* cursor)\n      : _forward_iterator(cursor), _reverse_iterator(cursor) {}\n\n  operator bool() const { return (bool)_forward_iterator; }\n\n  bool value(T* out) const { return _forward_iterator.value(out); }\n\n  T operator*() const {\n    T out;\n    _forward_iterator.value(&out);\n    return out;\n  }\n\n  BiDirectionalIterator& operator++() {\n    ++_forward_iterator;\n    return *this;\n  }\n\n  BiDirectionalIterator& operator--() {\n    --_reverse_iterator;\n    return *this;\n  }\n\n private:\n  Iterator<T> _forward_iterator;\n  ReverseIterator<T> _reverse_iterator;\n};\n\n/* A bi-directional list view over a good ol' C-style array. Compare\n   XOD library class \"PlainListView\" */\n\ntemplate <typename T>\nclass BiDirectionalPlainListView : public BiDirectionalListView<T> {\n  class Cursor : public BiDirectionalCursor<T> {\n   public:\n    explicit Cursor(const BiDirectionalPlainListView* owner) : _owner(owner), _idx(0) {}\n\n    bool isValid() const override { return _valid; }\n\n    bool value(T* out) const override {\n      if (!isValid()) return false;\n      *out = _owner->_data[_idx];\n      return true;\n    }\n\n    void next() override {\n      if (!(++_idx < _owner->_len)) {\n        _valid = false;\n      }\n    }\n\n    void prev() override { _idx != 0 ? --_idx : _valid = false; }\n\n   private:\n    const BiDirectionalPlainListView* _owner;\n    size_t _idx;\n    bool _valid = true;\n  };\n\n public:\n  BiDirectionalPlainListView(const T* data, size_t len)\n      : _data(data), _len(len) {}\n\n  Iterator<T> iterate() const override { return Iterator<T>(new Cursor(this)); }\n\n  BiDirectionalIterator<T> biterate() const override {\n    return BiDirectionalIterator<T>(new Cursor(this));\n  }\n\n private:\n  friend class BiDirectionalCursor<T>;\n  const T* _data;\n  size_t _len;\n};\n\n/* Base class tpye for all Menu instances representing a\n   particular kind of menu that can be displayed and defines\n   a minimal required set of interface methods. All Menu interface\n   classes must derive from this base type so these base methods\n   may be called polymorphically by the MenuController \n   implementation. */\n\nclass MenuBase {\n public:\n  virtual ~MenuBase() = default;\n\n  List<XString> text() { return text_(); }\n\n  MenuBase* invoke(Number param) { return invoke_(param); }\n\n  uint8_t internal_id() const { return internal_id_; }\n\n  uint8_t user_id() const { return user_id_; }\n\n protected:\n  explicit MenuBase(uint8_t user_id) : user_id_(user_id),\n           internal_id_(id_count()++) {}\n\n private:\n   uint8_t user_id_ = 0;\n   uint8_t internal_id_ = 0;\n\n  static uint8_t& id_count() {\n    static uint8_t id_count = 0;\n    return id_count;\n  }\n\n  virtual List<XString> text_() = 0;\n  virtual MenuBase* invoke_(Number) = 0;\n};\n\n/* Base interface class for a menu type, this can be further\n   inherited from to define necessary non-virtual method calls\n   for various types of menu items. */\n\ntemplate <typename MenuBase, template <typename> class MenuImpl>\nclass MenuInterface {\n public:\n  List<XString> text() {\n    return static_cast<MenuImpl<MenuBase>*>(this)->text_();\n  }\n\n  MenuBase* invoke() {\n    return static_cast<MenuImpl<MenuBase>*>(this)->invoke_();\n  }\n};\n\nusing Type = MenuBase**;\n\n/* The state is used to provide storage for a single base-type\n   Menu pointer which will be assigned to a Leaf menu instance. */\n\nstruct State {\n   MenuBase* leaf_menu_ptr = nullptr;\n};\n\n{{ GENERATED_CODE }}\n\n/* An interface to a simp leaf-type menu, which cannot have further sub-menus\n   called from it, and generates a pulse output plus a paramter change output\n   when it's selected from the MenuController. Particular implementation\n   behavior is injected using the CRTP/static polymorphism to avoid runtime\n   overhead/program memory bloat. */\n\ntemplate <typename MenuBase, template <typename> class LeafMenuImpl>\nclass LeafMenuInterface : public MenuInterface<MenuBase, LeafMenuImpl> {\n public:\n  void set_text(XString line1, XString line2) {\n    static_cast<LeafMenuImpl<MenuBase>*>(this)->set_text_(line1, line2);\n  }\n\n  bool update(Number* out) {\n    return static_cast<LeafMenuImpl<MenuBase>*>(this)->update_(out);\n  }\n};\n\n/* Simple leaf menu implementation example */\n\ntemplate <typename MenuBase>\nclass LeafMenuImpl final : public LeafMenuInterface<MenuBase, LeafMenuImpl>,\n                           public MenuBase {\n  friend class MenuInterface<MenuBase, LeafMenuImpl>;\n  friend class LeafMenuInterface<MenuBase, LeafMenuImpl>;\n\n public:\n  LeafMenuImpl() : MenuBase(0), menu_text_lines_view_(nullptr, 0) {}\n\n  LeafMenuImpl(XString line1, XString line2, uint8_t user_id)\n      : MenuBase(user_id),\n        lines_{line1, line2},\n        menu_text_lines_view_(PlainListView<XString>(lines_, 2)) {}\n\n protected:\n  List<XString> text_() override {\n    return List<XString>(&menu_text_lines_view_);\n  }\n\n  MenuBase* invoke_(Number param) override {\n    invoked_ = true;\n    param_ = param;\n    return nullptr;\n  }\n\n  void set_text_(XString line1, XString line2) {\n    lines_[0] = line1;\n    lines_[1] = line2;\n    menu_text_lines_view_ = PlainListView<XString>(lines_, 2);\n  }\n\n  bool update_(Number* out) {\n    if (invoked_) {\n      *out = param_;\n      invoked_ = false;\n      return true;\n    }\n    return false;\n  }\n\n private:\n  XString lines_[2];\n  PlainListView<XString> menu_text_lines_view_;\n  bool invoked_ = false;\n  Number param_;\n};\n\nvoid evaluate(Context ctx) {\n  if (isSettingUp()) {\n    auto state = getState(ctx);\n    emitValue<output_OUT>(ctx, &state->leaf_menu_ptr);\n  }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "B1Djf06wX": {
          "id": "B1Djf06wX",
          "position": {
            "x": 2,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        },
        "HJ9MbiqtL": {
          "id": "HJ9MbiqtL",
          "position": {
            "x": 2,
            "y": 73.11111110505604,
            "units": "slots"
          },
          "type": "xod/patch-nodes/utility"
        },
        "HkN7geRd7": {
          "id": "HkN7geRd7",
          "position": {
            "x": 2,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-self"
        }
      },
      "path": "@/menu-base"
    },
    "@/menu-controller": {
      "attachments": [
        {
          "content": "#pragma XOD dirtiness disable\n\nnamespace menu_base = ____menu_base;\nusing menu_base_t = menu_base::MenuBase;\nnamespace branch_menu_item = ____branch_menu_item;\n\n/* a MenuCursor interface, providing an interface from user \n   selections on a keypad to navigating thru the menu tree, \n   selecting, and invoking menu items */\n\ntemplate <typename MenuBase>\nclass MenuCursor {\n public:\n  MenuCursor() = default;\n\n  explicit MenuCursor(branch_menu_item::BranchMenuImpl<MenuBase>* top_menu)\n      : top_menu_ptr_(top_menu),\n        current_root_menu_ptr_(nullptr),\n        current_sub_menu_ptr_(top_menu) {}\n\n  void back() {\n    auto parent_ptr = current_root_menu_ptr_->parent();\n    if (parent_ptr && current_sub_menu_ptr_!= top_menu_ptr_) {\n      current_root_menu_ptr_ = parent_ptr;\n      current_sub_menu_ptr_ = current_root_menu_ptr_->sub_menu_ptr();\n    } else {\n      current_sub_menu_ptr_ = top_menu_ptr_;\n      current_root_menu_ptr_ = nullptr;\n    }\n  }\n\n  void left() {\n    if (current_root_menu_ptr_) {\n      current_sub_menu_ptr_ = current_root_menu_ptr_->prev();\n    }\n  }\n\n  void right() {\n    if (current_root_menu_ptr_) {\n      current_sub_menu_ptr_ = current_root_menu_ptr_->next();\n    }\n  }\n\n  void invoke(Number param) {\n    auto menu_ptr = current_sub_menu_ptr_->invoke(param);\n    if (menu_ptr) {\n      auto prev_root_menu_ = current_root_menu_ptr_;\n      current_root_menu_ptr_ =\n          static_cast<branch_menu_item::BranchMenuImpl<MenuBase>*>(\n              menu_ptr);\n      current_root_menu_ptr_->set_parent(prev_root_menu_);\n      current_sub_menu_ptr_ = current_root_menu_ptr_->sub_menu_ptr();\n    }\n  }\n\n  List<XString> text() const { return current_sub_menu_ptr_->text(); }\n\n private:\n  branch_menu_item::BranchMenuImpl<MenuBase>* top_menu_ptr_ = nullptr;\n  branch_menu_item::BranchMenuImpl<MenuBase>* current_root_menu_ptr_ = nullptr;\n  MenuBase* current_sub_menu_ptr_ = nullptr;\n};\n\n/* State for this node holds a branch menu to which the rest of\n   the menu structure is connected and derives from */\n\nstruct State {\n  MenuCursor<menu_base_t> menu_cursor;\n  branch_menu_item::BranchMenuImpl<menu_base_t> root_menu;\n};\n\n{{ GENERATED_CODE }}\n\nstatic XStringCString null_string = XStringCString(\"\");\n\nvoid evaluate(Context ctx) {\n  auto state = getState(ctx);\n\n  if (isSettingUp()) {\n    auto title_1 = getValue<input_TITLE_1>(ctx);\n    auto title_2 = getValue<input_TITLE_2>(ctx);\n    state->root_menu =\n    branch_menu_item::BranchMenuImpl<menu_base_t>(getValue<input_MENU_TREE>(ctx), title_1,\n                                                  title_2, 0);\n    state->root_menu.set_parent(&state->root_menu);\n    state->menu_cursor = MenuCursor<menu_base_t>(&state->root_menu);\n  }\n\n /* update all trigger pulse inputs */\n\n  bool back = isInputDirty<input_BACK>(ctx);\n  bool left = isInputDirty<input_LEFT>(ctx);\n  bool right = isInputDirty<input_RIGHT>(ctx);\n  bool invoke = isInputDirty<input_INVOKE>(ctx);\n\n  if (back) {\n    state->menu_cursor.back();\n  }\n  if (left) {\n    state->menu_cursor.left();\n  }\n  if (right) {\n    state->menu_cursor.right();\n  }\n  if (invoke) {\n    // if a menu is invoked pass along the input parameter\n    // to the appropriate MenuBase class instance\n    auto param = getValue<input_PARAM_IN>(ctx);\n    state->menu_cursor.invoke(param);\n  }\n\n  //Update the menu dispaly text\n\n  auto text_list = state->menu_cursor.text();\n  auto text_it = text_list.iterate();\n  emitValue<output_LINE1>(ctx, *text_it);\n\n  if (++text_it) {\n    emitValue<output_LINE2>(ctx, *text_it);\n  } else {\n    emitValue<output_LINE2>(ctx, null_string);\n    return;\n  }\n  if (++text_it) {\n    emitValue<output_LINE3>(ctx, *text_it);\n  } else {\n    emitValue<output_LINE3>(ctx, null_string);\n    return;\n  }\n  if (++text_it) {\n    emitValue<output_LINE4>(ctx, *text_it);\n  } else {\n    emitValue<output_LINE4>(ctx, null_string);\n    return;\n  }\n}\n",
          "encoding": "utf8",
          "filename": "patch.cpp"
        }
      ],
      "nodes": {
        "B19c8SUJV": {
          "id": "B19c8SUJV",
          "label": "BACK",
          "position": {
            "x": 11,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "BJGiIBLkE": {
          "id": "BJGiIBLkE",
          "label": "PARAM_IN",
          "position": {
            "x": 17,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-number"
        },
        "Bk22ISLyV": {
          "id": "Bk22ISLyV",
          "label": "INVOKE",
          "position": {
            "x": 13,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "HkEhLHLJE": {
          "id": "HkEhLHLJE",
          "label": "RIGHT",
          "position": {
            "x": 7,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "SJl_mc7yV": {
          "boundLiterals": {
            "__in__": "\"\""
          },
          "id": "SJl_mc7yV",
          "label": "LINE1",
          "position": {
            "x": 1,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        },
        "SJqEaMIVN": {
          "boundLiterals": {
            "__out__": "\"\""
          },
          "id": "SJqEaMIVN",
          "label": "TITLE_1",
          "position": {
            "x": 3,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "SkeKhQOH74": {
          "boundLiterals": {
            "__in__": "\"DISP_LINE_4\""
          },
          "id": "SkeKhQOH74",
          "label": "LINE4",
          "position": {
            "x": 7,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        },
        "SyY3mOB7E": {
          "boundLiterals": {
            "__in__": "\"DISP_LINE_3\""
          },
          "id": "SyY3mOB7E",
          "label": "LINE3",
          "position": {
            "x": 5,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        },
        "SyaiQdSX4": {
          "boundLiterals": {
            "__in__": "\"DISP_LINE_2\""
          },
          "id": "SyaiQdSX4",
          "label": "LINE2",
          "position": {
            "x": 3,
            "y": 2,
            "units": "slots"
          },
          "type": "xod/patch-nodes/output-string"
        },
        "rJQPX97JV": {
          "id": "rJQPX97JV",
          "position": {
            "x": 1,
            "y": 1,
            "units": "slots"
          },
          "type": "xod/patch-nodes/not-implemented-in-xod"
        },
        "rk7w8SIkN": {
          "id": "rk7w8SIkN",
          "label": "MENU_TREE",
          "position": {
            "x": 1,
            "y": 0,
            "units": "slots"
          },
          "type": "@/input-leaf-menu-item-impl"
        },
        "rktQN2FZN": {
          "id": "rktQN2FZN",
          "label": "TOP",
          "position": {
            "x": 15,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "ryAVpML4V": {
          "boundLiterals": {
            "__out__": "\"Title 2\""
          },
          "id": "ryAVpML4V",
          "label": "TITLE_2",
          "position": {
            "x": 5,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-string"
        },
        "rytiIB8kE": {
          "id": "rytiIB8kE",
          "label": "LEFT",
          "position": {
            "x": 9,
            "y": 0,
            "units": "slots"
          },
          "type": "xod/patch-nodes/input-pulse"
        }
      },
      "path": "@/menu-controller"
    }
  }
}
