{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://wirecharm.local/workspace.schema.json",
  "title": "Wirecharm linked multi-canvas project v3",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "format",
    "version",
    "name",
    "kind",
    "activeCanvasId",
    "canvases",
    "links"
  ],
  "properties": {
    "format": {
      "const": "wirecharm"
    },
    "version": {
      "const": 3
    },
    "name": {
      "type": "string",
      "maxLength": 2000
    },
    "kind": {
      "enum": [
        "building",
        "electronics"
      ]
    },
    "activeCanvasId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{1,100}$"
    },
    "canvases": {
      "type": "array",
      "minItems": 1,
      "maxItems": 30,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "canvas"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,100}$"
          },
          "canvas": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "$id": "https://wirecharm.local/project.schema.json",
            "title": "Wirecharm physical wiring project v1",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "format",
              "version",
              "name",
              "description",
              "units",
              "pixelsPerUnit",
              "parts",
              "junctions",
              "cables",
              "walls",
              "notes",
              "background"
            ],
            "properties": {
              "format": {
                "const": "wirecharm"
              },
              "version": {
                "const": 1
              },
              "name": {
                "type": "string",
                "maxLength": 2000
              },
              "description": {
                "type": "string",
                "maxLength": 2000
              },
              "units": {
                "enum": [
                  "mm",
                  "cm",
                  "m",
                  "in",
                  "ft"
                ]
              },
              "pixelsPerUnit": {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 10000
              },
              "parts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "type",
                    "name",
                    "x",
                    "y",
                    "width",
                    "height",
                    "color",
                    "notes",
                    "ports"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,100}$"
                    },
                    "type": {
                      "enum": [
                        "controller",
                        "servo",
                        "led",
                        "battery",
                        "charger",
                        "fuse",
                        "switch",
                        "panel",
                        "outlet",
                        "wall-switch",
                        "lamp",
                        "custom"
                      ]
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "x": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    },
                    "y": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    },
                    "width": {
                      "type": "number",
                      "minimum": 60,
                      "maximum": 2000
                    },
                    "height": {
                      "type": "number",
                      "minimum": 60,
                      "maximum": 2000
                    },
                    "color": {
                      "type": "string",
                      "pattern": "^#[0-9a-fA-F]{6}$"
                    },
                    "notes": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "ports": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "label",
                          "side",
                          "offset",
                          "direction",
                          "pins"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_-]{1,100}$"
                          },
                          "label": {
                            "type": "string",
                            "maxLength": 2000
                          },
                          "side": {
                            "enum": [
                              "left",
                              "right",
                              "top",
                              "bottom"
                            ]
                          },
                          "offset": {
                            "type": "number",
                            "minimum": 0,
                            "maximum": 1
                          },
                          "direction": {
                            "enum": [
                              "in",
                              "out",
                              "bidirectional"
                            ]
                          },
                          "pins": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "id",
                                "label",
                                "color"
                              ],
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "pattern": "^[A-Za-z0-9_-]{1,100}$"
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 2000
                                },
                                "color": {
                                  "type": "string",
                                  "pattern": "^#[0-9a-fA-F]{6}$"
                                }
                              }
                            },
                            "maxItems": 16,
                            "minItems": 1
                          }
                        }
                      },
                      "maxItems": 24
                    }
                  }
                },
                "maxItems": 500
              },
              "junctions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "x",
                    "y",
                    "pins"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,100}$"
                    },
                    "x": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    },
                    "y": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    },
                    "pins": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "label",
                          "color"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_-]{1,100}$"
                          },
                          "label": {
                            "type": "string",
                            "maxLength": 2000
                          },
                          "color": {
                            "type": "string",
                            "pattern": "^#[0-9a-fA-F]{6}$"
                          }
                        }
                      },
                      "maxItems": 16,
                      "minItems": 1
                    }
                  }
                },
                "maxItems": 500
              },
              "cables": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "name",
                    "from",
                    "to",
                    "points",
                    "gauge",
                    "wires"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,100}$"
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "from": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "partId",
                            "portId"
                          ],
                          "properties": {
                            "partId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            },
                            "portId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            }
                          }
                        },
                        {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "junctionId"
                          ],
                          "properties": {
                            "junctionId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            }
                          }
                        }
                      ]
                    },
                    "to": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "partId",
                            "portId"
                          ],
                          "properties": {
                            "partId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            },
                            "portId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            }
                          }
                        },
                        {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "junctionId"
                          ],
                          "properties": {
                            "junctionId": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,100}$"
                            }
                          }
                        }
                      ]
                    },
                    "points": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "x",
                          "y"
                        ],
                        "properties": {
                          "x": {
                            "type": "number",
                            "minimum": -1000000,
                            "maximum": 1000000
                          },
                          "y": {
                            "type": "number",
                            "minimum": -1000000,
                            "maximum": 1000000
                          }
                        }
                      },
                      "maxItems": 200
                    },
                    "gauge": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "wires": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "label",
                          "color",
                          "fromPin",
                          "toPin"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_-]{1,100}$"
                          },
                          "label": {
                            "type": "string",
                            "maxLength": 2000
                          },
                          "color": {
                            "type": "string",
                            "pattern": "^#[0-9a-fA-F]{6}$"
                          },
                          "fromPin": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_-]{1,100}$"
                          },
                          "toPin": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9_-]{1,100}$"
                          }
                        }
                      },
                      "maxItems": 16,
                      "minItems": 1
                    },
                    "color": {
                      "type": "string",
                      "pattern": "^#[0-9a-fA-F]{6}$"
                    },
                    "display": {
                      "enum": [
                        "cable",
                        "ground"
                      ]
                    }
                  }
                },
                "maxItems": 1500
              },
              "walls": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "name",
                    "a",
                    "b",
                    "thickness"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,100}$"
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "a": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "x",
                        "y"
                      ],
                      "properties": {
                        "x": {
                          "type": "number",
                          "minimum": -1000000,
                          "maximum": 1000000
                        },
                        "y": {
                          "type": "number",
                          "minimum": -1000000,
                          "maximum": 1000000
                        }
                      }
                    },
                    "b": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "x",
                        "y"
                      ],
                      "properties": {
                        "x": {
                          "type": "number",
                          "minimum": -1000000,
                          "maximum": 1000000
                        },
                        "y": {
                          "type": "number",
                          "minimum": -1000000,
                          "maximum": 1000000
                        }
                      }
                    },
                    "thickness": {
                      "type": "number",
                      "minimum": 1,
                      "maximum": 100
                    }
                  }
                },
                "maxItems": 500
              },
              "notes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "text",
                    "x",
                    "y"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "pattern": "^[A-Za-z0-9_-]{1,100}$"
                    },
                    "text": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "x": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    },
                    "y": {
                      "type": "number",
                      "minimum": -1000000,
                      "maximum": 1000000
                    }
                  }
                },
                "maxItems": 500
              },
              "background": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "dataUrl",
                      "x",
                      "y",
                      "width",
                      "height",
                      "opacity"
                    ],
                    "properties": {
                      "dataUrl": {
                        "type": "string",
                        "maxLength": 15000000,
                        "pattern": "^data:image/(png|jpeg|webp);base64,[A-Za-z0-9+/=]+$"
                      },
                      "x": {
                        "type": "number",
                        "minimum": -1000000,
                        "maximum": 1000000
                      },
                      "y": {
                        "type": "number",
                        "minimum": -1000000,
                        "maximum": 1000000
                      },
                      "width": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "maximum": 100000
                      },
                      "height": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "maximum": 100000
                      },
                      "opacity": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "metadata": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "studio": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "labels": {
              "type": "boolean"
            },
            "inspectorCollapsed": {
              "type": "boolean"
            },
            "panels": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "tools": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "x",
                    "y",
                    "dock",
                    "bottom"
                  ],
                  "properties": {
                    "x": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "y": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "dock": {
                      "enum": [
                        "bottom",
                        "free"
                      ]
                    },
                    "bottom": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 100000
                    },
                    "collapsed": {
                      "type": "boolean"
                    },
                    "mobileCollapsed": {
                      "type": "boolean"
                    }
                  }
                },
                "overview": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "x",
                    "y",
                    "dock",
                    "bottom"
                  ],
                  "properties": {
                    "x": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "y": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "dock": {
                      "enum": [
                        "bottom",
                        "free"
                      ]
                    },
                    "bottom": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 100000
                    },
                    "collapsed": {
                      "type": "boolean"
                    },
                    "mobileCollapsed": {
                      "type": "boolean"
                    }
                  }
                },
                "zoom": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "x",
                    "y",
                    "dock",
                    "bottom"
                  ],
                  "properties": {
                    "x": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "y": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "dock": {
                      "enum": [
                        "bottom",
                        "free"
                      ]
                    },
                    "bottom": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 100000
                    },
                    "collapsed": {
                      "type": "boolean"
                    },
                    "mobileCollapsed": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "links": {
      "type": "array",
      "maxItems": 1500,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "from",
          "to",
          "gauge",
          "wires"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,100}$"
          },
          "name": {
            "type": "string",
            "maxLength": 2000
          },
          "from": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "canvasId",
              "endpoint",
              "position"
            ],
            "properties": {
              "canvasId": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,100}$"
              },
              "endpoint": {
                "oneOf": [
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "partId",
                      "portId"
                    ],
                    "properties": {
                      "partId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      },
                      "portId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "junctionId"
                    ],
                    "properties": {
                      "junctionId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      }
                    }
                  }
                ]
              },
              "position": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "x",
                  "y"
                ],
                "properties": {
                  "x": {
                    "type": "number",
                    "minimum": -1000000,
                    "maximum": 1000000
                  },
                  "y": {
                    "type": "number",
                    "minimum": -1000000,
                    "maximum": 1000000
                  }
                }
              }
            }
          },
          "to": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "canvasId",
              "endpoint",
              "position"
            ],
            "properties": {
              "canvasId": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,100}$"
              },
              "endpoint": {
                "oneOf": [
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "partId",
                      "portId"
                    ],
                    "properties": {
                      "partId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      },
                      "portId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "junctionId"
                    ],
                    "properties": {
                      "junctionId": {
                        "type": "string",
                        "pattern": "^[A-Za-z0-9_-]{1,100}$"
                      }
                    }
                  }
                ]
              },
              "position": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "x",
                  "y"
                ],
                "properties": {
                  "x": {
                    "type": "number",
                    "minimum": -1000000,
                    "maximum": 1000000
                  },
                  "y": {
                    "type": "number",
                    "minimum": -1000000,
                    "maximum": 1000000
                  }
                }
              }
            }
          },
          "gauge": {
            "type": "string",
            "maxLength": 2000
          },
          "wires": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "label",
                "color",
                "fromPin",
                "toPin"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{1,100}$"
                },
                "label": {
                  "type": "string",
                  "maxLength": 2000
                },
                "color": {
                  "type": "string",
                  "pattern": "^#[0-9a-fA-F]{6}$"
                },
                "fromPin": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{1,100}$"
                },
                "toPin": {
                  "type": "string",
                  "pattern": "^[A-Za-z0-9_-]{1,100}$"
                }
              }
            },
            "maxItems": 16,
            "minItems": 1
          },
          "color": {
            "type": "string",
            "pattern": "^#[0-9a-fA-F]{6}$"
          }
        }
      }
    }
  }
}
