{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://byrdathome.org/schema/items.schema.json",
  "title": "byrd@home items",
  "description": "The public feed of the byrd@home content model (/items.json): STEM for home lessons and activities, simulations, family printables, the Byrd Academy STEM and AI curriculum units, the Nest cards for ages zero to five, the curriculum overviews, the access guide and the career lanes. Every text is a pair of English and Spanish. Every address is a path on the feed's home. Permanent IDs: the prefix names the kind and never changes, and an ID is never reused or renumbered. Free BYRD, CC BY 4.0.",
  "type": "object",
  "required": ["version", "updated", "name", "home", "license", "feeds", "vocabulary", "items"],
  "properties": {
    "$schema": { "type": "string" },
    "_": { "type": "string" },
    "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
    "updated": { "$ref": "#/$defs/date" },
    "name": { "const": "byrd@home" },
    "tagline": { "$ref": "#/$defs/text" },
    "home": { "type": "string", "format": "uri" },
    "license": {
      "type": "object",
      "required": ["collection", "name", "url", "credit"],
      "properties": { "collection": { "const": "Free BYRD" }, "name": { "const": "CC BY 4.0" }, "url": { "$ref": "#/$defs/textUrl" }, "credit": { "$ref": "#/$defs/text" } }
    },
    "feeds": { "type": "object", "required": ["items", "schema", "changelog"] },
    "vocabulary": { "type": "object", "required": ["formats", "kinds", "cost", "ages", "components"] },
    "items": { "type": "array", "items": { "$ref": "#/$defs/item" } }
  },
  "$defs": {
    "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
    "path": { "type": "string", "pattern": "^/[^\\s]*$" },
    "text": { "type": "object", "required": ["en", "es"], "properties": { "en": { "type": "string", "minLength": 1 }, "es": { "type": "string", "minLength": 1 } } },
    "textUrl": { "type": "object", "required": ["en", "es"], "properties": { "en": { "type": "string", "format": "uri" }, "es": { "type": "string", "format": "uri" } } },
    "texts": { "type": "array", "items": { "$ref": "#/$defs/text" } },
    "nullableText": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/text" }] },
    "ids": { "type": "array", "items": { "type": "string", "pattern": "^(?:BH-\\d{4}|SIM-\\d{4}|PRINT-\\d{4}|TOUR-\\d{4}|(?:STEM|AI)-(?:ES|JH|HS|FX)-\\d{2}|NEST-(?:HA|NE|BR|FL|FF)-\\d{2}|CUR-(?:STEM|AI|NEST)|GUIDE-\\d{4}|PATH-\\d{4})$" } },
    "format": { "enum": ["read", "watch", "do", "simulate", "tour"] },
    "cost": { "enum": ["free", "home", "few", "equip"] },
    "picture": { "type": "object", "required": ["src", "small", "alt"], "properties": { "src": { "$ref": "#/$defs/path" }, "small": { "$ref": "#/$defs/path" }, "alt": { "$ref": "#/$defs/text" } } },
    "item": {
      "type": "object",
      "required": ["id", "kind", "title", "summary", "source", "verified", "url", "formats", "minutes", "audience", "license", "credit", "next"],
      "properties": {
        "id": { "type": "string" },
        "kind": { "enum": ["lesson", "activity", "simulation", "printable", "tour", "unit", "card", "curriculum", "guide", "pathway"] },
        "title": { "$ref": "#/$defs/text" },
        "summary": { "$ref": "#/$defs/text" },
        "components": { "type": "string", "pattern": "^m?e?s?d?$" },
        "source": { "type": "string", "minLength": 1 },
        "verified": { "$ref": "#/$defs/date" },
        "url": { "$ref": "#/$defs/path" },
        "formats": { "type": "array", "items": { "$ref": "#/$defs/format" }, "minItems": 1 },
        "minutes": { "type": "object", "propertyNames": { "$ref": "#/$defs/format" }, "additionalProperties": { "type": "integer", "minimum": 1 } },
        "audience": { "type": "object", "required": ["from", "bands"], "properties": { "from": { "type": "integer", "minimum": 0 }, "to": { "type": ["integer", "null"] }, "bands": { "type": "array", "items": { "enum": ["little", "kids", "teens"] } } } },
        "costs": { "type": "array", "items": { "$ref": "#/$defs/cost" } },
        "license": { "type": "object", "required": ["collection", "name", "url"], "properties": { "collection": { "const": "Free BYRD" }, "name": { "const": "CC BY 4.0" }, "url": { "const": "https://creativecommons.org/licenses/by/4.0/" } } },
        "credit": { "$ref": "#/$defs/text" },
        "next": { "$ref": "#/$defs/ids" },
        "simulations": { "$ref": "#/$defs/ids" },
        "tours": { "$ref": "#/$defs/ids" },
        "at_home": { "$ref": "#/$defs/ids" },
        "harder": { "$ref": "#/$defs/text" },
        "younger": { "$ref": "#/$defs/text" },
        "media": {
          "type": "object",
          "properties": {
            "poster": { "$ref": "#/$defs/picture" },
            "photo": { "$ref": "#/$defs/picture" },
            "video": { "type": "object", "required": ["src", "type", "seconds", "captions"], "properties": { "src": { "$ref": "#/$defs/path" }, "type": { "const": "video/mp4" }, "seconds": { "type": "number" }, "captions": { "type": "object", "required": ["en", "es"], "properties": { "en": { "$ref": "#/$defs/path" }, "es": { "$ref": "#/$defs/path" } } } } },
            "simulation": { "type": "object", "required": ["page", "script", "drawing"], "properties": { "page": { "$ref": "#/$defs/path" }, "kit": { "$ref": "#/$defs/path" }, "script": { "$ref": "#/$defs/path" }, "drawing": { "$ref": "#/$defs/path" } } },
            "tour": { "type": "object", "required": ["page", "script", "scenes"], "properties": { "page": { "$ref": "#/$defs/path" }, "script": { "$ref": "#/$defs/path" }, "scenes": { "type": "array", "minItems": 3, "items": { "$ref": "#/$defs/path" } } } }
          }
        }
      },
      "allOf": [
        { "if": { "properties": { "kind": { "enum": ["lesson", "activity"] } } }, "then": {
          "properties": {
            "id": { "pattern": "^BH-\\d{4}$" },
            "ages": { "type": "object", "required": ["every", "from", "to", "note"], "properties": { "every": { "type": "boolean" }, "from": { "type": "integer" }, "to": { "type": ["integer", "null"] }, "note": { "$ref": "#/$defs/text" } } },
            "cost": { "enum": ["free", "home", "few"] },
            "related": { "$ref": "#/$defs/ids" },
            "units": { "$ref": "#/$defs/ids" },
            "read": { "type": "object", "required": ["idea", "challenge", "experiment", "safety"], "properties": { "idea": { "$ref": "#/$defs/text" }, "challenge": { "$ref": "#/$defs/text" }, "experiment": { "$ref": "#/$defs/texts" }, "safety": { "$ref": "#/$defs/text" } } },
            "do": { "type": "object", "required": ["minutes", "materials", "steps"], "properties": { "minutes": { "type": "integer", "minimum": 1 }, "materials": { "$ref": "#/$defs/texts" }, "steps": { "$ref": "#/$defs/texts" } } }
          },
          "required": ["ages", "cost", "related", "read", "do", "components"] } },
        { "if": { "properties": { "kind": { "const": "lesson" } } }, "then": { "required": ["episode", "date", "poster", "media"] } },
        { "if": { "properties": { "kind": { "const": "activity" } } }, "then": { "required": ["units"] } },
        { "if": { "properties": { "kind": { "const": "simulation" } } }, "then": {
          "properties": {
            "id": { "pattern": "^SIM-\\d{4}$" },
            "slug": { "type": "string", "pattern": "^[a-z][a-z-]+$" },
            "style": { "enum": ["simulation", "visualization"] },
            "topic": { "type": "string" },
            "for": { "$ref": "#/$defs/ids" },
            "challenge": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/text" } },
            "explain": { "$ref": "#/$defs/texts" },
            "try": { "$ref": "#/$defs/texts" },
            "note": { "$ref": "#/$defs/text" },
            "still": { "type": "object", "required": ["width", "height", "alt"], "properties": { "width": { "type": "integer" }, "height": { "type": "integer" }, "alt": { "$ref": "#/$defs/text" } } }
          },
          "required": ["slug", "style", "topic", "for", "challenge", "explain", "try", "note", "still", "media"] } },
        { "if": { "properties": { "kind": { "const": "tour" } } }, "then": {
          "required": ["slug", "topic", "for", "minutes", "stops", "sources", "media"],
          "properties": {
            "id": { "pattern": "^TOUR-\\d{4}$" },
            "slug": { "type": "string", "pattern": "^[a-z][a-z0-9-]+$" },
            "topic": { "type": "string" },
            "for": { "$ref": "#/$defs/ids" },
            "minutes": { "type": "object", "required": ["tour"] },
            "stops": { "type": "array", "minItems": 3, "items": { "type": "object", "required": ["title", "text", "look", "deeper", "home", "source", "alt"], "properties": {
              "title": { "$ref": "#/$defs/text" }, "text": { "$ref": "#/$defs/texts" }, "look": { "$ref": "#/$defs/texts" },
              "deeper": { "oneOf": [{ "type": "null" }, { "type": "object", "required": ["x", "y"], "properties": { "x": { "type": "number", "minimum": 0, "maximum": 1 }, "y": { "type": "number", "minimum": 0, "maximum": 1 } } }] },
              "home": { "oneOf": [{ "type": "null" }, { "type": "string" }] }, "source": { "type": "integer", "minimum": 0 }, "alt": { "$ref": "#/$defs/text" } } } },
            "sources": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["name", "url", "checked"], "properties": { "name": { "type": "string" }, "url": { "type": "string", "format": "uri" }, "checked": { "$ref": "#/$defs/date" } } } }
          } } },
        { "if": { "properties": { "kind": { "const": "printable" } } }, "then": {
          "required": ["slug", "for", "sheet"],
          "properties": {
            "id": { "pattern": "^PRINT-\\d{4}$" },
            "slug": { "type": "string", "pattern": "^[a-z][a-z-]+$" },
            "for": { "$ref": "#/$defs/ids" },
            "sheet": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["type"], "properties": { "type": { "enum": ["lead", "callout", "note", "blanks", "section", "checks", "cards", "steps", "key", "week", "moves"] } } } }
          } } },
        { "if": { "properties": { "kind": { "const": "unit" } } }, "then": {
          "properties": {
            "id": { "pattern": "^(?:STEM|AI)-(?:ES|JH|HS|FX)-\\d{2}$" },
            "discipline": { "enum": ["stem", "ai"] },
            "band": { "enum": ["es", "jh", "hs", "fx"] },
            "grades": { "type": "object", "required": ["from", "to"], "properties": { "from": { "type": "integer" }, "to": { "type": "integer" } } },
            "order": { "type": "integer", "minimum": 1 },
            "season": { "enum": ["fall", "spring", null] },
            "sessions": { "type": "integer", "minimum": 1 },
            "question": { "$ref": "#/$defs/text" },
            "story": { "$ref": "#/$defs/text" },
            "goals": { "$ref": "#/$defs/texts" },
            "vocabulary": { "$ref": "#/$defs/texts" },
            "math": { "$ref": "#/$defs/nullableText" },
            "ideas": { "type": "array", "items": { "enum": ["perception", "representation", "learning", "interaction", "society"] } },
            "standards": { "$ref": "#/$defs/texts" },
            "activities": { "$ref": "#/$defs/texts" },
            "materials": { "$ref": "#/$defs/texts" },
            "equipment": { "$ref": "#/$defs/texts" },
            "fallback": { "$ref": "#/$defs/nullableText" },
            "misconceptions": { "$ref": "#/$defs/texts" },
            "product": { "$ref": "#/$defs/text" },
            "safety": { "$ref": "#/$defs/nullableText" },
            "home": { "$ref": "#/$defs/nullableText" },
            "menu": { "$ref": "#/$defs/texts" },
            "cost": { "enum": ["home", "few", "equip"] }
          },
          "required": ["discipline", "band", "grades", "order", "season", "sessions", "question", "story", "goals", "activities", "materials", "equipment", "misconceptions", "product", "cost", "components"] } },
        { "if": { "properties": { "kind": { "const": "card" } } }, "then": {
          "properties": {
            "id": { "pattern": "^NEST-(?:HA|NE|BR|FL|FF)-\\d{2}$" },
            "code": { "type": "string" },
            "stage": { "enum": ["hatchling", "nestling", "brancher", "fledgling", "firstflight"] },
            "area": { "enum": ["explore", "build", "notice", "count", "tinker", "grow"] },
            "ready": { "$ref": "#/$defs/text" },
            "materials": { "$ref": "#/$defs/texts" },
            "level": { "enum": ["A", "B", "C"] },
            "safety": { "$ref": "#/$defs/text" },
            "allergens": { "$ref": "#/$defs/nullableText" },
            "poison": { "type": "boolean" },
            "steps": { "$ref": "#/$defs/texts" },
            "say": { "$ref": "#/$defs/text" },
            "listen": { "$ref": "#/$defs/text" },
            "further": { "$ref": "#/$defs/text" },
            "moveon": { "$ref": "#/$defs/text" },
            "time": { "$ref": "#/$defs/text" },
            "follow": { "$ref": "#/$defs/nullableText" },
            "ladder": { "$ref": "#/$defs/ids" },
            "check": { "type": "object", "required": ["result"], "properties": { "result": { "enum": ["pass", "fixed"] }, "fixes": { "$ref": "#/$defs/texts" } } }
          },
          "required": ["code", "stage", "area", "ready", "level", "safety", "poison", "steps", "say", "listen", "further", "moveon", "time", "check"] } },
        { "if": { "properties": { "kind": { "const": "curriculum" } } }, "then": { "properties": { "id": { "pattern": "^CUR-(?:STEM|AI|NEST)$" } }, "required": ["discipline", "intro", "principles"] } },
        { "if": { "properties": { "kind": { "const": "guide" } } }, "then": { "properties": { "id": { "pattern": "^GUIDE-\\d{4}$" } }, "required": ["intro", "principles", "patterns", "limits", "check"] } },
        { "if": { "properties": { "kind": { "const": "pathway" } } }, "then": {
          "properties": {
            "id": { "pattern": "^PATH-\\d{4}$" },
            "options": { "type": "array", "items": { "type": "object", "required": ["name", "institution", "kind", "url", "checked"], "properties": { "name": { "$ref": "#/$defs/text" }, "institution": { "type": "string" }, "kind": { "$ref": "#/$defs/text" }, "url": { "type": "string", "format": "uri" }, "checked": { "$ref": "#/$defs/date" } } } },
            "units": { "$ref": "#/$defs/ids" }
          },
          "required": ["work", "skills", "units", "start", "options", "honest"] } }
      ]
    }
  }
}
