diff --git a/.gitignore b/.gitignore index 0d78289..4213633 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .godot/ /android/ *.DS_Store +schema/Archive.zip diff --git a/README.md b/README.md index ca5f8b4..483080a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,17 @@ -# tsunagite +# Tsunagite A rhythm game net ranking service built on ATproto. --- -This is still *very* ad-hoc and may not ever hit the point of being Fully Real but I'm at least messing around with it! If you wanna help out for any reason you know where to find me lol \ No newline at end of file +This is still *very* ad-hoc and may not ever hit the point of being Fully Real but I'm at least messing around with it! If you wanna help out for any reason you know where to find me lol + +## Dictionary Objects + +A few features in Tsunagite's lexicons strongly depend on a type that does not yet exist in the Lexicon schema language. These objects are key-value dictionaries with specified key string formats and value data types. I will look into pushing to standardize these at some point, but for the moment I'm taking these steps to indicate their presence: + +- All schema that use a dictionary object type have the line `"featureFlags": ["dev.tsunagite.dictionaryObject"]` at their top level. +- All dictionary objects have the standard type `object`, with no required or nullable fields + - All dictionary objects have a `$keyFormat` property field with the type of `string`, specifying the string format keys should use. + - All dictionary objects have a `$valueType` property field with the type of what values should be contained within the dictionary. + +I would love to be able to add a `"dictionary": true` object to dictionary objects to make them more explicit, but that fails the [honk lexicon validator](https://hexdocs.pm/honk/index.html) I've been testing against. Keep in mind that this is all *extremely* not in the current Lexicon spec and should be treated as experimental! Unfortunately, there are not really any better ways to do represent something like [dev.tsunagite.translatable](/schema/translatable.json) - there are simply too many valid IETF language tags to specify even the subset of commonly-used language tags, and using an array of objects with `id` and `value` fields would turn what would in a dictionary be an `O(1)` lookup into an `O(n)` operation instead, which is unacceptable in my eyes. Hopefully someday this will be resolved! \ No newline at end of file diff --git a/game-example/OAuth.cs b/game-example/OAuth.cs index 5fbf624..2507ed3 100644 --- a/game-example/OAuth.cs +++ b/game-example/OAuth.cs @@ -57,7 +57,7 @@ public partial class OAuth : Control { connection.PutData("HTTP/1.1 200\r\n".ToAsciiBuffer()); //TODO: response page here - connection.PutData("Authentication complete!".ToAsciiBuffer()); + connection.PutData("Authentication complete!".ToAsciiBuffer()); RedirectServer.Stop(); } } diff --git a/schema/game.json b/schema/game.json index f7aa0b2..072308c 100644 --- a/schema/game.json +++ b/schema/game.json @@ -2,6 +2,7 @@ "lexicon": 1, "id": "dev.tsunagite.game", "description": "Definitions related to games hosting leaderboards via Tunagite.", + "featureFlags": ["dev.tsunagite.dictionaryObject"], "defs": { "enum": { "type": "object", @@ -12,13 +13,6 @@ "description": "The human-readable name of this component in UI.", "ref": "dev.tsunagite.translatable" }, - "id": { - "type": "string", - "description": "The internal ID of this component, limited to the RecordKey characterset.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "values": { "type": "array", "description": "The allowed values for this enum to take.", @@ -28,7 +22,7 @@ } } }, - "required": ["name", "id", "values"] + "required": ["name", "values"] }, "points": { "type": "object", @@ -39,19 +33,12 @@ "description": "The human-readable name of this component in UI.", "ref": "dev.tsunagite.translatable" }, - "id": { - "type": "string", - "description": "The internal ID of this component, limited to the RecordKey characterset.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "maximum": { "type": "integer", "description": "The maximum allowed value for this score." } }, - "required": ["name", "id"] + "required": ["name"] }, "percentage": { "type": "object", @@ -62,13 +49,6 @@ "description": "The human-readable name of this component in UI.", "ref": "dev.tsunagite.translatable" }, - "id": { - "type": "string", - "description": "The internal ID of this component, limited to the RecordKey characterset.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "maximum": { "type": "integer", "description": "The maximum allowed percentage for this score.", @@ -80,7 +60,7 @@ "default": 2 } }, - "required": ["name", "id", "maximum", "precision"] + "required": ["name", "maximum", "precision"] }, "text": { "type": "object", @@ -90,16 +70,9 @@ "type": "ref", "description": "The human-readable name of this component in UI.", "ref": "dev.tsunagite.translatable" - }, - "id": { - "type": "string", - "description": "The internal ID of this component, limited to the RecordKey characterset.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 } }, - "required": ["name", "id"] + "required": ["name"] }, "main": { "type": "record", @@ -158,17 +131,25 @@ } }, "scoreComponents": { - "type": "array", + "type": "object", "description": "All the components of a score in the game, including grades, lamps, EX score, and whatever other constructs are used.", - "items": { - "type": "union", - "description": "If you need a component type that doesn't exist yet, contact @lemmaeof.gay", - "refs": [ - "#enum", - "#points", - "#percentage", - "#text" - ] + "properties": { + "$keyFormat": { + "type": "string", + "format": "record-key", + "minLength": 1, + "maxLength": 32 + }, + "$valueType": { + "type": "union", + "description": "If you need a component type that doesn't exist yet, contact @lemmaeof.gay", + "refs": [ + "#enum", + "#points", + "#percentage", + "#text" + ] + } } }, "defaultComponent": { diff --git a/schema/score.json b/schema/score.json index 7155b78..49cd518 100644 --- a/schema/score.json +++ b/schema/score.json @@ -2,61 +2,41 @@ "lexicon": 1, "id": "dev.tsunagite.score", "description": "Definitions related to scores in games hosting leaderboards via Tsunagite.", + "featureFlags": ["dev.tsunagite.dictionaryObject"], "defs": { "enum": { "type": "object", "description": "An indexable named score component.", "properties": { - "id": { - "type": "string", - "description": "The internal ID of this component, matching with an enum defined by the game record.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "value": { "type": "string", "description": "The internal ID of the value, matching with an allowed enum value defined by the game record.", "format": "record-key" } }, - "required": ["id", "value"] + "required": ["value"] }, "points": { "type": "object", "description": "An integer point score component.", "properties": { - "id": { - "type": "string", - "description": "The internal ID of this component, matching with a point score defined by the game record.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "value": { "type": "integer", "description": "The number of points earned, capped by the limit defined by the game record if present." } }, - "required": ["id", "value"] + "required": ["value"] }, "percentage": { "type": "object", "description": "A percentage score component.", "properties": { - "id": { - "type": "string", - "description": "The internal ID of this component, matching with a percentage score defined by the game record.", - "format": "record-key", - "minLength": 1, - "maxLength": 32 - }, "value": { "type": "string", "description": "The percentage score earned, capped and formatted by the limits defined by the game record. Stored as a decimal number without a percent sign." } }, - "required": ["id", "value"] + "required": ["value"] }, "text": { "type": "object", @@ -116,7 +96,14 @@ "type": "object", "description": "A map of judgment names to the integer judgment amounts earned during play.", "properties": { - "$allFields": { + "$keyFormat": { + "type": "string", + "description": "Must match a judgment defined by the game record.", + "format": "record-key", + "minLength": 1, + "maxLength": 32 + }, + "$valueType": { "type": "object", "properties": { "total": { @@ -138,9 +125,16 @@ }, "scoreComponents": { "type": "object", - "description": "The components that make up this score, as defined by the game record and keyed to the IDs.", + "description": "The components that make up this score, as defined by the game record.", "properties": { - "$allFields": { + "$keyFormat": { + "type": "string", + "description": "Must match an ID defined by the game record, as well as using the same type.", + "format": "record-key", + "minLength": 1, + "maxLength": 32 + }, + "$valueType": { "type": "union", "description": "If you need a component type that doesn't exist yet, contact @lemmaeof.gay", "refs": [ diff --git a/schema/translatable.json b/schema/translatable.json index b366743..792e5f8 100644 --- a/schema/translatable.json +++ b/schema/translatable.json @@ -2,6 +2,7 @@ "lexicon": 1, "id": "dev.tsunagite.translatable", "description": "A piece of text with multiple translations, transliterations, or localizations into different languages.", + "featureFlags": ["dev.tsunagite.dictionaryObject"], "defs": { "main": { "type": "object", @@ -15,921 +16,14 @@ }, "translations": { "type": "object", - "description": "A key-value map of RFC 5646 IETF language tags to translated strings. This property list is NON-EXHAUSTIVE - any valid IETF language tag, including subtags, is legal!", + "description": "A key-value map of RFC 5646 IETF language tags to translated strings.", "properties": { - "af": { + "$keyFormat": { "type": "string", - "description": "Afrikaans (Afrikaans)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "am": { - "type": "string", - "description": "አማርኛ (Amharic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ar": { - "type": "string", - "description": "العربية (Arabic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "arn": { - "type": "string", - "description": "Mapudungun (Mapudungun)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ary": { - "type": "string", - "description": "الدارجة المغربية (Moroccan Arabic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "as": { - "type": "string", - "description": "অসমীয়া (Assamese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "az": { - "type": "string", - "description": "Azərbaycan (Azerbaijani)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ba": { - "type": "string", - "description": "Башҡорт (Bashkir)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "be": { - "type": "string", - "description": "беларуская (Belarusian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "bg": { - "type": "string", - "description": "български (Bulgarian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "bn": { - "type": "string", - "description": "বাংলা (Bengali)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "bo": { - "type": "string", - "description": "བོད་ཡིག (Tibetan)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "br": { - "type": "string", - "description": "brezhoneg (Breton)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "bs": { - "type": "string", - "description": "bosanski/босански (Bosnian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ca": { - "type": "string", - "description": "català (Catalan)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ckb": { - "type": "string", - "description": "کوردیی ناوەندی (Central Kurdish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "co": { - "type": "string", - "description": "Corsu (Corsican)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "cs": { - "type": "string", - "description": "čeština (Czech)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "cy": { - "type": "string", - "description": "Cymraeg (Welsh)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "da": { - "type": "string", - "description": "dansk (Danish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "de": { - "type": "string", - "description": "Deutsch (German)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "dsb": { - "type": "string", - "description": "dolnoserbšćina (Lower Sorbian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "dv": { - "type": "string", - "description": "ދިވެހިބަސް (Divehi)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "el": { - "type": "string", - "description": "Ελληνικά (Greek)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "en": { - "type": "string", - "description": "English (English)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "es": { - "type": "string", - "description": "español (Spanish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "et": { - "type": "string", - "description": "eesti (Estonian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "eu": { - "type": "string", - "description": "euskara (Basque)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fa": { - "type": "string", - "description": "فارسى (Persian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fi": { - "type": "string", - "description": "suomi (Finnish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fil": { - "type": "string", - "description": "Filipino (Filipino)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fo": { - "type": "string", - "description": "føroyskt (Faroese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fr": { - "type": "string", - "description": "français (French)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "fy": { - "type": "string", - "description": "Frysk (Frisian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ga": { - "type": "string", - "description": "Gaeilge (Irish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "gd": { - "type": "string", - "description": "Gàidhlig (Scottish Gaelic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "gil": { - "type": "string", - "description": "Taetae ni Kiribati (Gilbertese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "gl": { - "type": "string", - "description": "galego (Galician)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "gsw": { - "type": "string", - "description": "Schweizerdeutsch (Swiss German)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "gu": { - "type": "string", - "description": "ગુજરાતી (Gujarati)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ha": { - "type": "string", - "description": "Hausa (Hausa)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "he": { - "type": "string", - "description": "עברית (Hebrew)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "hi": { - "type": "string", - "description": "हिंदी (Hindi)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "hr": { - "type": "string", - "description": "hrvatski (Croatian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "hsb": { - "type": "string", - "description": "hornjoserbšćina (Upper Sorbian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "hu": { - "type": "string", - "description": "magyar (Hungarian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "hy": { - "type": "string", - "description": "Հայերեն (Armenian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "id": { - "type": "string", - "description": "Bahasa Indonesia (Indonesian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ig": { - "type": "string", - "description": "Igbo (Igbo)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ii": { - "type": "string", - "description": "ꆈꌠꁱꂷ (Yi)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "is": { - "type": "string", - "description": "íslenska (Icelandic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "it": { - "type": "string", - "description": "italiano (Italian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "iu": { - "type": "string", - "description": "nuktitut/ᐃᓄᒃᑎᑐᑦ (ᑲᓇᑕ) (Inukitut)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ja": { - "type": "string", - "description": "日本語 (Japanese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ka": { - "type": "string", - "description": "ქართული (Georgian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "kk": { - "type": "string", - "description": "Қазақша (Kazakh)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "kl": { - "type": "string", - "description": "kalaallisut (Greenlandic)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "km": { - "type": "string", - "description": "ខ្មែរ (Khmer)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "kn": { - "type": "string", - "description": "ಕನ್ನಡ (Kannada)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ko": { - "type": "string", - "description": "한국어 (Korean)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "kok": { - "type": "string", - "description": "कोंकणी (Konkani)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ku": { - "type": "string", - "description": "Kurdî/کوردی (Kurdish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ky": { - "type": "string", - "description": "Кыргыз (Kyrgyz)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "lb": { - "type": "string", - "description": "Lëtzebuergesch (Luxembourgish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "lo": { - "type": "string", - "description": "ລາວ (Lao)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "lt": { - "type": "string", - "description": "lietuvių (Lithuanian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "lv": { - "type": "string", - "description": "latviešu (Latvian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "mi": { - "type": "string", - "description": "Reo Māori (Maori)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "mk": { - "type": "string", - "description": "македонски јазик (Macedonian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ml": { - "type": "string", - "description": "മലയാളം (Malayalam)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "mn": { - "type": "string", - "description": "Монгол хэл/ᠮᠤᠨᠭᠭᠤᠯ ᠬᠡᠯᠡ (Mongolian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "moh": { - "type": "string", - "description": "Kanien'kéha (Mohawk)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "mr": { - "type": "string", - "description": "मराठी (Marathi)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ms": { - "type": "string", - "description": "Bahasa Malaysia (Malay)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "mt": { - "type": "string", - "description": "Malti (Maltese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "my": { - "type": "string", - "description": "မြန်မာဘာသာ (Burmese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "nb": { - "type": "string", - "description": "norsk - bokmål (Norwegian - Bokmål)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ne": { - "type": "string", - "description": "नेपाली - नेपाल (Nepali)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "nl": { - "type": "string", - "description": "Nederlands (Dutch)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "nn": { - "type": "string", - "description": "norsk - nynorsk (Norwegian - Nynorsk)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "no": { - "type": "string", - "description": "norsk (Norwegian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "oc": { - "type": "string", - "description": "occitan (Occitan)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "or": { - "type": "string", - "description": "ଓଡ଼ିଆ (Odia)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "pap": { - "type": "string", - "description": "Papiamentu (Papiamento)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "pa": { - "type": "string", - "description": "ਪੰਜਾਬੀ/پنجابی (Punjabi)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "pl": { - "type": "string", - "description": "polski (Polish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "prs": { - "type": "string", - "description": "درى (Dari)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ps": { - "type": "string", - "description": "پښتو (Pashto)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "pt": { - "type": "string", - "description": "português (Portugese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "quc": { - "type": "string", - "description": "K'iche (K'iche)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "qu": { - "type": "string", - "description": "runasimi (Quechua)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "rm": { - "type": "string", - "description": "Rumantsch (Romansh)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ro": { - "type": "string", - "description": "română (Romanian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ru": { - "type": "string", - "description": "русский (Russian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "rw": { - "type": "string", - "description": "Kinyarwanda (Kinyarwanda)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sa": { - "type": "string", - "description": "संस्कृत (Sanskrit)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sah": { - "type": "string", - "description": "caxa (Yakut)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "se": { - "type": "string", - "description": "davvisámegiella (Sami - Northern)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "si": { - "type": "string", - "description": "සිංහල (Sinhala)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sk": { - "type": "string", - "description": "slovenčina (Slovak)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sl": { - "type": "string", - "description": "slovenščina (Slovenian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sma": { - "type": "string", - "description": "åarjelsaemiengiele (Sami - Southern)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "smj": { - "type": "string", - "description": "julevusámegiella (Sami - Lule)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "smn": { - "type": "string", - "description": "sämikielâ (Sami - Inari)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sms": { - "type": "string", - "description": "sääʹmǩiõll (Sami - Skolt)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sq": { - "type": "string", - "description": "shqip (Albanian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sr": { - "type": "string", - "description": "srpski/српски (Serbian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "st": { - "type": "string", - "description": "Sesotho (Sesotho)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sv": { - "type": "string", - "description": "svenska (Swedish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "sw": { - "type": "string", - "description": "Kiswahili (Kiswahili)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "syc": { - "type": "string", - "description": "ܣܘܪܝܝܐ (Syriac)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ta": { - "type": "string", - "description": "தமிழ் (Tamil)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "te": { - "type": "string", - "description": "తెలుగు (Telugu)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tg": { - "type": "string", - "description": "Тоҷикӣ (Tajik)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "th": { - "type": "string", - "description": "ไทย (Thai)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tk": { - "type": "string", - "description": "türkmençe (Turkmen)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tl": { - "type": "string", - "description": "Tagalog (Tagalog)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tn": { - "type": "string", - "description": "Setswana (Tswana)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tr": { - "type": "string", - "description": "Türkçe (Turkish)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tt": { - "type": "string", - "description": "Татарча (Tatar)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "tzm": { - "type": "string", - "description": "Tamazight (Tamazight)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ug": { - "type": "string", - "description": "ئۇيغۇرچە (Uyghur)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "uk": { - "type": "string", - "description": "українська (Ukranian)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "ur": { - "type": "string", - "description": "اُردو (Urdu)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "uz": { - "type": "string", - "description": "Uzbek/Ўзбек (Uzbek)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "vi": { - "type": "string", - "description": "Tiếng Việt (Vietnamese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "wo": { - "type": "string", - "description": "Wolof (Wolof)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "xh": { - "type": "string", - "description": "isiXhosa (Xhosa)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "yo": { - "type": "string", - "description": "Yoruba (Yoruba)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 - }, - "zh": { - "type": "string", - "description": "中文 (Chinese)", - "minLength": 1, - "maxLength": 3000, - "maxGraphemes": 300 + "format": "language" }, - "zu": { + "$valueType": { "type": "string", - "description": "isiZulu (isiZulu)", "minLength": 1, "maxLength": 3000, "maxGraphemes": 300