{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lantern.boreale.dev/schemas/v1/common.json",
  "title": "Lantern common definitions",
  "description": "Definitions shared by Lantern's documents (SPEC.md). Readers ignore fields they do not know; every document allows them.",
  "$defs": {
    "schema1": {
      "description": "The document's schema (SPEC.md § 3.2). A reader treats a higher one as absent.",
      "const": 1
    },
    "platform": {
      "description": "A platform's name (SPEC.md § 4.3): Atlas's where it has one (switch, steam, gog, xbox), and 3ds, vita, ps4, android, ios, windows, macos, linux, web.",
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9-]{0,31}$"
    },
    "id": {
      "description": "A title or app id (SPEC.md § 6.1): opaque, of the form its platform's profile gives (Annex A), compared exactly.",
      "type": "string",
      "pattern": "^[A-Za-z0-9._-]{1,128}$"
    },
    "id16": {
      "description": "A Switch title or app id: 16 upper-case hex digits (SPEC.md Annex A.1).",
      "type": "string",
      "pattern": "^[0-9A-F]{16}$"
    },
    "switch_title_id": {
      "description": "A Switch game's title id (SPEC.md Annex A.1): 16 upper-case hex digits, its lowest 13 bits zero.",
      "type": "string",
      "pattern": "^[0-9A-F]{12}[02468ACE]000$"
    },
    "switch_update_id": {
      "description": "A Switch update's app id (SPEC.md Annex A.1): its game's title id plus 800 (hex).",
      "type": "string",
      "pattern": "^[0-9A-F]{12}[02468ACE]800$"
    },
    "app_type": {
      "description": "An app's type, from its profile's list (SPEC.md § 6.1).",
      "type": "string",
      "pattern": "^[a-z][a-z0-9_]{0,31}$"
    },
    "format": {
      "description": "A package format, from its profile's list (SPEC.md § 6.1).",
      "type": "string",
      "pattern": "^[a-z0-9]{1,16}$"
    },
    "sha256": {
      "description": "A SHA-256, lower-case hex.",
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "opaque": {
      "description": "An opaque id or token, chosen by the server.",
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "text": {
      "description": "A string field (SPEC.md § 13: 4 KiB at most).",
      "type": "string",
      "maxLength": 4096
    },
    "name": {
      "description": "A name (SPEC.md § 13: 512 bytes at most).",
      "type": "string",
      "maxLength": 512
    },
    "note": {
      "description": "A note (SPEC.md § 13: 120 bytes at most).",
      "type": "string",
      "maxLength": 120
    },
    "profile": {
      "description": "The name a user gave a profile (SPEC.md § 9.1: 64 bytes at most); never a hardware or account identifier.",
      "type": "string",
      "maxLength": 64
    },
    "url": {
      "description": "An absolute URL, or a path on the server's origin.",
      "type": "string",
      "minLength": 1,
      "maxLength": 4096
    },
    "time": {
      "description": "A UTC time (SPEC.md § 2.3): RFC 3339, Z and no offset, a fraction of a second of 1 to 9 digits at most.",
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,9})?Z$"
    },
    "language": {
      "description": "A language tag (BCP 47).",
      "type": "string",
      "maxLength": 35
    },
    "uint53": {
      "description": "A count or a size: an integer of I-JSON's range, 0 to 2^53 - 1 (SPEC.md § 2.3).",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "uint32": {
      "type": "integer",
      "minimum": 0,
      "maximum": 4294967295
    },
    "scope": {
      "enum": [
        "library",
        "saves",
        "cheats",
        "cheats.write",
        "requests",
        "admin",
        "sync.read",
        "sync.write"
      ]
    },
    "app": {
      "description": "One installable package (SPEC.md § 6.1). On a Switch, its ids, type and format follow Annex A.1.",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "app_id": {
          "$ref": "common.json#/$defs/id"
        },
        "type": {
          "$ref": "common.json#/$defs/app_type"
        },
        "version_code": {
          "$ref": "common.json#/$defs/uint53",
          "description": "An integer, as the profile derives it: clients compare it, never version_name."
        },
        "version_name": {
          "$ref": "common.json#/$defs/name"
        },
        "name": {
          "$ref": "common.json#/$defs/name"
        },
        "size": {
          "$ref": "common.json#/$defs/uint53"
        },
        "format": {
          "$ref": "common.json#/$defs/format"
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256",
          "description": "Of the file as served (SPEC.md § 6.1). Required: a server hashes a file before it lists it."
        },
        "added": {
          "$ref": "common.json#/$defs/time"
        },
        "file": {
          "$ref": "common.json#/$defs/url"
        },
        "atlas": {
          "$ref": "common.json#/$defs/atlas"
        },
        "installed_size": {
          "$ref": "common.json#/$defs/uint53",
          "description": "The bytes it takes once installed, when the server knows them (SPEC.md § 6.1, § 6.3)."
        },
        "mirrors": {
          "$ref": "common.json#/$defs/mirrors"
        }
      },
      "required": [
        "id",
        "platform",
        "title_id",
        "app_id",
        "type",
        "version_code",
        "size",
        "format",
        "sha256",
        "file"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/switch_title_id"
              },
              "app_id": {
                "$ref": "common.json#/$defs/id16"
              },
              "type": {
                "enum": [
                  "base",
                  "update",
                  "dlc"
                ]
              },
              "format": {
                "enum": [
                  "nsp",
                  "nsz",
                  "xci",
                  "xcz"
                ]
              },
              "version_code": {
                "$ref": "common.json#/$defs/uint32"
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "base"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/switch_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "update"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/switch_update_id"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "$ref": "common.json#/$defs/profile_ids"
        }
      ]
    },
    "image": {
      "description": "An image (SPEC.md § 7.1). external: elsewhere than the server's origin, never sent credentials.",
      "type": "object",
      "properties": {
        "url": {
          "$ref": "common.json#/$defs/url"
        },
        "width": {
          "type": "integer",
          "minimum": 1
        },
        "height": {
          "type": "integer",
          "minimum": 1
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256"
        },
        "external": {
          "type": "boolean"
        }
      },
      "required": [
        "url"
      ]
    },
    "page": {
      "description": "A page of apps (SPEC.md § 6.2).",
      "type": "object",
      "properties": {
        "schema": {
          "$ref": "common.json#/$defs/schema1"
        },
        "items": {
          "type": "array",
          "maxItems": 1000,
          "items": {
            "$ref": "common.json#/$defs/app"
          }
        },
        "total": {
          "$ref": "common.json#/$defs/uint53"
        },
        "next": {
          "oneOf": [
            {
              "$ref": "common.json#/$defs/opaque"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "schema",
        "items",
        "next"
      ]
    },
    "genre": {
      "description": "A genre, from SPEC.md § 7.1's fixed list. A reader shows one it does not know as other; the schema lists today's.",
      "enum": [
        "action",
        "adventure",
        "rpg",
        "strategy",
        "simulation",
        "sports",
        "racing",
        "puzzle",
        "platformer",
        "shooter",
        "fighting",
        "music",
        "party",
        "education",
        "other"
      ]
    },
    "title": {
      "description": "What the server knows about a game on one platform (SPEC.md § 7.1).",
      "type": "object",
      "properties": {
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "language": {
          "$ref": "common.json#/$defs/language"
        },
        "name": {
          "$ref": "common.json#/$defs/name"
        },
        "publisher": {
          "$ref": "common.json#/$defs/name"
        },
        "developer": {
          "$ref": "common.json#/$defs/name"
        },
        "release": {
          "type": "string",
          "format": "date",
          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
          "description": "A date (SPEC.md § 2.3)."
        },
        "updated": {
          "$ref": "common.json#/$defs/time"
        },
        "genres": {
          "type": "array",
          "items": {
            "$ref": "common.json#/$defs/genre"
          },
          "uniqueItems": true
        },
        "tags": {
          "type": "array",
          "maxItems": 32,
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "players": {
          "type": "object",
          "properties": {
            "min": {
              "type": "integer",
              "minimum": 1
            },
            "max": {
              "type": "integer",
              "minimum": 1
            },
            "online": {
              "type": "boolean"
            },
            "online_max": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "ratings": {
          "$ref": "common.json#/$defs/ratings"
        },
        "languages": {
          "type": "array",
          "items": {
            "$ref": "common.json#/$defs/language"
          }
        },
        "summary": {
          "$ref": "common.json#/$defs/text"
        },
        "description": {
          "$ref": "common.json#/$defs/text"
        },
        "icon": {
          "$ref": "common.json#/$defs/image"
        },
        "banner": {
          "$ref": "common.json#/$defs/image"
        },
        "screenshots": {
          "type": "array",
          "maxItems": 16,
          "items": {
            "$ref": "common.json#/$defs/image"
          }
        },
        "video": {
          "type": "object",
          "properties": {
            "url": {
              "$ref": "common.json#/$defs/url"
            },
            "external": {
              "const": true
            }
          },
          "required": [
            "url",
            "external"
          ]
        },
        "atlas": {
          "$ref": "common.json#/$defs/atlas"
        }
      },
      "required": [
        "platform",
        "title_id",
        "name"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/switch_title_id"
              }
            }
          }
        },
        {
          "$ref": "common.json#/$defs/profile_ids"
        }
      ]
    },
    "device_path": {
      "description": "A path on the device (SPEC.md § 8.2): absolute, parts separated by /, none empty, . or ..; no backslash, colon, quote or control character; a part 255 bytes at most.",
      "type": "string",
      "maxLength": 1024,
      "pattern": "^(?!.*/\\.\\.?(?:/|$))(?:/[^/\\\\:\"\\u0000-\\u001f\\u007f]{1,255})+$"
    },
    "manifest_entry": {
      "description": "A file a homebrew installs (SPEC.md § 8.2).",
      "type": "object",
      "properties": {
        "path": {
          "$ref": "common.json#/$defs/device_path"
        },
        "size": {
          "$ref": "common.json#/$defs/uint53"
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256"
        }
      },
      "required": [
        "path",
        "size",
        "sha256"
      ]
    },
    "homebrew_id": {
      "description": "A homebrew's id (SPEC.md § 8.1): reverse-DNS, lower-case, stable.",
      "type": "string",
      "maxLength": 128,
      "pattern": "^[a-z][a-z0-9_-]*(?:\\.[a-z0-9][a-z0-9_-]*)+$"
    },
    "base64": {
      "type": "string",
      "pattern": "^[A-Za-z0-9+/]*={0,2}$"
    },
    "arch": {
      "description": "A package's architecture (SPEC.md § 8.2): aarch64, armhf, x86, x86_64, riscv64, or a later one of the same form, which a reader that does not know it treats as not its own.",
      "type": "string",
      "pattern": "^[a-z0-9_]{1,32}$"
    },
    "data_path": {
      "description": "Where a port's required file goes, relative to the port's root (SPEC.md § 8.6): parts separated by /, none empty, . or ..; no leading /, no drive letter, backslash, colon, quote or control character.",
      "type": "string",
      "maxLength": 1024,
      "pattern": "^(?!/)(?!(?:.*/)?\\.\\.?(?:/|$))[^/\\\\:\"\\u0000-\\u001f\\u007f]{1,255}(?:/[^/\\\\:\"\\u0000-\\u001f\\u007f]{1,255})*$"
    },
    "required_data": {
      "description": "A file a port needs from the user's own copy, or a group of alternatives (SPEC.md § 8.6); never served.",
      "oneOf": [
        {
          "allOf": [
            {
              "$ref": "common.json#/$defs/required_file"
            },
            {
              "not": {
                "required": [
                  "one_of"
                ]
              }
            }
          ]
        },
        {
          "type": "object",
          "properties": {
            "one_of": {
              "type": "array",
              "minItems": 2,
              "maxItems": 16,
              "items": {
                "type": "array",
                "minItems": 1,
                "maxItems": 64,
                "items": {
                  "$ref": "common.json#/$defs/required_file"
                }
              }
            },
            "optional": {
              "type": "boolean"
            }
          },
          "required": [
            "one_of"
          ]
        }
      ]
    },
    "package": {
      "type": "object",
      "properties": {
        "format": {
          "$ref": "common.json#/$defs/format"
        },
        "file": {
          "$ref": "common.json#/$defs/url"
        },
        "size": {
          "$ref": "common.json#/$defs/uint53"
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256"
        },
        "manifest_sha256": {
          "$ref": "common.json#/$defs/sha256",
          "description": "The SHA-256 of the manifest's canonical form (SPEC.md § 8.2)."
        },
        "path": {
          "$ref": "common.json#/$defs/device_path",
          "description": "A single file's place on the device; absent when the system's installer installs it."
        },
        "manifest": {
          "type": "array",
          "maxItems": 4096,
          "items": {
            "$ref": "common.json#/$defs/manifest_entry"
          }
        },
        "arch": {
          "description": "The architectures it runs on (SPEC.md § 8.2); absent: every one of its platform.",
          "type": "array",
          "minItems": 1,
          "maxItems": 8,
          "uniqueItems": true,
          "items": {
            "$ref": "common.json#/$defs/arch"
          }
        },
        "signature": {
          "$ref": "common.json#/$defs/signature",
          "description": "In packages only: this package's own signature (SPEC.md § 8.4)."
        },
        "signer_sha256": {
          "$ref": "common.json#/$defs/sha256",
          "description": "The SHA-256 of the platform's own signing certificate, where the profile has one (SPEC.md § 8.2, Annex A.5)."
        },
        "installed_size": {
          "$ref": "common.json#/$defs/uint53",
          "description": "What it takes once installed (SPEC.md § 8.2)."
        },
        "mirrors": {
          "$ref": "common.json#/$defs/mirrors"
        }
      },
      "required": [
        "format",
        "file",
        "size",
        "sha256",
        "manifest_sha256"
      ],
      "description": "A homebrew's package (SPEC.md § 8.2). A listing leaves manifest out."
    },
    "signature": {
      "type": "object",
      "properties": {
        "alg": {
          "const": "ed25519"
        },
        "public_key": {
          "$ref": "common.json#/$defs/base64",
          "minLength": 44,
          "maxLength": 44
        },
        "value": {
          "$ref": "common.json#/$defs/base64",
          "minLength": 88,
          "maxLength": 88
        }
      },
      "required": [
        "alg",
        "public_key",
        "value"
      ],
      "description": "An author's ed25519 signature (SPEC.md § 8.4)."
    },
    "homebrew": {
      "description": "A homebrew (SPEC.md § 8.1). A listing leaves package.manifest out (§ 8.2).",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/homebrew_id"
        },
        "system_id": {
          "description": "The platform's own id of the installed software, where it has one (SPEC.md § 8.1, Annex A).",
          "type": "string",
          "minLength": 1,
          "maxLength": 128
        },
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "kind": {
          "description": "What it is (SPEC.md § 8.1): app, game, port, emulator, tool, overlay, sysmodule or theme. A reader reads one it does not know as app.",
          "type": "string",
          "pattern": "^[a-z][a-z0-9_-]{0,31}$"
        },
        "name": {
          "$ref": "common.json#/$defs/name"
        },
        "author": {
          "$ref": "common.json#/$defs/name"
        },
        "genres": {
          "description": "Genres, from the titles' fixed list (SPEC.md § 7.1, § 8.1): meant for a game or a port.",
          "type": "array",
          "maxItems": 15,
          "uniqueItems": true,
          "items": {
            "$ref": "common.json#/$defs/genre"
          }
        },
        "tags": {
          "description": "Free words (SPEC.md § 8.1, § 13).",
          "type": "array",
          "maxItems": 32,
          "items": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "category": {
          "description": "Gone in draft 0.3: shelves come from kind and genres (SPEC.md § 8.1). A server does not write it.",
          "not": {}
        },
        "version": {
          "$ref": "common.json#/$defs/name"
        },
        "build": {
          "$ref": "common.json#/$defs/uint53"
        },
        "license": {
          "description": "An SPDX licence expression.",
          "type": "string",
          "maxLength": 256
        },
        "assets_license": {
          "description": "The licence of the assets it bundles, when it differs (SPDX, LicenseRef- allowed).",
          "type": "string",
          "maxLength": 256
        },
        "source": {
          "$ref": "common.json#/$defs/url"
        },
        "language": {
          "$ref": "common.json#/$defs/language"
        },
        "summary": {
          "$ref": "common.json#/$defs/text"
        },
        "description": {
          "$ref": "common.json#/$defs/text"
        },
        "icon": {
          "$ref": "common.json#/$defs/image"
        },
        "screenshots": {
          "type": "array",
          "maxItems": 16,
          "items": {
            "$ref": "common.json#/$defs/image"
          }
        },
        "requires": {
          "$ref": "common.json#/$defs/requires"
        },
        "updated": {
          "$ref": "common.json#/$defs/time"
        },
        "package": {
          "$ref": "common.json#/$defs/package"
        },
        "packages": {
          "description": "More packages of the same build, each for its arch (SPEC.md § 8.2).",
          "type": "array",
          "maxItems": 16,
          "items": {
            "allOf": [
              {
                "$ref": "common.json#/$defs/package"
              },
              {
                "required": [
                  "arch"
                ]
              }
            ]
          }
        },
        "signature": {
          "$ref": "common.json#/$defs/signature"
        },
        "port": {
          "$ref": "common.json#/$defs/port"
        },
        "atlas": {
          "$ref": "common.json#/$defs/atlas"
        },
        "ratings": {
          "$ref": "common.json#/$defs/ratings"
        }
      },
      "required": [
        "id",
        "platform",
        "kind",
        "name",
        "version",
        "build",
        "package"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "package": {
                "properties": {
                  "format": {
                    "enum": [
                      "nro",
                      "ovl",
                      "zip"
                    ]
                  }
                }
              },
              "packages": {
                "maxItems": 0
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "kind": {
                "const": "port"
              }
            },
            "required": [
              "kind"
            ]
          },
          "then": {
            "required": [
              "port"
            ]
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "linux"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "package": {
                "properties": {
                  "format": {
                    "const": "zip"
                  }
                },
                "not": {
                  "required": [
                    "path"
                  ]
                }
              },
              "packages": {
                "items": {
                  "properties": {
                    "format": {
                      "const": "zip"
                    }
                  }
                }
              },
              "system_id": false
            }
          }
        },
        {
          "$ref": "common.json#/$defs/system_ids"
        }
      ]
    },
    "save_kind": {
      "enum": [
        "account",
        "device",
        "bcat",
        "cache",
        "other"
      ]
    },
    "save": {
      "description": "A save backup (SPEC.md § 9.1).",
      "type": "object",
      "properties": {
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "save_id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        },
        "size": {
          "$ref": "common.json#/$defs/uint53"
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256"
        },
        "slot": {
          "$ref": "common.json#/$defs/slot"
        },
        "kind": {
          "$ref": "common.json#/$defs/save_kind"
        },
        "game_version_code": {
          "$ref": "common.json#/$defs/uint53"
        },
        "profile": {
          "$ref": "common.json#/$defs/profile"
        },
        "note": {
          "$ref": "common.json#/$defs/note"
        },
        "device": {
          "$ref": "common.json#/$defs/name"
        },
        "encryption": {
          "$ref": "common.json#/$defs/encryption"
        }
      },
      "required": [
        "platform",
        "title_id",
        "save_id",
        "created",
        "size",
        "sha256"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/switch_title_id"
              }
            }
          }
        },
        {
          "$ref": "common.json#/$defs/profile_ids"
        }
      ]
    },
    "cheat_set": {
      "description": "A set of cheats for a game's build (SPEC.md § 10).",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "build_id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._-]{1,64}$"
        },
        "source": {
          "$ref": "common.json#/$defs/name"
        },
        "note": {
          "$ref": "common.json#/$defs/note"
        },
        "updated": {
          "$ref": "common.json#/$defs/time"
        },
        "size": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1048576
        },
        "sha256": {
          "$ref": "common.json#/$defs/sha256"
        }
      },
      "required": [
        "id",
        "platform",
        "title_id",
        "size",
        "sha256"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/switch_title_id"
              },
              "build_id": {
                "type": "string",
                "pattern": "^[0-9A-F]{1,64}$"
              }
            },
            "required": [
              "build_id"
            ]
          }
        },
        {
          "$ref": "common.json#/$defs/profile_ids"
        },
        {
          "if": {
            "properties": {
              "platform": {
                "enum": [
                  "3ds",
                  "vita"
                ]
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "build_id": false
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "ps4"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "build_id": {
                "type": "string",
                "pattern": "^[0-9]{2}\\.[0-9]{2}(_[A-Za-z0-9.-]{1,32})?$"
              }
            },
            "required": [
              "build_id"
            ]
          }
        },
        {
          "not": {
            "properties": {
              "platform": {
                "enum": [
                  "android",
                  "linux"
                ]
              }
            },
            "required": [
              "platform"
            ]
          }
        }
      ]
    },
    "request": {
      "description": "A request for a game (SPEC.md § 11): open, then done or declined, which are final.",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "name": {
          "$ref": "common.json#/$defs/name"
        },
        "status": {
          "enum": [
            "open",
            "done",
            "declined"
          ]
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        },
        "updated": {
          "$ref": "common.json#/$defs/time",
          "description": "When its status last changed."
        },
        "reason": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512,
          "description": "Why an admin declined it, for its requester (SPEC.md § 11): only on a declined request."
        },
        "user": {
          "$ref": "common.json#/$defs/account_name",
          "description": "Whose it is: in the administration API only (SPEC.md § 5.7)."
        }
      },
      "required": [
        "id",
        "platform",
        "title_id",
        "status",
        "created"
      ],
      "allOf": [
        {
          "$ref": "common.json#/$defs/profile_ids"
        },
        {
          "if": {
            "required": [
              "reason"
            ]
          },
          "then": {
            "properties": {
              "status": {
                "const": "declined"
              }
            }
          }
        }
      ]
    },
    "slot": {
      "description": "One of a title's save folders (SPEC.md § 9.1), as the platform names it.",
      "type": "string",
      "pattern": "^[A-Za-z0-9._-]{1,64}$"
    },
    "required_file": {
      "description": "A file a port needs from the user (SPEC.md § 8.6).",
      "type": "object",
      "properties": {
        "path": {
          "$ref": "common.json#/$defs/data_path"
        },
        "size": {
          "$ref": "common.json#/$defs/uint53"
        },
        "accept": {
          "type": "array",
          "maxItems": 32,
          "items": {
            "type": "object",
            "properties": {
              "sha256": {
                "$ref": "common.json#/$defs/sha256"
              },
              "sha1": {
                "type": "string",
                "pattern": "^[0-9a-f]{40}$"
              },
              "md5": {
                "type": "string",
                "pattern": "^[0-9a-f]{32}$"
              },
              "label": {
                "$ref": "common.json#/$defs/name"
              }
            },
            "required": [
              "label"
            ],
            "anyOf": [
              {
                "required": [
                  "sha256"
                ]
              },
              {
                "required": [
                  "sha1"
                ]
              },
              {
                "required": [
                  "md5"
                ]
              }
            ]
          }
        },
        "hint": {
          "$ref": "common.json#/$defs/text"
        },
        "optional": {
          "type": "boolean"
        }
      },
      "required": [
        "path",
        "hint"
      ]
    },
    "port": {
      "description": "A game port's original game, engine and data (SPEC.md § 8.6).",
      "type": "object",
      "properties": {
        "original": {
          "type": "object",
          "properties": {
            "name": {
              "$ref": "common.json#/$defs/name"
            },
            "year": {
              "type": "integer",
              "minimum": 1950,
              "maximum": 2200
            },
            "developer": {
              "$ref": "common.json#/$defs/name"
            },
            "stores": {
              "type": "array",
              "maxItems": 32,
              "items": {
                "type": "object",
                "properties": {
                  "store": {
                    "$ref": "common.json#/$defs/platform"
                  },
                  "id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "url": {
                    "$ref": "common.json#/$defs/url"
                  }
                },
                "required": [
                  "store",
                  "url"
                ]
              }
            },
            "title": {
              "type": "object",
              "properties": {
                "platform": {
                  "$ref": "common.json#/$defs/platform"
                },
                "title_id": {
                  "$ref": "common.json#/$defs/id"
                }
              },
              "required": [
                "platform",
                "title_id"
              ]
            }
          },
          "required": [
            "name"
          ]
        },
        "engine": {
          "type": "object",
          "properties": {
            "name": {
              "$ref": "common.json#/$defs/name"
            },
            "version": {
              "$ref": "common.json#/$defs/name"
            },
            "source": {
              "$ref": "common.json#/$defs/url"
            },
            "license": {
              "description": "Only when it differs from the entry's.",
              "type": "string",
              "maxLength": 256
            }
          },
          "required": [
            "name"
          ]
        },
        "data_root": {
          "description": "An absolute folder, ending with /, under the profile's areas for ports' data (SPEC.md § 8.6): parts as in a device path.",
          "type": "string",
          "maxLength": 1024,
          "pattern": "^(?!.*/\\.\\.?/)(?:/[^/\\\\:\"\\u0000-\\u001f\\u007f]{1,255})+/$"
        },
        "assets": {
          "description": "included, demo_included, free_external or user_owned; a reader reads one it does not know as user_owned.",
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]{0,31}$"
        },
        "requires_data": {
          "type": "array",
          "maxItems": 256,
          "items": {
            "$ref": "common.json#/$defs/required_data"
          }
        }
      },
      "required": [
        "original",
        "engine",
        "data_root",
        "assets",
        "requires_data"
      ]
    },
    "3ds_title_id": {
      "description": "A 3DS game's title id (SPEC.md Annex A.2): 16 upper-case hex digits, 00040000 (a game) or 00040002 (a demo) first.",
      "type": "string",
      "pattern": "^0004000[02][0-9A-F]{8}$"
    },
    "3ds_app_id": {
      "description": "A 3DS package's id (SPEC.md Annex A.2): its game's, an update's (0004000E) or an add-on's (0004008C).",
      "type": "string",
      "pattern": "^0004(0000|0002|000E|008C)[0-9A-F]{8}$"
    },
    "vita_title_id": {
      "description": "A Vita title id (SPEC.md Annex A.3): nine upper-case letters and digits.",
      "type": "string",
      "pattern": "^[A-Z0-9]{9}$"
    },
    "vita_content_id": {
      "description": "A Vita add-on's content id (SPEC.md Annex A.3).",
      "type": "string",
      "pattern": "^[A-Z]{2}[0-9]{4}-[A-Z0-9]{9}_[0-9]{2}-[A-Z0-9]{16}$"
    },
    "ps4_title_id": {
      "description": "A PS4 title id (SPEC.md Annex A.4): four upper-case letters and five digits.",
      "type": "string",
      "pattern": "^[A-Z]{4}[0-9]{5}$"
    },
    "ps4_content_id": {
      "description": "A PS4 add-on's content id (SPEC.md Annex A.4).",
      "type": "string",
      "pattern": "^[A-Z]{2}[0-9]{4}-[A-Z]{4}[0-9]{5}_[0-9]{2}-[A-Z0-9]{16}$"
    },
    "android_package": {
      "description": "An Android package name (SPEC.md Annex A.5).",
      "type": "string",
      "pattern": "^[a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)+$"
    },
    "profile_ids": {
      "description": "The forms of title_id and app_id on every profile (SPEC.md Annex A): the Switch's (A.1) and the drafts' (A.2 to A.5), for any document that carries platform and those ids. Linux (A.6) has no form beyond the core's, and open platforms none (A.7).",
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "const": "switch"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/switch_title_id"
              },
              "app_id": {
                "$ref": "common.json#/$defs/id16"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "3ds"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/3ds_title_id"
              },
              "app_id": {
                "$ref": "common.json#/$defs/3ds_app_id"
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "base"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/3ds_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "update"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "pattern": "^0004000E"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "dlc"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "pattern": "^0004008C"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "vita"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/vita_title_id"
              },
              "app_id": {
                "anyOf": [
                  {
                    "$ref": "common.json#/$defs/vita_title_id"
                  },
                  {
                    "$ref": "common.json#/$defs/vita_content_id"
                  }
                ]
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "base"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/vita_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "update"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/vita_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "dlc"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/vita_content_id"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "ps4"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/ps4_title_id"
              },
              "app_id": {
                "anyOf": [
                  {
                    "$ref": "common.json#/$defs/ps4_title_id"
                  },
                  {
                    "$ref": "common.json#/$defs/ps4_content_id"
                  }
                ]
              }
            },
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "base"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/ps4_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "update"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/ps4_title_id"
                    }
                  }
                }
              },
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "dlc"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "app_id": {
                      "$ref": "common.json#/$defs/ps4_content_id"
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "android"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "title_id": {
                "$ref": "common.json#/$defs/android_package"
              },
              "app_id": {
                "$ref": "common.json#/$defs/android_package"
              }
            }
          }
        }
      ]
    },
    "dotted": {
      "description": "A dotted version, compared part by part as numbers (SPEC.md § 8.7).",
      "type": "string",
      "pattern": "^[0-9]+(\\.[0-9]+){0,3}$"
    },
    "requires": {
      "description": "What the device needs (SPEC.md § 8.7). min and gpu are conditions a client checks before it offers a package; a key it cannot read gives a warning, not a refusal. A server keeps the keys it does not know.",
      "type": "object",
      "properties": {
        "text": {
          "$ref": "common.json#/$defs/text"
        },
        "min": {
          "description": "The lowest the device may have: the profile's keys (Annex A) as dotted versions, and glibc, ram_mb and screen, which any profile may use.",
          "type": "object",
          "properties": {
            "glibc": {
              "$ref": "common.json#/$defs/dotted"
            },
            "ram_mb": {
              "type": "integer",
              "minimum": 1,
              "maximum": 16777216
            },
            "screen": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,5}x[1-9][0-9]{0,5}$"
            },
            "firmware": {
              "$ref": "common.json#/$defs/dotted"
            },
            "atmosphere": {
              "$ref": "common.json#/$defs/dotted"
            },
            "luma": {
              "$ref": "common.json#/$defs/dotted"
            },
            "goldhen": {
              "$ref": "common.json#/$defs/dotted"
            },
            "sdk": {
              "$ref": "common.json#/$defs/dotted"
            }
          },
          "propertyNames": {
            "pattern": "^[a-z][a-z0-9_-]{0,31}$"
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              },
              {
                "type": "integer",
                "minimum": 0
              }
            ]
          }
        },
        "gpu": {
          "description": "Graphics interfaces, at least one of which the device must offer. A later version may add names; the schema lists today's.",
          "type": "array",
          "minItems": 1,
          "maxItems": 8,
          "uniqueItems": true,
          "items": {
            "enum": [
              "gles2",
              "gles3",
              "gl",
              "vulkan"
            ]
          }
        },
        "homebrew": {
          "type": "array",
          "maxItems": 32,
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "$ref": "common.json#/$defs/homebrew_id"
              },
              "min_build": {
                "$ref": "common.json#/$defs/uint53"
              }
            },
            "required": [
              "id",
              "min_build"
            ]
          }
        }
      },
      "required": [
        "text"
      ]
    },
    "atlas": {
      "description": "A game's id in Atlas (SPEC.md § 6.1): its Wikidata item, the key of Atlas's links.json. A hint, never an identity.",
      "type": "string",
      "pattern": "^Q[1-9][0-9]{0,15}$"
    },
    "ratings": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "system": {
            "type": "string",
            "pattern": "^[A-Z][A-Z0-9-]{1,15}$"
          },
          "rating": {
            "type": "string",
            "minLength": 1,
            "maxLength": 16
          }
        },
        "required": [
          "system",
          "rating"
        ]
      },
      "description": "Age ratings, each an organisation's short name and its rating as it writes it (SPEC.md § 7.1); rating caps read them (§ 5.6)."
    },
    "rating_cap": {
      "description": "A rating cap a token carries (SPEC.md § 5.6): an age, or a rating of one system; unrated says what becomes of what has no rating the table reads.",
      "type": "object",
      "properties": {
        "age": {
          "type": "integer",
          "minimum": 0,
          "maximum": 99
        },
        "system": {
          "type": "string",
          "pattern": "^[A-Z][A-Z0-9-]{1,15}$"
        },
        "rating": {
          "type": "string",
          "minLength": 1,
          "maxLength": 16
        },
        "unrated": {
          "enum": [
            "show",
            "hide"
          ]
        }
      },
      "oneOf": [
        {
          "required": [
            "age"
          ],
          "not": {
            "anyOf": [
              {
                "required": [
                  "system"
                ]
              },
              {
                "required": [
                  "rating"
                ]
              }
            ]
          }
        },
        {
          "required": [
            "system",
            "rating"
          ],
          "not": {
            "required": [
              "age"
            ]
          }
        }
      ]
    },
    "device_key": {
      "description": "A device's public key, made at pairing (SPEC.md § 5.4): Ed25519, its 32 bytes in base64.",
      "type": "object",
      "properties": {
        "alg": {
          "const": "ed25519"
        },
        "public_key": {
          "type": "string",
          "pattern": "^[A-Za-z0-9+/]{43}=$"
        }
      },
      "required": [
        "alg",
        "public_key"
      ]
    },
    "short_fingerprint": {
      "description": "A key's short fingerprint (SPEC.md § 5.3): 16 upper-case hex digits in groups of 4.",
      "type": "string",
      "pattern": "^[0-9A-F]{4}( [0-9A-F]{4}){3}$"
    },
    "invitation_code": {
      "description": "An invitation's code (SPEC.md § 5.5): 16 to 32 symbols of the pairing alphabet, in groups of 4.",
      "type": "string",
      "pattern": "^[2-9A-HJ-NP-Z]{4}(-[2-9A-HJ-NP-Z]{4}){3,7}$"
    },
    "account_name": {
      "description": "An account's name (SPEC.md § 5.7): 1 to 64 letters, digits, '.', '_' and '-'.",
      "type": "string",
      "pattern": "^[A-Za-z0-9._-]{1,64}$"
    },
    "scopes": {
      "type": "array",
      "items": {
        "$ref": "common.json#/$defs/scope"
      },
      "uniqueItems": true
    },
    "admin_user": {
      "description": "An account, as the administration API shows it (SPEC.md § 5.7). No password, nor its hash.",
      "type": "object",
      "properties": {
        "name": {
          "$ref": "common.json#/$defs/account_name"
        },
        "state": {
          "enum": [
            "active",
            "frozen"
          ]
        },
        "scopes": {
          "$ref": "common.json#/$defs/scopes"
        },
        "devices": {
          "$ref": "common.json#/$defs/uint32"
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "password"
            ]
          },
          {
            "required": [
              "token"
            ]
          }
        ]
      },
      "required": [
        "name",
        "state",
        "scopes"
      ]
    },
    "admin_device": {
      "description": "A paired device and its token, as the administration API shows it (SPEC.md § 5.7). Never the token, nor its hash.",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "user": {
          "$ref": "common.json#/$defs/account_name"
        },
        "device": {
          "$ref": "common.json#/$defs/name"
        },
        "scopes": {
          "$ref": "common.json#/$defs/scopes"
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        },
        "expires": {
          "$ref": "common.json#/$defs/time"
        },
        "bound": {
          "type": "boolean"
        },
        "key": {
          "$ref": "common.json#/$defs/short_fingerprint"
        },
        "rating_cap": {
          "$ref": "common.json#/$defs/rating_cap"
        },
        "invitation": {
          "$ref": "common.json#/$defs/opaque"
        },
        "last_used": {
          "$ref": "common.json#/$defs/time"
        }
      },
      "not": {
        "anyOf": [
          {
            "required": [
              "token"
            ]
          },
          {
            "required": [
              "token_hash"
            ]
          }
        ]
      },
      "required": [
        "id",
        "user",
        "device",
        "scopes",
        "created",
        "bound"
      ]
    },
    "admin_pairing": {
      "description": "A pairing waiting for approval (SPEC.md § 5.7). Its id is not its poll address.",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "code": {
          "type": "string",
          "pattern": "^[2-9A-HJ-NP-Z]{4}(-[2-9A-HJ-NP-Z]{4}){1,7}$"
        },
        "device": {
          "$ref": "common.json#/$defs/name"
        },
        "scopes": {
          "$ref": "common.json#/$defs/scopes"
        },
        "key": {
          "$ref": "common.json#/$defs/short_fingerprint"
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        },
        "expires": {
          "$ref": "common.json#/$defs/time"
        }
      },
      "not": {
        "required": [
          "poll"
        ]
      },
      "required": [
        "id",
        "code",
        "device",
        "scopes",
        "expires"
      ]
    },
    "invitation": {
      "description": "An invitation (SPEC.md § 5.5).",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "code": {
          "$ref": "common.json#/$defs/invitation_code"
        },
        "link": {
          "$ref": "common.json#/$defs/url"
        },
        "user": {
          "$ref": "common.json#/$defs/account_name"
        },
        "scopes": {
          "$ref": "common.json#/$defs/scopes",
          "minItems": 1
        },
        "expires": {
          "$ref": "common.json#/$defs/time"
        },
        "devices": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        },
        "used": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100
        },
        "rating_cap": {
          "$ref": "common.json#/$defs/rating_cap"
        },
        "note": {
          "$ref": "common.json#/$defs/note"
        },
        "created": {
          "$ref": "common.json#/$defs/time"
        }
      },
      "required": [
        "id",
        "code",
        "link",
        "user",
        "scopes",
        "expires",
        "devices",
        "used"
      ]
    },
    "mirror": {
      "description": "Another address of a file's exact bytes (SPEC.md § 19.2): HTTPS, or HTTP at an address of a private network (10/8, 172.16/12, 192.168/16, fc00::/7, fe80::/10), or of loopback for testing (127/8, ::1; SPEC.md § 2). A client checks what it gives by the file's size and SHA-256.",
      "type": "object",
      "properties": {
        "url": {
          "type": "string",
          "maxLength": 4096,
          "pattern": "^(https://[^/?#\\s]+|http://(10(\\.[0-9]{1,3}){3}|127(\\.[0-9]{1,3}){3}|\\[::1\\]|192\\.168(\\.[0-9]{1,3}){2}|172\\.(1[6-9]|2[0-9]|3[01])(\\.[0-9]{1,3}){2}|\\[[fF][cdCD][0-9a-fA-F:]*\\]|\\[[fF][eE][89abAB][0-9a-fA-F:%.a-zA-Z]*\\])(:[0-9]{1,5})?)(/[^\\s]*)?$"
        }
      },
      "required": [
        "url"
      ]
    },
    "mirrors": {
      "description": "Other addresses of the same bytes (SPEC.md § 19.2), 8 at most.",
      "type": "array",
      "maxItems": 8,
      "items": {
        "$ref": "common.json#/$defs/mirror"
      }
    },
    "key_id": {
      "description": "A save key's id (SPEC.md § 9.4): the first 8 bytes of HKDF-SHA-256(key, info \"lantern-save-e2e-1 key id\"), 16 lower-case hex digits.",
      "type": "string",
      "pattern": "^[0-9a-f]{16}$"
    },
    "encryption": {
      "description": "An end-to-end encrypted backup's metadata (SPEC.md § 9.4): its scheme and key id, in clear.",
      "type": "object",
      "properties": {
        "scheme": {
          "const": "lantern-save-e2e-1"
        },
        "key_id": {
          "$ref": "common.json#/$defs/key_id"
        }
      },
      "required": [
        "scheme",
        "key_id"
      ]
    },
    "sync_time": {
      "description": "When a sync item changed (SPEC.md § 20.2): UTC, to the millisecond.",
      "type": "string",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,3})?Z$"
    },
    "device_id": {
      "description": "A device's id (SPEC.md § 5.7), its key in the sync collection installed.",
      "type": "string",
      "pattern": "^d_[0-9a-f]{16}$"
    },
    "wish": {
      "description": "A game wished for (SPEC.md § 20.2).",
      "type": "object",
      "properties": {
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "title_id": {
          "$ref": "common.json#/$defs/id"
        },
        "name": {
          "$ref": "common.json#/$defs/name"
        },
        "note": {
          "$ref": "common.json#/$defs/note"
        }
      },
      "required": [
        "platform",
        "title_id"
      ],
      "allOf": [
        {
          "$ref": "common.json#/$defs/profile_ids"
        }
      ]
    },
    "installed": {
      "description": "What a device has installed (SPEC.md § 20.2), sent only with its user's consent (§ 20.1).",
      "type": "object",
      "properties": {
        "device": {
          "$ref": "common.json#/$defs/name"
        },
        "platform": {
          "$ref": "common.json#/$defs/platform"
        },
        "apps": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "app_id": {
                "$ref": "common.json#/$defs/id"
              },
              "version_code": {
                "$ref": "common.json#/$defs/uint53"
              }
            },
            "required": [
              "app_id",
              "version_code"
            ]
          }
        },
        "homebrew": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "$ref": "common.json#/$defs/homebrew_id"
              },
              "build": {
                "$ref": "common.json#/$defs/uint53"
              }
            },
            "required": [
              "id",
              "build"
            ]
          }
        }
      },
      "required": [
        "device",
        "platform"
      ]
    },
    "sync_item": {
      "description": "An item of a sync collection (SPEC.md § 20.2): a value, or a deletion.",
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512
        },
        "value": {},
        "deleted": {
          "const": true
        },
        "updated": {
          "$ref": "common.json#/$defs/sync_time"
        },
        "rev": {
          "$ref": "common.json#/$defs/uint53"
        }
      },
      "required": [
        "key",
        "updated"
      ],
      "oneOf": [
        {
          "required": [
            "value"
          ],
          "not": {
            "required": [
              "deleted"
            ]
          }
        },
        {
          "required": [
            "deleted"
          ],
          "not": {
            "required": [
              "value"
            ]
          }
        }
      ]
    },
    "generation": {
      "description": "The generation of an account's sync data (SPEC.md § 20.3): it changes only when the data is deleted.",
      "type": "string",
      "minLength": 1,
      "maxLength": 128
    },
    "collection": {
      "description": "A sync collection (SPEC.md § 20.2); a later version may add others.",
      "type": "string",
      "pattern": "^[a-z][a-z0-9_]{0,31}$"
    },
    "event": {
      "description": "An event (SPEC.md § 18): its id, a token of /v1/changes, its type and its document. A reader ignores a type it does not know.",
      "type": "object",
      "properties": {
        "id": {
          "$ref": "common.json#/$defs/opaque"
        },
        "event": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]{0,31}$"
        },
        "data": {
          "type": "object",
          "properties": {
            "schema": {
              "$ref": "common.json#/$defs/schema1"
            }
          },
          "required": [
            "schema"
          ]
        }
      },
      "required": [
        "id",
        "event",
        "data"
      ],
      "allOf": [
        {
          "if": {
            "properties": {
              "event": {
                "const": "library"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "families": {
                    "type": "array",
                    "minItems": 1,
                    "uniqueItems": true,
                    "items": {
                      "type": "string",
                      "pattern": "^[a-z][a-z0-9_]{0,31}$"
                    }
                  },
                  "platforms": {
                    "type": "array",
                    "minItems": 1,
                    "uniqueItems": true,
                    "items": {
                      "$ref": "common.json#/$defs/platform"
                    }
                  }
                },
                "required": [
                  "families",
                  "platforms"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "request"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "id": {
                    "$ref": "common.json#/$defs/opaque"
                  },
                  "platform": {
                    "$ref": "common.json#/$defs/platform"
                  },
                  "title_id": {
                    "$ref": "common.json#/$defs/id"
                  },
                  "status": {
                    "enum": [
                      "open",
                      "done",
                      "declined"
                    ]
                  },
                  "deleted": {
                    "const": true
                  },
                  "user": {
                    "$ref": "common.json#/$defs/account_name",
                    "description": "Whose request: to a caller with the scope admin (SPEC.md § 18.2)."
                  }
                },
                "required": [
                  "id"
                ],
                "oneOf": [
                  {
                    "required": [
                      "status"
                    ]
                  },
                  {
                    "required": [
                      "deleted"
                    ]
                  }
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "pairing"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "id": {
                    "$ref": "common.json#/$defs/opaque"
                  },
                  "code": {
                    "type": "string"
                  },
                  "device": {
                    "$ref": "common.json#/$defs/name"
                  },
                  "key": {
                    "$ref": "common.json#/$defs/short_fingerprint"
                  },
                  "expires": {
                    "$ref": "common.json#/$defs/time"
                  }
                },
                "required": [
                  "id",
                  "code",
                  "device",
                  "expires"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "save"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "platform": {
                    "$ref": "common.json#/$defs/platform"
                  },
                  "title_id": {
                    "$ref": "common.json#/$defs/id"
                  },
                  "save_id": {
                    "$ref": "common.json#/$defs/opaque"
                  },
                  "created": {
                    "$ref": "common.json#/$defs/time"
                  },
                  "device": {
                    "$ref": "common.json#/$defs/name"
                  }
                },
                "required": [
                  "platform",
                  "title_id",
                  "save_id"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "sync"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "collection": {
                    "$ref": "common.json#/$defs/collection"
                  },
                  "rev": {
                    "$ref": "common.json#/$defs/uint53"
                  }
                },
                "required": [
                  "collection",
                  "rev"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "event": {
                "const": "shutdown"
              }
            },
            "required": [
              "event"
            ]
          },
          "then": {
            "properties": {
              "data": {
                "properties": {
                  "retry": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          }
        }
      ]
    },
    "system_ids": {
      "description": "A homebrew's system_id, of its profile's form (SPEC.md Annex A): a 3DS title id, a Vita or PS4 title id, an Android package name; none on the Switch and on Linux.",
      "allOf": [
        {
          "if": {
            "properties": {
              "platform": {
                "enum": [
                  "switch",
                  "linux"
                ]
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "system_id": false
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "3ds"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "system_id": {
                "type": "string",
                "pattern": "^0004000[0-9A-F]{9}$"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "vita"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "system_id": {
                "$ref": "common.json#/$defs/vita_title_id"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "ps4"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "system_id": {
                "$ref": "common.json#/$defs/ps4_title_id"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "platform": {
                "const": "android"
              }
            },
            "required": [
              "platform"
            ]
          },
          "then": {
            "properties": {
              "system_id": {
                "$ref": "common.json#/$defs/android_package"
              }
            }
          }
        }
      ]
    }
  }
}
