diff --git a/CHANGELOG.md b/CHANGELOG.md index 8010a1e..a6a851f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ Release History =============== +Unreleased +---------- + - `file_formats` mimetype `vtt`: `.vtt` → `text/vtt` + - `file_formats` mimetype `mp3`: `.mp3` → `audio/mpeg` + - `file_formats` mimetype `zip`: `.zip` → `application/zip` + - `file_formats` mimetype `svg`: `image/svg` → `image/svg+xml` + - `file_formats` mimetype `h5p`: `.h5p` → `application/h5p+zip` + - `file_formats` mimetype `zim`: `.zim` → `application/x-openzim` + - `file_formats` mimetype `graphie`: `.graphie` → `application/x-graphie` + - `file_formats.getformat(id, default)` returns `default` for an unknown `id` + - Removed `resources/formatlookup.json`; use `file_formats.FORMATLIST` + - Added `kolibri-constants/FileFormats` + + 0.2.17 Apr 13, 2026 ------------------- - Added library enum constants (KOLIBRI, COMMUNITY) for identifying channel library membership diff --git a/js/FileFormats.js b/js/FileFormats.js new file mode 100644 index 0000000..e6e5fc7 --- /dev/null +++ b/js/FileFormats.js @@ -0,0 +1,80 @@ +// -*- coding: utf-8 -*- +// Generated by scripts/generate_from_specs.py +// FileFormats + +export default { + MP4: "mp4", + MP4_MIMETYPE: "video/mp4", + WEBM: "webm", + WEBM_MIMETYPE: "video/webm", + VTT: "vtt", + VTT_MIMETYPE: "text/vtt", + PDF: "pdf", + PDF_MIMETYPE: "application/pdf", + EPUB: "epub", + EPUB_MIMETYPE: "application/epub+zip", + MP3: "mp3", + MP3_MIMETYPE: "audio/mpeg", + JPG: "jpg", + JPG_MIMETYPE: "image/jpeg", + JPEG: "jpeg", + PNG: "png", + PNG_MIMETYPE: "image/png", + GIF: "gif", + GIF_MIMETYPE: "image/gif", + JSON: "json", + JSON_MIMETYPE: "application/json", + SVG: "svg", + SVG_MIMETYPE: "image/svg+xml", + GRAPHIE: "graphie", + GRAPHIE_MIMETYPE: "application/x-graphie", + PERSEUS: "perseus", + PERSEUS_MIMETYPE: "application/perseus+zip", + H5P: "h5p", + H5P_MIMETYPE: "application/h5p+zip", + ZIM: "zim", + ZIM_MIMETYPE: "application/x-openzim", + HTML5: "zip", + HTML5_MIMETYPE: "application/zip", + BLOOMPUB: "bloompub", + BLOOMPUB_MIMETYPE: "application/bloompub+zip", + BLOOMD: "bloomd", + HTML5_ARTICLE: "kpub", + HTML5_ARTICLE_MIMETYPE: "application/kpub+zip", + AVI: "avi", + MOV: "mov", + MPG: "mpg", + WMV: "wmv", + MKV: "mkv", + FLV: "flv", + OGV: "ogv", + M4V: "m4v", + SRT: "srt", + TTML: "ttml", + SAMI: "sami", + SCC: "scc", + DFXP: "dfxp", +}; + +export const FORMATLIST = [ + { id: "mp4", mimetype: "video/mp4" }, + { id: "webm", mimetype: "video/webm" }, + { id: "vtt", mimetype: "text/vtt" }, + { id: "pdf", mimetype: "application/pdf" }, + { id: "epub", mimetype: "application/epub+zip" }, + { id: "mp3", mimetype: "audio/mpeg" }, + { id: "jpg", mimetype: "image/jpeg" }, + { id: "jpeg", mimetype: "image/jpeg" }, + { id: "png", mimetype: "image/png" }, + { id: "gif", mimetype: "image/gif" }, + { id: "json", mimetype: "application/json" }, + { id: "svg", mimetype: "image/svg+xml" }, + { id: "graphie", mimetype: "application/x-graphie" }, + { id: "perseus", mimetype: "application/perseus+zip" }, + { id: "h5p", mimetype: "application/h5p+zip" }, + { id: "zim", mimetype: "application/x-openzim" }, + { id: "zip", mimetype: "application/zip" }, + { id: "bloompub", mimetype: "application/bloompub+zip" }, + { id: "bloomd", mimetype: "application/bloompub+zip" }, + { id: "kpub", mimetype: "application/kpub+zip" }, +]; diff --git a/le_utils/constants/file_formats.py b/le_utils/constants/file_formats.py index f5fa4c4..db69dd0 100644 --- a/le_utils/constants/file_formats.py +++ b/le_utils/constants/file_formats.py @@ -1,45 +1,23 @@ -import json -import pkgutil -from collections import namedtuple +# -*- coding: utf-8 -*- +# Generated by scripts/generate_from_specs.py +from __future__ import unicode_literals -""" File Format Constants """ +from collections import namedtuple -# IMPORTANT: Keep these constants in sync with formatlookup.json and presetlookup.json +# FileFormats -# constants for Video format MP4 = "mp4" MP4_MIMETYPE = "video/mp4" WEBM = "webm" WEBM_MIMETYPE = "video/webm" -# constants for video formats converitble to mp4 -AVI = "avi" -MOV = "mov" -MPG = "mpg" -WMV = "wmv" -MKV = "mkv" -FLV = "flv" -OGV = "ogv" -M4V = "m4v" - -# constants for Subtitle format VTT = "vtt" -VTT_MIMETYPE = ".vtt" -# constants for formats convertible to VTT -SRT = "srt" -TTML = "ttml" -SAMI = "sami" -SCC = "scc" -DFXP = "dfxp" - -# constants for Audio format -MP3 = "mp3" -MP3_MIMETYPE = ".mp3" - -# constants for Document format +VTT_MIMETYPE = "text/vtt" PDF = "pdf" PDF_MIMETYPE = "application/pdf" - -# constants for Thumbnail format +EPUB = "epub" +EPUB_MIMETYPE = "application/epub+zip" +MP3 = "mp3" +MP3_MIMETYPE = "audio/mpeg" JPG = "jpg" JPG_MIMETYPE = "image/jpeg" JPEG = "jpeg" @@ -47,47 +25,47 @@ PNG_MIMETYPE = "image/png" GIF = "gif" GIF_MIMETYPE = "image/gif" - - JSON = "json" JSON_MIMETYPE = "application/json" SVG = "svg" -SVG_MIMETYPE = "image/svg" +SVG_MIMETYPE = "image/svg+xml" GRAPHIE = "graphie" -GRAPHIE_MIMETYPE = ".graphie" - -# constants for Exercise format +GRAPHIE_MIMETYPE = "application/x-graphie" PERSEUS = "perseus" PERSEUS_MIMETYPE = "application/perseus+zip" - -# constants for HTML5 zip format -HTML5 = "zip" -HTML5_MIMETYPE = ".zip" - -# constants for Kolibri article zip format -HTML5_ARTICLE = "kpub" -HTML5_ARTICLE_MIMETYPE = "application/kpub+zip" - -# constants for H5P format H5P = "h5p" -H5P_MIMETYPE = ".h5p" - -# constants for Zim format +H5P_MIMETYPE = "application/h5p+zip" ZIM = "zim" -ZIM_MIMETYPE = ".zim" - -# constants for ePub format -EPUB = "epub" -EPUB_MIMETYPE = "application/epub+zip" - -# constants for bloomPub format +ZIM_MIMETYPE = "application/x-openzim" +HTML5 = "zip" +HTML5_MIMETYPE = "application/zip" BLOOMPUB = "bloompub" -BLOOMD = "bloomd" BLOOMPUB_MIMETYPE = "application/bloompub+zip" +BLOOMD = "bloomd" +HTML5_ARTICLE = "kpub" +HTML5_ARTICLE_MIMETYPE = "application/kpub+zip" +AVI = "avi" +MOV = "mov" +MPG = "mpg" +WMV = "wmv" +MKV = "mkv" +FLV = "flv" +OGV = "ogv" +M4V = "m4v" +SRT = "srt" +TTML = "ttml" +SAMI = "sami" +SCC = "scc" +DFXP = "dfxp" -# Zip-based formats identified by le_utils.archive.contents_sha256. -# FROZEN: ricecooker and Studio's upload Cloud Function pin this; removing a format orphans its index entries. -ARCHIVE_FORMATS = (HTML5, H5P, EPUB, HTML5_ARTICLE, BLOOMPUB, BLOOMD) +ARCHIVE_FORMATS = ( + HTML5, + H5P, + EPUB, + HTML5_ARTICLE, + BLOOMPUB, + BLOOMD, +) choices = ( (MP4, "MP4 Video"), @@ -118,24 +96,35 @@ class Format(namedtuple("Format", ["id", "mimetype"])): def generate_list(constantlist): - for id, format in constantlist.items(): - yield Format(id=id, **format) - - -def _initialize_format_list(): - constantlist = json.loads(pkgutil.get_data("le_utils", "resources/formatlookup.json").decode("utf-8")) - return generate_list(constantlist) - - -FORMATLIST = list(_initialize_format_list()) - -_FORMATLOOKUP = {f.id: f for f in FORMATLIST} + for id, record in constantlist.items(): + yield Format(id=id, **record) + + +FORMATLIST = [ + Format(id="mp4", mimetype="video/mp4"), + Format(id="webm", mimetype="video/webm"), + Format(id="vtt", mimetype="text/vtt"), + Format(id="pdf", mimetype="application/pdf"), + Format(id="epub", mimetype="application/epub+zip"), + Format(id="mp3", mimetype="audio/mpeg"), + Format(id="jpg", mimetype="image/jpeg"), + Format(id="jpeg", mimetype="image/jpeg"), + Format(id="png", mimetype="image/png"), + Format(id="gif", mimetype="image/gif"), + Format(id="json", mimetype="application/json"), + Format(id="svg", mimetype="image/svg+xml"), + Format(id="graphie", mimetype="application/x-graphie"), + Format(id="perseus", mimetype="application/perseus+zip"), + Format(id="h5p", mimetype="application/h5p+zip"), + Format(id="zim", mimetype="application/x-openzim"), + Format(id="zip", mimetype="application/zip"), + Format(id="bloompub", mimetype="application/bloompub+zip"), + Format(id="bloomd", mimetype="application/bloompub+zip"), + Format(id="kpub", mimetype="application/kpub+zip"), +] + +_FORMATLOOKUP = {r.id: r for r in FORMATLIST} def getformat(id, default=None): - """ - Try to lookup a file format object for its `id` in internal representation defined - in resources/formatlookup.json. - Returns None if lookup by internal representation fails. - """ - return _FORMATLOOKUP.get(id) or None + return _FORMATLOOKUP.get(id, default) diff --git a/le_utils/resources/formatlookup.json b/le_utils/resources/formatlookup.json deleted file mode 100644 index 472c241..0000000 --- a/le_utils/resources/formatlookup.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "mp4": { - "mimetype": "video/mp4" - }, - "webm": { - "mimetype": "video/webm" - }, - "vtt": { - "mimetype": ".vtt" - }, - "pdf": { - "mimetype": "application/pdf" - }, - "epub": { - "mimetype": "application/epub+zip" - }, - "mp3": { - "mimetype": ".mp3" - }, - "jpg": { - "mimetype": "image/jpeg" - }, - "jpeg": { - "mimetype": "image/jpeg" - }, - "png": { - "mimetype": "image/png" - }, - "gif": { - "mimetype": "image/gif" - }, - "json": { - "mimetype": "application/json" - }, - "svg": { - "mimetype": "image/svg" - }, - "graphie": { - "mimetype": ".graphie" - }, - "perseus": { - "mimetype": "application/perseus+zip" - }, - "h5p": { - "mimetype": ".h5p" - }, - "zim": { - "mimetype": ".zim" - }, - "zip": { - "mimetype": ".zip" - }, - "bloompub": { - "mimetype": "application/bloompub+zip" - }, - "bloomd": { - "mimetype": "application/bloompub+zip" - }, - "kpub": { - "mimetype": "application/kpub+zip" - } -} diff --git a/scripts/generate_from_specs.py b/scripts/generate_from_specs.py index 66c8d62..ef834b9 100644 --- a/scripts/generate_from_specs.py +++ b/scripts/generate_from_specs.py @@ -182,12 +182,16 @@ def read_schema_specs(): return schema_outputs, constants_outputs +def write_python_header(f): + f.write("# -*- coding: utf-8 -*-\n") + f.write("# Generated by scripts/generate_from_specs.py\n") + f.write("from __future__ import unicode_literals\n") + f.write("\n") + + def write_python_file(output_file, name, ordered_output, schema=None): with open(output_file, "w") as f: - f.write("# -*- coding: utf-8 -*-\n") - f.write("# Generated by scripts/generate_from_specs.py\n") - f.write("from __future__ import unicode_literals\n") - f.write("\n") + write_python_header(f) f.write("# {}\n".format(name)) f.write("\n") for key, value in ordered_output.items(): @@ -227,6 +231,138 @@ def write_js_file(output_file, name, ordered_output, schema=None): f.write("export const SCHEMA = {};\n".format(schema)) +def define_constant(constants, constant, value): + if constant in constants: + raise ValueError("Constant {} is defined twice".format(constant)) + constants[constant] = value + + +def namedtuple_constants(spec): + constants = OrderedDict() + ids = set() + for record in spec["records"]: + for field in spec["namedtuple"]["fields"]: + if field not in record: + raise ValueError("Record {} has no field {}".format(record["constant"], field)) + if record["id"] in ids: + raise ValueError("Record id {} is defined twice".format(record["id"])) + ids.add(record["id"]) + define_constant(constants, record["constant"], record["id"]) + for field in record.get("field_constants", []): + define_constant(constants, "{}_{}".format(record["constant"], field.upper()), record[field]) + for constant, value in spec.get("constants", {}).items(): + define_constant(constants, constant, value) + return constants + + +def namedtuple_tuples(spec, constants): + tuples = spec.get("tuples", {}) + for tuple_name, members in tuples.items(): + if len(set(members)) != len(members): + raise ValueError("Tuple {} repeats a constant".format(tuple_name)) + for member in members: + if member not in constants: + raise ValueError("Tuple {} references undefined constant {}".format(tuple_name, member)) + return tuples + + +def namedtuple_choices(spec): + if "choices_order" not in spec: + return None + labels = {record["constant"]: record["label"] for record in spec["records"]} + if len(set(spec["choices_order"])) != len(spec["choices_order"]): + raise ValueError("choices_order repeats a record") + for constant in spec["choices_order"]: + if constant not in labels: + raise ValueError("choices_order references undefined record {}".format(constant)) + for constant in labels: + if constant not in spec["choices_order"]: + raise ValueError("choices_order omits record {}".format(constant)) + return [(constant, labels[constant]) for constant in spec["choices_order"]] + + +def write_python_choices(f, choices): + f.write("choices = (\n") + for constant, label in choices: + f.write(" ({}, {!r}),\n".format(constant, label)) + f.write(")\n") + + +def write_python_records(f, spec): + type_name = spec["namedtuple"]["name"] + fields = spec["namedtuple"]["fields"] + f.write("class {name}(namedtuple({name!r}, {fields!r})):\n".format(name=type_name, fields=fields)) + f.write(" pass\n") + f.write("\n") + f.write("\n") + f.write("def generate_list(constantlist):\n") + f.write(" for id, record in constantlist.items():\n") + f.write(" yield {}(id=id, **record)\n".format(type_name)) + f.write("\n") + f.write("\n") + f.write("{}LIST = [\n".format(type_name.upper())) + for record in spec["records"]: + arguments = ", ".join("{}={!r}".format(field, record[field]) for field in fields) + f.write(" {}({}),\n".format(type_name, arguments)) + f.write("]\n") + + +def write_python_getter(f, spec): + upper = spec["namedtuple"]["name"].upper() + f.write("\n") + f.write("_{name}LOOKUP = {{r.id: r for r in {name}LIST}}\n".format(name=upper)) + f.write("\n") + f.write("\n") + f.write("def {}(id, default=None):\n".format(spec["namedtuple"]["getter"])) + f.write(" return _{}LOOKUP.get(id, default)\n".format(upper)) + + +def write_namedtuple_python_file(output_file, name, spec): + constants = namedtuple_constants(spec) + tuples = namedtuple_tuples(spec, constants) + choices = namedtuple_choices(spec) + with open(output_file, "w") as f: + write_python_header(f) + f.write("from collections import namedtuple\n") + f.write("\n") + f.write("# {}\n".format(name)) + f.write("\n") + for constant, value in constants.items(): + f.write("{} = {!r}\n".format(constant, value)) + for tuple_name, members in tuples.items(): + f.write("\n") + f.write("{} = ({},)\n".format(tuple_name, ", ".join(members))) + f.write("\n") + if choices is not None: + write_python_choices(f, choices) + f.write("\n") + f.write("\n") + write_python_records(f, spec) + if "getter" in spec["namedtuple"]: + write_python_getter(f, spec) + + +def js_object(pairs): + return "{{ {} }}".format(", ".join("{}: {}".format(key, json.dumps(value)) for key, value in pairs)) + + +def write_namedtuple_js_file(output_file, name, spec): + fields = spec["namedtuple"]["fields"] + with open(output_file, "w") as f: + write_js_header(f) + f.write("// {}\n".format(name)) + f.write("\n") + f.write("export default {\n") + for constant, value in namedtuple_constants(spec).items(): + f.write(" {}: {},\n".format(constant, json.dumps(value))) + f.write("};\n") + f.write("\n") + f.write("export const {}LIST = [\n".format(spec["namedtuple"]["name"].upper())) + for record in spec["records"]: + f.write(" {},\n".format(js_object((field, record[field]) for field in fields))) + f.write("];\n") + + def write_labels_src_files(label_outputs): output_files = [] for label_type, ordered_output in label_outputs.items(): @@ -249,12 +385,14 @@ def write_constants_src_files(constants_outputs, schemas): schema = schemas.get(key, None) py_output_file = os.path.join(py_output_dir, "{}.py".format(pascal_to_snake(key))) - write_python_file(py_output_file, key, constant_outputs, schema=schema) - output_files.append(py_output_file) - js_output_file = os.path.join(js_output_dir, "{}.js".format(key)) - write_js_file(js_output_file, key, constant_outputs, schema=schema) - output_files.append(js_output_file) + if "namedtuple" in constant_outputs: + write_namedtuple_python_file(py_output_file, key, constant_outputs) + write_namedtuple_js_file(js_output_file, key, constant_outputs) + else: + write_python_file(py_output_file, key, constant_outputs, schema=schema) + write_js_file(js_output_file, key, constant_outputs, schema=schema) + output_files += [py_output_file, js_output_file] return output_files diff --git a/spec/constants-file_formats.json b/spec/constants-file_formats.json new file mode 100644 index 0000000..a7bd379 --- /dev/null +++ b/spec/constants-file_formats.json @@ -0,0 +1,195 @@ +{ + "namedtuple": { + "name": "Format", + "fields": ["id", "mimetype"], + "getter": "getformat" + }, + "records": [ + { + "constant": "MP4", + "label": "MP4 Video", + "field_constants": ["mimetype"], + "id": "mp4", + "mimetype": "video/mp4" + }, + { + "constant": "WEBM", + "label": "WEBM Video", + "field_constants": ["mimetype"], + "id": "webm", + "mimetype": "video/webm" + }, + { + "constant": "VTT", + "label": "VTT Subtitle", + "field_constants": ["mimetype"], + "id": "vtt", + "mimetype": "text/vtt" + }, + { + "constant": "PDF", + "label": "PDF Document", + "field_constants": ["mimetype"], + "id": "pdf", + "mimetype": "application/pdf" + }, + { + "constant": "EPUB", + "label": "ePub Document", + "field_constants": ["mimetype"], + "id": "epub", + "mimetype": "application/epub+zip" + }, + { + "constant": "MP3", + "label": "MP3 Audio", + "field_constants": ["mimetype"], + "id": "mp3", + "mimetype": "audio/mpeg" + }, + { + "constant": "JPG", + "label": "JPG Image", + "field_constants": ["mimetype"], + "id": "jpg", + "mimetype": "image/jpeg" + }, + { + "constant": "JPEG", + "label": "JPEG Image", + "id": "jpeg", + "mimetype": "image/jpeg" + }, + { + "constant": "PNG", + "label": "PNG Image", + "field_constants": ["mimetype"], + "id": "png", + "mimetype": "image/png" + }, + { + "constant": "GIF", + "label": "GIF Image", + "field_constants": ["mimetype"], + "id": "gif", + "mimetype": "image/gif" + }, + { + "constant": "JSON", + "label": "JSON", + "field_constants": ["mimetype"], + "id": "json", + "mimetype": "application/json" + }, + { + "constant": "SVG", + "label": "SVG Image", + "field_constants": ["mimetype"], + "id": "svg", + "mimetype": "image/svg+xml" + }, + { + "constant": "GRAPHIE", + "label": "Graphie Exercise", + "field_constants": ["mimetype"], + "id": "graphie", + "mimetype": "application/x-graphie" + }, + { + "constant": "PERSEUS", + "label": "Perseus Exercise", + "field_constants": ["mimetype"], + "id": "perseus", + "mimetype": "application/perseus+zip" + }, + { + "constant": "H5P", + "label": "H5P", + "field_constants": ["mimetype"], + "id": "h5p", + "mimetype": "application/h5p+zip" + }, + { + "constant": "ZIM", + "label": "ZIM", + "field_constants": ["mimetype"], + "id": "zim", + "mimetype": "application/x-openzim" + }, + { + "constant": "HTML5", + "label": "HTML5 Zip", + "field_constants": ["mimetype"], + "id": "zip", + "mimetype": "application/zip" + }, + { + "constant": "BLOOMPUB", + "label": "Bloom Document", + "field_constants": ["mimetype"], + "id": "bloompub", + "mimetype": "application/bloompub+zip" + }, + { + "constant": "BLOOMD", + "label": "Bloom Document", + "id": "bloomd", + "mimetype": "application/bloompub+zip" + }, + { + "constant": "HTML5_ARTICLE", + "label": "Kolibri HTML5 Article", + "field_constants": ["mimetype"], + "id": "kpub", + "mimetype": "application/kpub+zip" + } + ], + "choices_order": [ + "MP4", + "WEBM", + "VTT", + "MP3", + "PDF", + "JPG", + "JPEG", + "PNG", + "GIF", + "JSON", + "SVG", + "PERSEUS", + "GRAPHIE", + "HTML5", + "H5P", + "ZIM", + "EPUB", + "BLOOMPUB", + "BLOOMD", + "HTML5_ARTICLE" + ], + "constants": { + "AVI": "avi", + "MOV": "mov", + "MPG": "mpg", + "WMV": "wmv", + "MKV": "mkv", + "FLV": "flv", + "OGV": "ogv", + "M4V": "m4v", + "SRT": "srt", + "TTML": "ttml", + "SAMI": "sami", + "SCC": "scc", + "DFXP": "dfxp" + }, + "tuples": { + "ARCHIVE_FORMATS": [ + "HTML5", + "H5P", + "EPUB", + "HTML5_ARTICLE", + "BLOOMPUB", + "BLOOMD" + ] + } +} + diff --git a/tests/pinned_api.json b/tests/pinned_api.json new file mode 100644 index 0000000..83fbc77 --- /dev/null +++ b/tests/pinned_api.json @@ -0,0 +1,11932 @@ +{ + "content_kinds": { + "AUDIO": "audio", + "DOCUMENT": "document", + "EXERCISE": "exercise", + "H5P": "h5p", + "HTML5": "html5", + "KINDLIST": { + "list": [ + { + "fields": [ + [ + "id", + "topic" + ], + [ + "name", + "topic" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "video" + ], + [ + "name", + "video" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "audio" + ], + [ + "name", + "audio" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "exercise" + ], + [ + "name", + "exercise" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "document" + ], + [ + "name", + "document" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "html5" + ], + [ + "name", + "html5" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "slideshow" + ], + [ + "name", + "slideshow" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "h5p" + ], + [ + "name", + "h5p" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "zim" + ], + [ + "name", + "zim" + ] + ], + "namedtuple": "Kind", + "properties": {} + }, + { + "fields": [ + [ + "id", + "quiz" + ], + [ + "name", + "quiz" + ] + ], + "namedtuple": "Kind", + "properties": {} + } + ] + }, + "Kind": { + "fields": [ + "id", + "name" + ], + "namedtuple_class": "Kind" + }, + "MAPPING": { + "dict": { + "bloomd": "document", + "bloompub": "document", + "epub": "document", + "h5p": "h5p", + "mp3": "audio", + "mp4": "video", + "pdf": "document", + "perseus": "exercise", + "webm": "video", + "zim": "zim", + "zip": "html5" + } + }, + "QUIZ": "quiz", + "SLIDESHOW": "slideshow", + "TOPIC": "topic", + "VIDEO": "video", + "ZIM": "zim", + "choices": { + "tuple": [ + { + "tuple": [ + "topic", + "Topic" + ] + }, + { + "tuple": [ + "video", + "Video" + ] + }, + { + "tuple": [ + "audio", + "Audio" + ] + }, + { + "tuple": [ + "exercise", + "Exercise" + ] + }, + { + "tuple": [ + "document", + "Document" + ] + }, + { + "tuple": [ + "html5", + "HTML5 App" + ] + }, + { + "tuple": [ + "slideshow", + "Slideshow" + ] + }, + { + "tuple": [ + "h5p", + "H5P" + ] + }, + { + "tuple": [ + "zim", + "Zim" + ] + }, + { + "tuple": [ + "quiz", + "Quiz" + ] + } + ] + }, + "generate_list": { + "function": "(constantlist)" + } + }, + "file_formats": { + "ARCHIVE_FORMATS": { + "tuple": [ + "zip", + "h5p", + "epub", + "kpub", + "bloompub", + "bloomd" + ] + }, + "AVI": "avi", + "BLOOMD": "bloomd", + "BLOOMPUB": "bloompub", + "BLOOMPUB_MIMETYPE": "application/bloompub+zip", + "DFXP": "dfxp", + "EPUB": "epub", + "EPUB_MIMETYPE": "application/epub+zip", + "FLV": "flv", + "FORMATLIST": { + "list": [ + { + "fields": [ + [ + "id", + "mp4" + ], + [ + "mimetype", + "video/mp4" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "webm" + ], + [ + "mimetype", + "video/webm" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "vtt" + ], + [ + "mimetype", + "text/vtt" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "pdf" + ], + [ + "mimetype", + "application/pdf" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "epub" + ], + [ + "mimetype", + "application/epub+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "mp3" + ], + [ + "mimetype", + "audio/mpeg" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "jpg" + ], + [ + "mimetype", + "image/jpeg" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "jpeg" + ], + [ + "mimetype", + "image/jpeg" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "png" + ], + [ + "mimetype", + "image/png" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "gif" + ], + [ + "mimetype", + "image/gif" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "json" + ], + [ + "mimetype", + "application/json" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "svg" + ], + [ + "mimetype", + "image/svg+xml" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "graphie" + ], + [ + "mimetype", + "application/x-graphie" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "perseus" + ], + [ + "mimetype", + "application/perseus+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "h5p" + ], + [ + "mimetype", + "application/h5p+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "zim" + ], + [ + "mimetype", + "application/x-openzim" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "zip" + ], + [ + "mimetype", + "application/zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "bloompub" + ], + [ + "mimetype", + "application/bloompub+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "bloomd" + ], + [ + "mimetype", + "application/bloompub+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + }, + { + "fields": [ + [ + "id", + "kpub" + ], + [ + "mimetype", + "application/kpub+zip" + ] + ], + "namedtuple": "Format", + "properties": {} + } + ] + }, + "Format": { + "fields": [ + "id", + "mimetype" + ], + "namedtuple_class": "Format" + }, + "GIF": "gif", + "GIF_MIMETYPE": "image/gif", + "GRAPHIE": "graphie", + "GRAPHIE_MIMETYPE": "application/x-graphie", + "H5P": "h5p", + "H5P_MIMETYPE": "application/h5p+zip", + "HTML5": "zip", + "HTML5_ARTICLE": "kpub", + "HTML5_ARTICLE_MIMETYPE": "application/kpub+zip", + "HTML5_MIMETYPE": "application/zip", + "JPEG": "jpeg", + "JPG": "jpg", + "JPG_MIMETYPE": "image/jpeg", + "JSON": "json", + "JSON_MIMETYPE": "application/json", + "M4V": "m4v", + "MKV": "mkv", + "MOV": "mov", + "MP3": "mp3", + "MP3_MIMETYPE": "audio/mpeg", + "MP4": "mp4", + "MP4_MIMETYPE": "video/mp4", + "MPG": "mpg", + "OGV": "ogv", + "PDF": "pdf", + "PDF_MIMETYPE": "application/pdf", + "PERSEUS": "perseus", + "PERSEUS_MIMETYPE": "application/perseus+zip", + "PNG": "png", + "PNG_MIMETYPE": "image/png", + "SAMI": "sami", + "SCC": "scc", + "SRT": "srt", + "SVG": "svg", + "SVG_MIMETYPE": "image/svg+xml", + "TTML": "ttml", + "VTT": "vtt", + "VTT_MIMETYPE": "text/vtt", + "WEBM": "webm", + "WEBM_MIMETYPE": "video/webm", + "WMV": "wmv", + "ZIM": "zim", + "ZIM_MIMETYPE": "application/x-openzim", + "choices": { + "tuple": [ + { + "tuple": [ + "mp4", + "MP4 Video" + ] + }, + { + "tuple": [ + "webm", + "WEBM Video" + ] + }, + { + "tuple": [ + "vtt", + "VTT Subtitle" + ] + }, + { + "tuple": [ + "mp3", + "MP3 Audio" + ] + }, + { + "tuple": [ + "pdf", + "PDF Document" + ] + }, + { + "tuple": [ + "jpg", + "JPG Image" + ] + }, + { + "tuple": [ + "jpeg", + "JPEG Image" + ] + }, + { + "tuple": [ + "png", + "PNG Image" + ] + }, + { + "tuple": [ + "gif", + "GIF Image" + ] + }, + { + "tuple": [ + "json", + "JSON" + ] + }, + { + "tuple": [ + "svg", + "SVG Image" + ] + }, + { + "tuple": [ + "perseus", + "Perseus Exercise" + ] + }, + { + "tuple": [ + "graphie", + "Graphie Exercise" + ] + }, + { + "tuple": [ + "zip", + "HTML5 Zip" + ] + }, + { + "tuple": [ + "h5p", + "H5P" + ] + }, + { + "tuple": [ + "zim", + "ZIM" + ] + }, + { + "tuple": [ + "epub", + "ePub Document" + ] + }, + { + "tuple": [ + "bloompub", + "Bloom Document" + ] + }, + { + "tuple": [ + "bloomd", + "Bloom Document" + ] + }, + { + "tuple": [ + "kpub", + "Kolibri HTML5 Article" + ] + } + ] + }, + "generate_list": { + "function": "(constantlist)" + }, + "getformat": { + "function": "(id, default=None)" + } + }, + "format_presets": { + "AUDIO": "audio", + "AUDIO_DEPENDENCY": "audio_dependency", + "AUDIO_DEPENDENCY_READABLE": "audio (dependency)", + "AUDIO_READABLE": "Audio", + "AUDIO_THUMBNAIL": "audio_thumbnail", + "AUDIO_THUMBNAIL_READABLE": "Thumbnail", + "BLOOMPUB": "bloompub", + "BLOOMPUB_READABLE": "Bloom Document", + "CHANNEL_THUMBNAIL": "channel_thumbnail", + "CHANNEL_THUMBNAIL_READABLE": "Channel Thumbnail", + "DOCUMENT": "document", + "DOCUMENT_READABLE": "Document", + "DOCUMENT_THUMBNAIL": "document_thumbnail", + "DOCUMENT_THUMBNAIL_READABLE": "Thumbnail", + "EPUB": "epub", + "EPUB_READABLE": "ePub Document", + "EXERCISE": "exercise", + "EXERCISE_GRAPHIE": "exercise_graphie", + "EXERCISE_GRAPHIE_READABLE": "Exercise Graphie", + "EXERCISE_IMAGE": "exercise_image", + "EXERCISE_IMAGE_READABLE": "Exercise Image", + "EXERCISE_READABLE": "Exercise", + "EXERCISE_THUMBNAIL": "exercise_thumbnail", + "EXERCISE_THUMBNAIL_READABLE": "Thumbnail", + "H5P_THUMBNAIL": "h5p_thumbnail", + "H5P_THUMBNAIL_READABLE": "H5P Thumbnail", + "H5P_ZIP": "h5p", + "H5P_ZIP_READABLE": "H5P Zip", + "HTML5_DEPENDENCY_ZIP": "html5_dependency", + "HTML5_DEPENDENCY_ZIP_READABLE": "HTML5 Dependency (Zip format)", + "HTML5_THUMBNAIL": "html5_thumbnail", + "HTML5_THUMBNAIL_READABLE": "HTML5 Thumbnail", + "HTML5_ZIP": "html5_zip", + "HTML5_ZIP_READABLE": "HTML5 Zip", + "IMSCP_ZIP": "imscp_zip", + "IMSCP_ZIP_READABLE": "IMSCP Zip", + "KPUB_ZIP": "kpub", + "KPUB_ZIP_READABLE": "Kolibri HTML5 Article", + "PRESETLIST": { + "list": [ + { + "fields": [ + [ + "id", + "high_res_video" + ], + [ + "readable_name", + "High Resolution" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "video" + ], + [ + "allowed_formats", + { + "list": [ + "mp4", + "webm" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "avi", + "mov", + "mpg", + "wmv", + "mkv", + "flv", + "ogv", + "m4v" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "low_res_video" + ], + [ + "readable_name", + "Low Resolution" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "video" + ], + [ + "allowed_formats", + { + "list": [ + "mp4", + "webm" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "avi", + "mov", + "mpg", + "wmv", + "mkv", + "flv", + "ogv", + "m4v" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "video_dependency" + ], + [ + "readable_name", + "Video Dependency" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 3 + ], + [ + "kind", + "video" + ], + [ + "allowed_formats", + { + "list": [ + "mp4", + "webm" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "avi", + "mov", + "mpg", + "wmv", + "mkv", + "flv", + "ogv", + "m4v" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "video_thumbnail" + ], + [ + "readable_name", + "Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 3 + ], + [ + "kind", + "video" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "video_subtitle" + ], + [ + "readable_name", + "Subtitle" + ], + [ + "multi_language", + true + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + true + ], + [ + "display", + true + ], + [ + "order", + 4 + ], + [ + "kind", + "video" + ], + [ + "allowed_formats", + { + "list": [ + "vtt" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "srt", + "ttml", + "sami", + "scc", + "dfxp" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "audio" + ], + [ + "readable_name", + "Audio" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "audio" + ], + [ + "allowed_formats", + { + "list": [ + "mp3" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "wav", + "m4a", + "aac", + "ogg" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "audio_dependency" + ], + [ + "readable_name", + "Audio" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 3 + ], + [ + "kind", + "audio" + ], + [ + "allowed_formats", + { + "list": [ + "mp3" + ] + } + ], + [ + "convertible_formats", + { + "list": [ + "wav", + "m4a", + "aac", + "ogg" + ] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "audio_thumbnail" + ], + [ + "readable_name", + "Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "audio" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "epub" + ], + [ + "readable_name", + "ePub Document" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "document" + ], + [ + "allowed_formats", + { + "list": [ + "epub" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "document" + ], + [ + "readable_name", + "Document" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "document" + ], + [ + "allowed_formats", + { + "list": [ + "pdf" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "document_thumbnail" + ], + [ + "readable_name", + "Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 4 + ], + [ + "kind", + "document" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "exercise" + ], + [ + "readable_name", + "Exercise" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 1 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "perseus" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "exercise_thumbnail" + ], + [ + "readable_name", + "Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "exercise_image" + ], + [ + "readable_name", + "Exercise Image" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 3 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg", + "gif", + "svg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "exercise_graphie" + ], + [ + "readable_name", + "Exercise Graphie" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 4 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "svg", + "json", + "graphie" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "channel_thumbnail" + ], + [ + "readable_name", + "Channel Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 0 + ], + [ + "kind", + null + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "topic_thumbnail" + ], + [ + "readable_name", + "Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "topic" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "html5_zip" + ], + [ + "readable_name", + "HTML5 Zip" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "html5" + ], + [ + "allowed_formats", + { + "list": [ + "zip" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "html5_dependency" + ], + [ + "readable_name", + "HTML5 Zip Dependency" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 3 + ], + [ + "kind", + "html5" + ], + [ + "allowed_formats", + { + "list": [ + "zip" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "html5_thumbnail" + ], + [ + "readable_name", + "HTML5 Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "html5" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "imscp_zip" + ], + [ + "readable_name", + "IMSCP Zip" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "html5" + ], + [ + "allowed_formats", + { + "list": [ + "zip" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "h5p" + ], + [ + "readable_name", + "H5P" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "h5p" + ], + [ + "allowed_formats", + { + "list": [ + "h5p" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "h5p_thumbnail" + ], + [ + "readable_name", + "H5P Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "h5p" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "zim" + ], + [ + "readable_name", + "Zim" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 1 + ], + [ + "kind", + "zim" + ], + [ + "allowed_formats", + { + "list": [ + "zim" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "zim_thumbnail" + ], + [ + "readable_name", + "Zim Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "zim" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "qti" + ], + [ + "readable_name", + "QTI" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 0 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "zip" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "qti_thumbnail" + ], + [ + "readable_name", + "QTI Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 2 + ], + [ + "kind", + "exercise" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "slideshow_image" + ], + [ + "readable_name", + "Slideshow Slide Image" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 3 + ], + [ + "kind", + "slideshow" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "slideshow_thumbnail" + ], + [ + "readable_name", + "Slideshow Thumbnail" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + true + ], + [ + "thumbnail", + true + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 2 + ], + [ + "kind", + "slideshow" + ], + [ + "allowed_formats", + { + "list": [ + "png", + "jpg", + "jpeg" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "slideshow_manifest" + ], + [ + "readable_name", + "Slideshow Manifest" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + false + ], + [ + "order", + 1 + ], + [ + "kind", + "slideshow" + ], + [ + "allowed_formats", + { + "list": [ + "json" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "bloompub" + ], + [ + "readable_name", + "Bloom Document" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 3 + ], + [ + "kind", + "document" + ], + [ + "allowed_formats", + { + "list": [ + "bloompub", + "bloomd" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + }, + { + "fields": [ + [ + "id", + "kpub" + ], + [ + "readable_name", + "Kolibri HTML5 Article" + ], + [ + "multi_language", + false + ], + [ + "supplementary", + false + ], + [ + "thumbnail", + false + ], + [ + "subtitle", + false + ], + [ + "display", + true + ], + [ + "order", + 1 + ], + [ + "kind", + "document" + ], + [ + "allowed_formats", + { + "list": [ + "kpub" + ] + } + ], + [ + "convertible_formats", + { + "list": [] + } + ] + ], + "namedtuple": "Preset", + "properties": {} + } + ] + }, + "Preset": { + "fields": [ + "id", + "readable_name", + "multi_language", + "supplementary", + "thumbnail", + "subtitle", + "display", + "order", + "kind", + "allowed_formats", + "convertible_formats" + ], + "namedtuple_class": "Preset" + }, + "QTI_THUMBNAIL": "qti_thumbnail", + "QTI_THUMBNAIL_READABLE": "QTI Thumbnail", + "QTI_ZIP": "qti", + "QTI_ZIP_READABLE": "QTI Zip", + "RENDERABLE_PRESETS_ORDER": { + "list": [ + "high_res_video", + "low_res_video", + "video_dependency", + "audio", + "audio_dependency", + "epub", + "document", + "exercise", + "html5_zip", + "html5_dependency", + "imscp_zip", + "h5p", + "zim", + "qti", + "slideshow_image", + "slideshow_manifest", + "bloompub", + "kpub" + ] + }, + "SLIDESHOW_IMAGE": "slideshow_image", + "SLIDESHOW_IMAGE_READABLE": "Slideshow Image", + "SLIDESHOW_MANIFEST": "slideshow_manifest", + "SLIDESHOW_MANIFEST_READABLE": "Slideshow Manifest", + "SLIDESHOW_THUMBNAIL": "slideshow_thumbnail", + "SLIDESHOW_THUMBNAIL_READABLE": "Slideshow Thumbnail", + "TOPIC_THUMBNAIL": "topic_thumbnail", + "TOPIC_THUMBNAIL_READABLE": "Thumbnail", + "VIDEO_DEPENDENCY": "video_dependency", + "VIDEO_DEPENDENCY_READABLE": "Video (dependency)", + "VIDEO_HIGH_RES": "high_res_video", + "VIDEO_HIGH_RES_READABLE": "High Resolution", + "VIDEO_LOW_RES": "low_res_video", + "VIDEO_LOW_RES_READABLE": "Low Resolution", + "VIDEO_SUBTITLE": "video_subtitle", + "VIDEO_SUBTITLE_READABLE": "Subtitle", + "VIDEO_THUMBNAIL": "video_thumbnail", + "VIDEO_THUMBNAIL_READABLE": "Thumbnail", + "VIDEO_VECTOR": "vector_video", + "VIDEO_VECTOR_READABLE": "Vectorized", + "ZIM": "zim", + "ZIM_READABLE": "Zim", + "ZIM_THUMBNAIL": "zim_thumbnail", + "ZIM_THUMBNAIL_READABLE": "Zim Thumbnail", + "choices": { + "tuple": [ + { + "tuple": [ + "high_res_video", + "High Resolution" + ] + }, + { + "tuple": [ + "low_res_video", + "Low Resolution" + ] + }, + { + "tuple": [ + "video_thumbnail", + "Thumbnail" + ] + }, + { + "tuple": [ + "video_subtitle", + "Subtitle" + ] + }, + { + "tuple": [ + "video_dependency", + "Video (dependency)" + ] + }, + { + "tuple": [ + "audio", + "Audio" + ] + }, + { + "tuple": [ + "audio_thumbnail", + "Thumbnail" + ] + }, + { + "tuple": [ + "audio_dependency", + "audio (dependency)" + ] + }, + { + "tuple": [ + "document", + "Document" + ] + }, + { + "tuple": [ + "epub", + "ePub Document" + ] + }, + { + "tuple": [ + "document_thumbnail", + "Thumbnail" + ] + }, + { + "tuple": [ + "exercise", + "Exercise" + ] + }, + { + "tuple": [ + "exercise_thumbnail", + "Thumbnail" + ] + }, + { + "tuple": [ + "exercise_image", + "Exercise Image" + ] + }, + { + "tuple": [ + "exercise_graphie", + "Exercise Graphie" + ] + }, + { + "tuple": [ + "channel_thumbnail", + "Channel Thumbnail" + ] + }, + { + "tuple": [ + "topic_thumbnail", + "Thumbnail" + ] + }, + { + "tuple": [ + "html5_zip", + "HTML5 Zip" + ] + }, + { + "tuple": [ + "html5_dependency", + "HTML5 Dependency (Zip format)" + ] + }, + { + "tuple": [ + "html5_thumbnail", + "HTML5 Thumbnail" + ] + }, + { + "tuple": [ + "h5p", + "H5P Zip" + ] + }, + { + "tuple": [ + "h5p_thumbnail", + "H5P Thumbnail" + ] + }, + { + "tuple": [ + "zim", + "Zim" + ] + }, + { + "tuple": [ + "zim_thumbnail", + "Zim Thumbnail" + ] + }, + { + "tuple": [ + "qti", + "QTI Zip" + ] + }, + { + "tuple": [ + "qti_thumbnail", + "QTI Thumbnail" + ] + }, + { + "tuple": [ + "slideshow_image", + "Slideshow Image" + ] + }, + { + "tuple": [ + "slideshow_thumbnail", + "Slideshow Thumbnail" + ] + }, + { + "tuple": [ + "slideshow_manifest", + "Slideshow Manifest" + ] + }, + { + "tuple": [ + "imscp_zip", + "IMSCP Zip" + ] + }, + { + "tuple": [ + "bloompub", + "Bloom Document" + ] + }, + { + "tuple": [ + "kpub", + "Kolibri HTML5 Article" + ] + } + ] + }, + "generate_list": { + "function": "(constantlist)" + } + }, + "languages": { + "LANGUAGELIST": { + "list": [ + { + "fields": [ + [ + "native_name", + "Afaraf" + ], + [ + "primary_code", + "aa" + ], + [ + "subcode", + null + ], + [ + "name", + "Afar" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "aa", + "first_native_name": "Afaraf", + "id": "aa" + } + }, + { + "fields": [ + [ + "native_name", + "\u0430\u04a7\u0441\u0443\u0430" + ], + [ + "primary_code", + "ab" + ], + [ + "subcode", + null + ], + [ + "name", + "Abkhaz" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ab", + "first_native_name": "\u0430\u04a7\u0441\u0443\u0430", + "id": "ab" + } + }, + { + "fields": [ + [ + "native_name", + "Acholi" + ], + [ + "primary_code", + "ach" + ], + [ + "subcode", + null + ], + [ + "name", + "Acholi; Acooli; Akoli" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ach", + "first_native_name": "Acholi", + "id": "ach" + } + }, + { + "fields": [ + [ + "native_name", + "avesta" + ], + [ + "primary_code", + "ae" + ], + [ + "subcode", + null + ], + [ + "name", + "Avestan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ae", + "first_native_name": "avesta", + "id": "ae" + } + }, + { + "fields": [ + [ + "native_name", + "Afrikaans" + ], + [ + "primary_code", + "af" + ], + [ + "subcode", + null + ], + [ + "name", + "Afrikaans" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "af", + "first_native_name": "Afrikaans", + "id": "af" + } + }, + { + "fields": [ + [ + "native_name", + "Akan" + ], + [ + "primary_code", + "ak" + ], + [ + "subcode", + null + ], + [ + "name", + "Akan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ak", + "first_native_name": "Akan", + "id": "ak" + } + }, + { + "fields": [ + [ + "native_name", + "Akan" + ], + [ + "primary_code", + "aka" + ], + [ + "subcode", + null + ], + [ + "name", + "Akan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "aka", + "first_native_name": "Akan", + "id": "aka" + } + }, + { + "fields": [ + [ + "native_name", + "\u12a0\u121b\u122d\u129b" + ], + [ + "primary_code", + "am" + ], + [ + "subcode", + null + ], + [ + "name", + "Amharic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "am", + "first_native_name": "\u12a0\u121b\u122d\u129b", + "id": "am" + } + }, + { + "fields": [ + [ + "native_name", + "Aragon\u00e9s" + ], + [ + "primary_code", + "an" + ], + [ + "subcode", + null + ], + [ + "name", + "Aragonese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "an", + "first_native_name": "Aragon\u00e9s", + "id": "an" + } + }, + { + "fields": [ + [ + "native_name", + "\u0627\u0644\u0639\u0631\u0628\u064a\u0629" + ], + [ + "primary_code", + "ar" + ], + [ + "subcode", + null + ], + [ + "name", + "Arabic" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ar", + "first_native_name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629", + "id": "ar" + } + }, + { + "fields": [ + [ + "native_name", + "\u062f\u0632\u064a\u0631\u064a\u0629" + ], + [ + "primary_code", + "arq" + ], + [ + "subcode", + null + ], + [ + "name", + "Algerian; Darja" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "arq", + "first_native_name": "\u062f\u0632\u064a\u0631\u064a\u0629", + "id": "arq" + } + }, + { + "fields": [ + [ + "native_name", + "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be" + ], + [ + "primary_code", + "as" + ], + [ + "subcode", + null + ], + [ + "name", + "Assamese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "as", + "first_native_name": "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be", + "id": "as" + } + }, + { + "fields": [ + [ + "native_name", + "\u0430\u0432\u0430\u0440 \u043c\u0430\u0446\u04c0, \u043c\u0430\u0433\u04c0\u0430\u0440\u0443\u043b \u043c\u0430\u0446\u04c0" + ], + [ + "primary_code", + "av" + ], + [ + "subcode", + null + ], + [ + "name", + "Avaric" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "av", + "first_native_name": "\u0430\u0432\u0430\u0440 \u043c\u0430\u0446\u04c0", + "id": "av" + } + }, + { + "fields": [ + [ + "native_name", + "\u0905\u0935\u0927\u0940" + ], + [ + "primary_code", + "awa" + ], + [ + "subcode", + null + ], + [ + "name", + "Awadhi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "awa", + "first_native_name": "\u0905\u0935\u0927\u0940", + "id": "awa" + } + }, + { + "fields": [ + [ + "native_name", + "aymar aru" + ], + [ + "primary_code", + "ay" + ], + [ + "subcode", + null + ], + [ + "name", + "Aymara" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ay", + "first_native_name": "aymar aru", + "id": "ay" + } + }, + { + "fields": [ + [ + "native_name", + "az\u0259rbaycan dili" + ], + [ + "primary_code", + "az" + ], + [ + "subcode", + null + ], + [ + "name", + "Azerbaijani" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "az", + "first_native_name": "az\u0259rbaycan dili", + "id": "az" + } + }, + { + "fields": [ + [ + "native_name", + "\u0431\u0430\u0448\u04a1\u043e\u0440\u0442 \u0442\u0435\u043b\u0435" + ], + [ + "primary_code", + "ba" + ], + [ + "subcode", + null + ], + [ + "name", + "Bashkir" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ba", + "first_native_name": "\u0431\u0430\u0448\u04a1\u043e\u0440\u0442 \u0442\u0435\u043b\u0435", + "id": "ba" + } + }, + { + "fields": [ + [ + "native_name", + "Southern Balochi" + ], + [ + "primary_code", + "bcc" + ], + [ + "subcode", + null + ], + [ + "name", + "Southern Balochi" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bcc", + "first_native_name": "Southern Balochi", + "id": "bcc" + } + }, + { + "fields": [ + [ + "native_name", + "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f" + ], + [ + "primary_code", + "be" + ], + [ + "subcode", + null + ], + [ + "name", + "Belarusian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "be", + "first_native_name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f", + "id": "be" + } + }, + { + "fields": [ + [ + "native_name", + "Tara\u0161kievica, \u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430, \u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f \u043a\u043b\u044f\u0441\u044b\u0447\u043d\u044b \u043f\u0440\u0430\u0432\u0430\u043f\u0456\u0441" + ], + [ + "primary_code", + "be" + ], + [ + "subcode", + "tarask" + ], + [ + "name", + "Belarusian, Classical Orthography" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "be-tarask", + "first_native_name": "Tara\u0161kievica", + "id": "be-tarask" + } + }, + { + "fields": [ + [ + "native_name", + "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a" + ], + [ + "primary_code", + "bg" + ], + [ + "subcode", + null + ], + [ + "name", + "Bulgarian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bg", + "first_native_name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a", + "id": "bg" + } + }, + { + "fields": [ + [ + "native_name", + "\u092d\u094b\u091c\u092a\u0941\u0930\u0940" + ], + [ + "primary_code", + "bh" + ], + [ + "subcode", + null + ], + [ + "name", + "Bihari" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bh", + "first_native_name": "\u092d\u094b\u091c\u092a\u0941\u0930\u0940", + "id": "bh" + } + }, + { + "fields": [ + [ + "native_name", + "\u092d\u094b\u091c\u092a\u0941\u0930\u0940" + ], + [ + "primary_code", + "bho" + ], + [ + "subcode", + null + ], + [ + "name", + "Bhojpuri; Bajpuri; Bhojapuri" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bho", + "first_native_name": "\u092d\u094b\u091c\u092a\u0941\u0930\u0940", + "id": "bho" + } + }, + { + "fields": [ + [ + "native_name", + "Bislama" + ], + [ + "primary_code", + "bi" + ], + [ + "subcode", + null + ], + [ + "name", + "Bislama" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bi", + "first_native_name": "Bislama", + "id": "bi" + } + }, + { + "fields": [ + [ + "native_name", + "bamanankan" + ], + [ + "primary_code", + "bm" + ], + [ + "subcode", + null + ], + [ + "name", + "Bambara" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bm", + "first_native_name": "bamanankan", + "id": "bm" + } + }, + { + "fields": [ + [ + "native_name", + "Lame" + ], + [ + "primary_code", + "bma" + ], + [ + "subcode", + null + ], + [ + "name", + "Lame" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bma", + "first_native_name": "Lame", + "id": "bma" + } + }, + { + "fields": [ + [ + "native_name", + "\u09ac\u09be\u0982\u09b2\u09be" + ], + [ + "primary_code", + "bn" + ], + [ + "subcode", + null + ], + [ + "name", + "Bengali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bn", + "first_native_name": "\u09ac\u09be\u0982\u09b2\u09be", + "id": "bn" + } + }, + { + "fields": [ + [ + "native_name", + "\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42" + ], + [ + "primary_code", + "bo" + ], + [ + "subcode", + null + ], + [ + "name", + "Tibetan Standard; Tibetan, Central" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bo", + "first_native_name": "\u0f56\u0f7c\u0f51\u0f0b\u0f61\u0f72\u0f42", + "id": "bo" + } + }, + { + "fields": [ + [ + "native_name", + "Bamako Sign Language" + ], + [ + "primary_code", + "bog" + ], + [ + "subcode", + null + ], + [ + "name", + "Bamako Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bog", + "first_native_name": "Bamako Sign Language", + "id": "bog" + } + }, + { + "fields": [ + [ + "native_name", + "brezhoneg" + ], + [ + "primary_code", + "br" + ], + [ + "subcode", + null + ], + [ + "name", + "Breton" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "br", + "first_native_name": "brezhoneg", + "id": "br" + } + }, + { + "fields": [ + [ + "native_name", + "Brahui" + ], + [ + "primary_code", + "brh" + ], + [ + "subcode", + null + ], + [ + "name", + "Brahui" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "brh", + "first_native_name": "Brahui", + "id": "brh" + } + }, + { + "fields": [ + [ + "native_name", + "bosanski jezik" + ], + [ + "primary_code", + "bs" + ], + [ + "subcode", + null + ], + [ + "name", + "Bosnian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bs", + "first_native_name": "bosanski jezik", + "id": "bs" + } + }, + { + "fields": [ + [ + "native_name", + "Buginese" + ], + [ + "primary_code", + "bug" + ], + [ + "subcode", + null + ], + [ + "name", + "Buginese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bug", + "first_native_name": "Buginese", + "id": "bug" + } + }, + { + "fields": [ + [ + "native_name", + "Bukusu" + ], + [ + "primary_code", + "bxk" + ], + [ + "subcode", + null + ], + [ + "name", + "Bukusu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "bxk", + "first_native_name": "Bukusu", + "id": "bxk" + } + }, + { + "fields": [ + [ + "native_name", + "Catal\u00e0" + ], + [ + "primary_code", + "ca" + ], + [ + "subcode", + null + ], + [ + "name", + "Catalan; Valencian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ca", + "first_native_name": "Catal\u00e0", + "id": "ca" + } + }, + { + "fields": [ + [ + "native_name", + "\u043d\u043e\u0445\u0447\u0438\u0439\u043d \u043c\u043e\u0442\u0442" + ], + [ + "primary_code", + "ce" + ], + [ + "subcode", + null + ], + [ + "name", + "Chechen" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ce", + "first_native_name": "\u043d\u043e\u0445\u0447\u0438\u0439\u043d \u043c\u043e\u0442\u0442", + "id": "ce" + } + }, + { + "fields": [ + [ + "native_name", + "Cebuano" + ], + [ + "primary_code", + "ceb" + ], + [ + "subcode", + null + ], + [ + "name", + "Cebuano" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ceb", + "first_native_name": "Cebuano", + "id": "ceb" + } + }, + { + "fields": [ + [ + "native_name", + "Chamoru" + ], + [ + "primary_code", + "ch" + ], + [ + "subcode", + null + ], + [ + "name", + "Chamorro" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ch", + "first_native_name": "Chamoru", + "id": "ch" + } + }, + { + "fields": [ + [ + "native_name", + "Choctaw" + ], + [ + "primary_code", + "cho" + ], + [ + "subcode", + null + ], + [ + "name", + "Choctaw" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cho", + "first_native_name": "Choctaw", + "id": "cho" + } + }, + { + "fields": [ + [ + "native_name", + "corsu, lingua corsa" + ], + [ + "primary_code", + "co" + ], + [ + "subcode", + null + ], + [ + "name", + "Corsican" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "co", + "first_native_name": "corsu", + "id": "co" + } + }, + { + "fields": [ + [ + "native_name", + "\u14c0\u1426\u1403\u152d\u140d\u140f\u1423" + ], + [ + "primary_code", + "cr" + ], + [ + "subcode", + null + ], + [ + "name", + "Cree" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cr", + "first_native_name": "\u14c0\u1426\u1403\u152d\u140d\u140f\u1423", + "id": "cr" + } + }, + { + "fields": [ + [ + "native_name", + "\u010desky, \u010de\u0161tina" + ], + [ + "primary_code", + "cs" + ], + [ + "subcode", + null + ], + [ + "name", + "Czech" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cs", + "first_native_name": "\u010desky", + "id": "cs" + } + }, + { + "fields": [ + [ + "native_name", + "Cambodian Sign Language" + ], + [ + "primary_code", + "csx" + ], + [ + "subcode", + null + ], + [ + "name", + "Cambodian Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "csx", + "first_native_name": "Cambodian Sign Language", + "id": "csx" + } + }, + { + "fields": [ + [ + "native_name", + "\u0469\u0437\u044b\u043a\u044a \u0441\u043b\u043e\u0432\u0463\u043d\u044c\u0441\u043a\u044a" + ], + [ + "primary_code", + "cu" + ], + [ + "subcode", + null + ], + [ + "name", + "Old Church Slavonic; Church Slavic; Church Slavonic; Old Bulgarian; Old Slavonic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cu", + "first_native_name": "\u0469\u0437\u044b\u043a\u044a \u0441\u043b\u043e\u0432\u0463\u043d\u044c\u0441\u043a\u044a", + "id": "cu" + } + }, + { + "fields": [ + [ + "native_name", + "\u0447\u04d1\u0432\u0430\u0448 \u0447\u04d7\u043b\u0445\u0438" + ], + [ + "primary_code", + "cv" + ], + [ + "subcode", + null + ], + [ + "name", + "Chuvash" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cv", + "first_native_name": "\u0447\u04d1\u0432\u0430\u0448 \u0447\u04d7\u043b\u0445\u0438", + "id": "cv" + } + }, + { + "fields": [ + [ + "native_name", + "Cymraeg" + ], + [ + "primary_code", + "cy" + ], + [ + "subcode", + null + ], + [ + "name", + "Welsh" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "cy", + "first_native_name": "Cymraeg", + "id": "cy" + } + }, + { + "fields": [ + [ + "native_name", + "Dansk" + ], + [ + "primary_code", + "da" + ], + [ + "subcode", + null + ], + [ + "name", + "Danish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "da", + "first_native_name": "Dansk", + "id": "da" + } + }, + { + "fields": [ + [ + "native_name", + "Deutsch" + ], + [ + "primary_code", + "de" + ], + [ + "subcode", + null + ], + [ + "name", + "German" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "de", + "first_native_name": "Deutsch", + "id": "de" + } + }, + { + "fields": [ + [ + "native_name", + "Dotyali" + ], + [ + "primary_code", + "dty" + ], + [ + "subcode", + null + ], + [ + "name", + "Dotyali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "dty", + "first_native_name": "Dotyali", + "id": "dty" + } + }, + { + "fields": [ + [ + "native_name", + "\u078b\u07a8\u0788\u07ac\u0780\u07a8" + ], + [ + "primary_code", + "dv" + ], + [ + "subcode", + null + ], + [ + "name", + "Divehi; Dhivehi; Maldivian" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "dv", + "first_native_name": "\u078b\u07a8\u0788\u07ac\u0780\u07a8", + "id": "dv" + } + }, + { + "fields": [ + [ + "native_name", + "E\u028begbe" + ], + [ + "primary_code", + "ee" + ], + [ + "subcode", + null + ], + [ + "name", + "Ewe" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ee", + "first_native_name": "E\u028begbe", + "id": "ee" + } + }, + { + "fields": [ + [ + "native_name", + "Efik" + ], + [ + "primary_code", + "efi" + ], + [ + "subcode", + null + ], + [ + "name", + "Efik" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "efi", + "first_native_name": "Efik", + "id": "efi" + } + }, + { + "fields": [ + [ + "native_name", + "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac" + ], + [ + "primary_code", + "el" + ], + [ + "subcode", + null + ], + [ + "name", + "Greek, Modern" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "el", + "first_native_name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac", + "id": "el" + } + }, + { + "fields": [ + [ + "native_name", + "English" + ], + [ + "primary_code", + "en" + ], + [ + "subcode", + null + ], + [ + "name", + "English" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "en", + "first_native_name": "English", + "id": "en" + } + }, + { + "fields": [ + [ + "native_name", + "British English" + ], + [ + "primary_code", + "en" + ], + [ + "subcode", + "GB" + ], + [ + "name", + "English, Britain" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "en-GB", + "first_native_name": "British English", + "id": "en-GB" + } + }, + { + "fields": [ + [ + "native_name", + "Argh! Pirates!" + ], + [ + "primary_code", + "en" + ], + [ + "subcode", + "PT" + ], + [ + "name", + "English, Pirate" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "en-PT", + "first_native_name": "Argh! Pirates!", + "id": "en-PT" + } + }, + { + "fields": [ + [ + "native_name", + "Enga" + ], + [ + "primary_code", + "enq" + ], + [ + "subcode", + null + ], + [ + "name", + "Enga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "enq", + "first_native_name": "Enga", + "id": "enq" + } + }, + { + "fields": [ + [ + "native_name", + "Esperanto" + ], + [ + "primary_code", + "eo" + ], + [ + "subcode", + null + ], + [ + "name", + "Esperanto" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "eo", + "first_native_name": "Esperanto", + "id": "eo" + } + }, + { + "fields": [ + [ + "native_name", + "Espa\u00f1ol" + ], + [ + "primary_code", + "es" + ], + [ + "subcode", + null + ], + [ + "name", + "Spanish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "es", + "first_native_name": "Espa\u00f1ol", + "id": "es" + } + }, + { + "fields": [ + [ + "native_name", + "Espa\u00f1ol (Argentina)" + ], + [ + "primary_code", + "es" + ], + [ + "subcode", + "AR" + ], + [ + "name", + "Spanish, Argentina" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "es-AR", + "first_native_name": "Espa\u00f1ol (Argentina)", + "id": "es-AR" + } + }, + { + "fields": [ + [ + "native_name", + "Espa\u00f1ol (Espa\u00f1a), Castellano" + ], + [ + "primary_code", + "es" + ], + [ + "subcode", + "ES" + ], + [ + "name", + "Spanish, Spain; Castilian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "es-ES", + "first_native_name": "Espa\u00f1ol (Espa\u00f1a)", + "id": "es-ES" + } + }, + { + "fields": [ + [ + "native_name", + "Espa\u00f1ol (Mexico)" + ], + [ + "primary_code", + "es" + ], + [ + "subcode", + "MX" + ], + [ + "name", + "Spanish, Mexico" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "es-MX", + "first_native_name": "Espa\u00f1ol (Mexico)", + "id": "es-MX" + } + }, + { + "fields": [ + [ + "native_name", + "Espa\u00f1ol (Nicaragua)" + ], + [ + "primary_code", + "es" + ], + [ + "subcode", + "NI" + ], + [ + "name", + "Spanish, Nicaragua" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "es-NI", + "first_native_name": "Espa\u00f1ol (Nicaragua)", + "id": "es-NI" + } + }, + { + "fields": [ + [ + "native_name", + "eesti, eesti keel" + ], + [ + "primary_code", + "et" + ], + [ + "subcode", + null + ], + [ + "name", + "Estonian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "et", + "first_native_name": "eesti", + "id": "et" + } + }, + { + "fields": [ + [ + "native_name", + "euskara, euskera" + ], + [ + "primary_code", + "eu" + ], + [ + "subcode", + null + ], + [ + "name", + "Basque" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "eu", + "first_native_name": "euskara", + "id": "eu" + } + }, + { + "fields": [ + [ + "native_name", + "\u0641\u0627\u0631\u0633\u06cc" + ], + [ + "primary_code", + "fa" + ], + [ + "subcode", + null + ], + [ + "name", + "Persian" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fa", + "first_native_name": "\u0641\u0627\u0631\u0633\u06cc", + "id": "fa" + } + }, + { + "fields": [ + [ + "native_name", + "Fulfulde, Pulaar, Pular" + ], + [ + "primary_code", + "ff" + ], + [ + "subcode", + null + ], + [ + "name", + "Fula; Fulah; Pulaar; Pular" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ff", + "first_native_name": "Fulfulde", + "id": "ff" + } + }, + { + "fields": [ + [ + "native_name", + "suomi, suomen kieli" + ], + [ + "primary_code", + "fi" + ], + [ + "subcode", + null + ], + [ + "name", + "Finnish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fi", + "first_native_name": "suomi", + "id": "fi" + } + }, + { + "fields": [ + [ + "native_name", + "Pilipino" + ], + [ + "primary_code", + "fil" + ], + [ + "subcode", + null + ], + [ + "name", + "Filipino" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fil", + "first_native_name": "Pilipino", + "id": "fil" + } + }, + { + "fields": [ + [ + "native_name", + "vosa Vakaviti" + ], + [ + "primary_code", + "fj" + ], + [ + "subcode", + null + ], + [ + "name", + "Fijian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fj", + "first_native_name": "vosa Vakaviti", + "id": "fj" + } + }, + { + "fields": [ + [ + "native_name", + "f\u00f8royskt" + ], + [ + "primary_code", + "fo" + ], + [ + "subcode", + null + ], + [ + "name", + "Faroese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fo", + "first_native_name": "f\u00f8royskt", + "id": "fo" + } + }, + { + "fields": [ + [ + "native_name", + "Fran\u00e7ais, langue fran\u00e7aise" + ], + [ + "primary_code", + "fr" + ], + [ + "subcode", + null + ], + [ + "name", + "French" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fr", + "first_native_name": "Fran\u00e7ais", + "id": "fr" + } + }, + { + "fields": [ + [ + "native_name", + "Fran\u00e7ais (Canada)" + ], + [ + "primary_code", + "fr" + ], + [ + "subcode", + "CA" + ], + [ + "name", + "French, Canada" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fr-CA", + "first_native_name": "Fran\u00e7ais (Canada)", + "id": "fr-CA" + } + }, + { + "fields": [ + [ + "native_name", + "Fulfulde" + ], + [ + "primary_code", + "ful" + ], + [ + "subcode", + null + ], + [ + "name", + "Fula; Fulah" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ful", + "first_native_name": "Fulfulde", + "id": "ful" + } + }, + { + "fields": [ + [ + "native_name", + "Fulfulde" + ], + [ + "primary_code", + "fuv" + ], + [ + "subcode", + null + ], + [ + "name", + "Fulfulde Mbororo; Fulfulde Mbororoore" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fuv", + "first_native_name": "Fulfulde", + "id": "fuv" + } + }, + { + "fields": [ + [ + "native_name", + "Frysk" + ], + [ + "primary_code", + "fy" + ], + [ + "subcode", + null + ], + [ + "name", + "Western Frisian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fy", + "first_native_name": "Frysk", + "id": "fy" + } + }, + { + "fields": [ + [ + "native_name", + "Frysk" + ], + [ + "primary_code", + "fy" + ], + [ + "subcode", + "NL" + ], + [ + "name", + "Frisian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "fy-NL", + "first_native_name": "Frysk", + "id": "fy-NL" + } + }, + { + "fields": [ + [ + "native_name", + "Gaeilge" + ], + [ + "primary_code", + "ga" + ], + [ + "subcode", + null + ], + [ + "name", + "Irish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ga", + "first_native_name": "Gaeilge", + "id": "ga" + } + }, + { + "fields": [ + [ + "native_name", + "G\u00e0idhlig" + ], + [ + "primary_code", + "gd" + ], + [ + "subcode", + null + ], + [ + "name", + "Scottish Gaelic; Gaelic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "gd", + "first_native_name": "G\u00e0idhlig", + "id": "gd" + } + }, + { + "fields": [ + [ + "native_name", + "Galego" + ], + [ + "primary_code", + "gl" + ], + [ + "subcode", + null + ], + [ + "name", + "Galician" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "gl", + "first_native_name": "Galego", + "id": "gl" + } + }, + { + "fields": [ + [ + "native_name", + "Ava\u00f1e\u1ebd" + ], + [ + "primary_code", + "gn" + ], + [ + "subcode", + null + ], + [ + "name", + "Guaran\u00ed" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "gn", + "first_native_name": "Ava\u00f1e\u1ebd", + "id": "gn" + } + }, + { + "fields": [ + [ + "native_name", + "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0" + ], + [ + "primary_code", + "gu" + ], + [ + "subcode", + null + ], + [ + "name", + "Gujarati" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "gu", + "first_native_name": "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0", + "id": "gu" + } + }, + { + "fields": [ + [ + "native_name", + "Ekegusii" + ], + [ + "primary_code", + "guz" + ], + [ + "subcode", + null + ], + [ + "name", + "Gusii" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "guz", + "first_native_name": "Ekegusii", + "id": "guz" + } + }, + { + "fields": [ + [ + "native_name", + "Gaelg, Gailck" + ], + [ + "primary_code", + "gv" + ], + [ + "subcode", + null + ], + [ + "name", + "Manx" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "gv", + "first_native_name": "Gaelg", + "id": "gv" + } + }, + { + "fields": [ + [ + "native_name", + "Hausa, \u0647\u064e\u0648\u064f\u0633\u064e" + ], + [ + "primary_code", + "ha" + ], + [ + "subcode", + null + ], + [ + "name", + "Hausa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ha", + "first_native_name": "Hausa", + "id": "ha" + } + }, + { + "fields": [ + [ + "native_name", + "Hausa, \u0647\u064e\u0648\u064f\u0633\u064e" + ], + [ + "primary_code", + "hau" + ], + [ + "subcode", + null + ], + [ + "name", + "Hausa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hau", + "first_native_name": "Hausa", + "id": "hau" + } + }, + { + "fields": [ + [ + "native_name", + "Hadiyyisa" + ], + [ + "primary_code", + "hdy" + ], + [ + "subcode", + null + ], + [ + "name", + "Hadiyya; Hadiya; Adea; Adiya; Hadia" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hdy", + "first_native_name": "Hadiyyisa", + "id": "hdy" + } + }, + { + "fields": [ + [ + "native_name", + "\u05e2\u05d1\u05e8\u05d9\u05ea" + ], + [ + "primary_code", + "he" + ], + [ + "subcode", + null + ], + [ + "name", + "Hebrew (modern)" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "he", + "first_native_name": "\u05e2\u05d1\u05e8\u05d9\u05ea", + "id": "he" + } + }, + { + "fields": [ + [ + "native_name", + "\u0939\u093f\u0928\u094d\u0926\u0940, \u0939\u093f\u0902\u0926\u0940" + ], + [ + "primary_code", + "hi" + ], + [ + "subcode", + null + ], + [ + "name", + "Hindi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hi", + "first_native_name": "\u0939\u093f\u0928\u094d\u0926\u0940", + "id": "hi" + } + }, + { + "fields": [ + [ + "native_name", + "Hiri Motu" + ], + [ + "primary_code", + "ho" + ], + [ + "subcode", + null + ], + [ + "name", + "Hiri Motu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ho", + "first_native_name": "Hiri Motu", + "id": "ho" + } + }, + { + "fields": [ + [ + "native_name", + "hrvatski" + ], + [ + "primary_code", + "hr" + ], + [ + "subcode", + null + ], + [ + "name", + "Croatian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hr", + "first_native_name": "hrvatski", + "id": "hr" + } + }, + { + "fields": [ + [ + "native_name", + "Hunsr\u00fcckisch, Hunsr\u00fcck, Hunsriker" + ], + [ + "primary_code", + "hrx" + ], + [ + "subcode", + null + ], + [ + "name", + "Hunsrik" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hrx", + "first_native_name": "Hunsr\u00fcckisch", + "id": "hrx" + } + }, + { + "fields": [ + [ + "native_name", + "Krey\u00f2l ayisyen" + ], + [ + "primary_code", + "ht" + ], + [ + "subcode", + null + ], + [ + "name", + "Haitian; Haitian Creole" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ht", + "first_native_name": "Krey\u00f2l ayisyen", + "id": "ht" + } + }, + { + "fields": [ + [ + "native_name", + "Magyar" + ], + [ + "primary_code", + "hu" + ], + [ + "subcode", + null + ], + [ + "name", + "Hungarian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hu", + "first_native_name": "Magyar", + "id": "hu" + } + }, + { + "fields": [ + [ + "native_name", + "\u0540\u0561\u0575\u0565\u0580\u0565\u0576" + ], + [ + "primary_code", + "hy" + ], + [ + "subcode", + null + ], + [ + "name", + "Armenian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hy", + "first_native_name": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576", + "id": "hy" + } + }, + { + "fields": [ + [ + "native_name", + "Otjiherero" + ], + [ + "primary_code", + "hz" + ], + [ + "subcode", + null + ], + [ + "name", + "Herero" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "hz", + "first_native_name": "Otjiherero", + "id": "hz" + } + }, + { + "fields": [ + [ + "native_name", + "Interlingua" + ], + [ + "primary_code", + "ia" + ], + [ + "subcode", + null + ], + [ + "name", + "Interlingua" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ia", + "first_native_name": "Interlingua", + "id": "ia" + } + }, + { + "fields": [ + [ + "native_name", + "As\u1ee5s\u1ee5 Igbo" + ], + [ + "primary_code", + "ibo" + ], + [ + "subcode", + null + ], + [ + "name", + "Igbo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ibo", + "first_native_name": "As\u1ee5s\u1ee5 Igbo", + "id": "ibo" + } + }, + { + "fields": [ + [ + "native_name", + "Bahasa Indonesia" + ], + [ + "primary_code", + "id" + ], + [ + "subcode", + null + ], + [ + "name", + "Indonesian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "id", + "first_native_name": "Bahasa Indonesia", + "id": "id" + } + }, + { + "fields": [ + [ + "native_name", + "Originally called Occidental; then Interlingue after WWII" + ], + [ + "primary_code", + "ie" + ], + [ + "subcode", + null + ], + [ + "name", + "Interlingue" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ie", + "first_native_name": "Originally called Occidental; then Interlingue after WWII", + "id": "ie" + } + }, + { + "fields": [ + [ + "native_name", + "As\u1ee5s\u1ee5 Igbo" + ], + [ + "primary_code", + "ig" + ], + [ + "subcode", + null + ], + [ + "name", + "Igbo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ig", + "first_native_name": "As\u1ee5s\u1ee5 Igbo", + "id": "ig" + } + }, + { + "fields": [ + [ + "native_name", + "\ua188\ua320\ua4bf Nuosuhxop" + ], + [ + "primary_code", + "ii" + ], + [ + "subcode", + null + ], + [ + "name", + "Nuosu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ii", + "first_native_name": "\ua188\ua320\ua4bf Nuosuhxop", + "id": "ii" + } + }, + { + "fields": [ + [ + "native_name", + "I\u00f1upiaq, I\u00f1upiatun" + ], + [ + "primary_code", + "ik" + ], + [ + "subcode", + null + ], + [ + "name", + "Inupiaq" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ik", + "first_native_name": "I\u00f1upiaq", + "id": "ik" + } + }, + { + "fields": [ + [ + "native_name", + "Ido" + ], + [ + "primary_code", + "io" + ], + [ + "subcode", + null + ], + [ + "name", + "Ido" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "io", + "first_native_name": "Ido", + "id": "io" + } + }, + { + "fields": [ + [ + "native_name", + "\u00cdslenska" + ], + [ + "primary_code", + "is" + ], + [ + "subcode", + null + ], + [ + "name", + "Icelandic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "is", + "first_native_name": "\u00cdslenska", + "id": "is" + } + }, + { + "fields": [ + [ + "native_name", + "Italiano" + ], + [ + "primary_code", + "it" + ], + [ + "subcode", + null + ], + [ + "name", + "Italian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "it", + "first_native_name": "Italiano", + "id": "it" + } + }, + { + "fields": [ + [ + "native_name", + "\u1403\u14c4\u1483\u144e\u1450\u1466" + ], + [ + "primary_code", + "iu" + ], + [ + "subcode", + null + ], + [ + "name", + "Inuktitut" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "iu", + "first_native_name": "\u1403\u14c4\u1483\u144e\u1450\u1466", + "id": "iu" + } + }, + { + "fields": [ + [ + "native_name", + "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054\uff0f\u306b\u3063\u307d\u3093\u3054)" + ], + [ + "primary_code", + "ja" + ], + [ + "subcode", + null + ], + [ + "name", + "Japanese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ja", + "first_native_name": "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054\uff0f\u306b\u3063\u307d\u3093\u3054)", + "id": "ja" + } + }, + { + "fields": [ + [ + "native_name", + "basa Jawa" + ], + [ + "primary_code", + "jv" + ], + [ + "subcode", + null + ], + [ + "name", + "Javanese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "jv", + "first_native_name": "basa Jawa", + "id": "jv" + } + }, + { + "fields": [ + [ + "native_name", + "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8" + ], + [ + "primary_code", + "ka" + ], + [ + "subcode", + null + ], + [ + "name", + "Georgian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ka", + "first_native_name": "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8", + "id": "ka" + } + }, + { + "fields": [ + [ + "native_name", + "Kalanguya" + ], + [ + "primary_code", + "kak" + ], + [ + "subcode", + null + ], + [ + "name", + "Kalanguya" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kak", + "first_native_name": "Kalanguya", + "id": "kak" + } + }, + { + "fields": [ + [ + "native_name", + "Kikamba" + ], + [ + "primary_code", + "kam" + ], + [ + "subcode", + null + ], + [ + "name", + "Kamba (Kenya)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kam", + "first_native_name": "Kikamba", + "id": "kam" + } + }, + { + "fields": [ + [ + "native_name", + "KiKongo" + ], + [ + "primary_code", + "kg" + ], + [ + "subcode", + null + ], + [ + "name", + "Kongo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kg", + "first_native_name": "KiKongo", + "id": "kg" + } + }, + { + "fields": [ + [ + "native_name", + "G\u0129k\u0169y\u0169" + ], + [ + "primary_code", + "ki" + ], + [ + "subcode", + null + ], + [ + "name", + "Kikuyu; Gikuyu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ki", + "first_native_name": "G\u0129k\u0169y\u0169", + "id": "ki" + } + }, + { + "fields": [ + [ + "native_name", + "G\u0129k\u0169y\u0169" + ], + [ + "primary_code", + "kik" + ], + [ + "subcode", + null + ], + [ + "name", + "Kikuyu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kik", + "first_native_name": "G\u0129k\u0169y\u0169", + "id": "kik" + } + }, + { + "fields": [ + [ + "native_name", + "Kuanyama" + ], + [ + "primary_code", + "kj" + ], + [ + "subcode", + null + ], + [ + "name", + "Kwanyama; Kuanyama" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kj", + "first_native_name": "Kuanyama", + "id": "kj" + } + }, + { + "fields": [ + [ + "native_name", + "\u049a\u0430\u0437\u0430\u049b \u0442\u0456\u043b\u0456" + ], + [ + "primary_code", + "kk" + ], + [ + "subcode", + null + ], + [ + "name", + "Kazakh" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kk", + "first_native_name": "\u049a\u0430\u0437\u0430\u049b \u0442\u0456\u043b\u0456", + "id": "kk" + } + }, + { + "fields": [ + [ + "native_name", + "kalaallisut, kalaallit oqaasii" + ], + [ + "primary_code", + "kl" + ], + [ + "subcode", + null + ], + [ + "name", + "Kalaallisut, Greenlandic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kl", + "first_native_name": "kalaallisut", + "id": "kl" + } + }, + { + "fields": [ + [ + "native_name", + "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a" + ], + [ + "primary_code", + "km" + ], + [ + "subcode", + null + ], + [ + "name", + "Khmer" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "km", + "first_native_name": "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a", + "id": "km" + } + }, + { + "fields": [ + [ + "native_name", + "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1" + ], + [ + "primary_code", + "kn" + ], + [ + "subcode", + null + ], + [ + "name", + "Kannada" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kn", + "first_native_name": "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1", + "id": "kn" + } + }, + { + "fields": [ + [ + "native_name", + "\ud55c\uad6d\uc5b4 (\u97d3\u570b\u8a9e), \uc870\uc120\ub9d0 (\u671d\u9bae\u8a9e)" + ], + [ + "primary_code", + "ko" + ], + [ + "subcode", + null + ], + [ + "name", + "Korean" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ko", + "first_native_name": "\ud55c\uad6d\uc5b4 (\u97d3\u570b\u8a9e)", + "id": "ko" + } + }, + { + "fields": [ + [ + "native_name", + "KiKongo" + ], + [ + "primary_code", + "kon" + ], + [ + "subcode", + null + ], + [ + "name", + "Kongo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kon", + "first_native_name": "KiKongo", + "id": "kon" + } + }, + { + "fields": [ + [ + "native_name", + "Kanuri" + ], + [ + "primary_code", + "kr" + ], + [ + "subcode", + null + ], + [ + "name", + "Kanuri" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kr", + "first_native_name": "Kanuri", + "id": "kr" + } + }, + { + "fields": [ + [ + "native_name", + "\u0915\u0936\u094d\u092e\u0940\u0930\u0940, \u0643\u0634\u0645\u064a\u0631\u064a\u200e" + ], + [ + "primary_code", + "ks" + ], + [ + "subcode", + null + ], + [ + "name", + "Kashmiri" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ks", + "first_native_name": "\u0915\u0936\u094d\u092e\u0940\u0930\u0940", + "id": "ks" + } + }, + { + "fields": [ + [ + "native_name", + "Kurd\u00ee, \u0643\u0648\u0631\u062f\u06cc\u200e" + ], + [ + "primary_code", + "ku" + ], + [ + "subcode", + null + ], + [ + "name", + "Kurdish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ku", + "first_native_name": "Kurd\u00ee", + "id": "ku" + } + }, + { + "fields": [ + [ + "native_name", + "\u043a\u043e\u043c\u0438 \u043a\u044b\u0432" + ], + [ + "primary_code", + "kv" + ], + [ + "subcode", + null + ], + [ + "name", + "Komi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kv", + "first_native_name": "\u043a\u043e\u043c\u0438 \u043a\u044b\u0432", + "id": "kv" + } + }, + { + "fields": [ + [ + "native_name", + "Kernewek" + ], + [ + "primary_code", + "kw" + ], + [ + "subcode", + null + ], + [ + "name", + "Cornish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "kw", + "first_native_name": "Kernewek", + "id": "kw" + } + }, + { + "fields": [ + [ + "native_name", + "\u043a\u044b\u0440\u0433\u044b\u0437 \u0442\u0438\u043b\u0438" + ], + [ + "primary_code", + "ky" + ], + [ + "subcode", + null + ], + [ + "name", + "Kirghiz; Kyrgyz" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ky", + "first_native_name": "\u043a\u044b\u0440\u0433\u044b\u0437 \u0442\u0438\u043b\u0438", + "id": "ky" + } + }, + { + "fields": [ + [ + "native_name", + "latine, lingua latina" + ], + [ + "primary_code", + "la" + ], + [ + "subcode", + null + ], + [ + "name", + "Latin" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "la", + "first_native_name": "latine", + "id": "la" + } + }, + { + "fields": [ + [ + "native_name", + "L\u00ebtzebuergesch" + ], + [ + "primary_code", + "lb" + ], + [ + "subcode", + null + ], + [ + "name", + "Luxembourgish; Letzeburgesch" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lb", + "first_native_name": "L\u00ebtzebuergesch", + "id": "lb" + } + }, + { + "fields": [ + [ + "native_name", + "Luganda" + ], + [ + "primary_code", + "lg" + ], + [ + "subcode", + null + ], + [ + "name", + "Luganda" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lg", + "first_native_name": "Luganda", + "id": "lg" + } + }, + { + "fields": [ + [ + "native_name", + "Limburgs" + ], + [ + "primary_code", + "li" + ], + [ + "subcode", + null + ], + [ + "name", + "Limburgish; Limburgan; Limburger" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "li", + "first_native_name": "Limburgs", + "id": "li" + } + }, + { + "fields": [ + [ + "native_name", + "Ling\u00e1la" + ], + [ + "primary_code", + "lin" + ], + [ + "subcode", + null + ], + [ + "name", + "Lingala" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lin", + "first_native_name": "Ling\u00e1la", + "id": "lin" + } + }, + { + "fields": [ + [ + "native_name", + "Lakhota" + ], + [ + "primary_code", + "lkt" + ], + [ + "subcode", + null + ], + [ + "name", + "Lakhota; Lakotiyapi; Teton" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lkt", + "first_native_name": "Lakhota", + "id": "lkt" + } + }, + { + "fields": [ + [ + "native_name", + "Ling\u00e1la" + ], + [ + "primary_code", + "ln" + ], + [ + "subcode", + null + ], + [ + "name", + "Lingala" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ln", + "first_native_name": "Ling\u00e1la", + "id": "ln" + } + }, + { + "fields": [ + [ + "native_name", + "\u0e9e\u0eb2\u0eaa\u0eb2\u0ea5\u0eb2\u0ea7" + ], + [ + "primary_code", + "lo" + ], + [ + "subcode", + null + ], + [ + "name", + "Lao" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lo", + "first_native_name": "\u0e9e\u0eb2\u0eaa\u0eb2\u0ea5\u0eb2\u0ea7", + "id": "lo" + } + }, + { + "fields": [ + [ + "native_name", + "lietuvi\u0173 kalba" + ], + [ + "primary_code", + "lt" + ], + [ + "subcode", + null + ], + [ + "name", + "Lithuanian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lt", + "first_native_name": "lietuvi\u0173 kalba", + "id": "lt" + } + }, + { + "fields": [ + [ + "native_name", + "Luba-Katanga" + ], + [ + "primary_code", + "lu" + ], + [ + "subcode", + null + ], + [ + "name", + "Luba-Katanga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lu", + "first_native_name": "Luba-Katanga", + "id": "lu" + } + }, + { + "fields": [ + [ + "native_name", + "Luba-Kasai, Tshiluba" + ], + [ + "primary_code", + "lua" + ], + [ + "subcode", + null + ], + [ + "name", + "Luba-Kasai" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lua", + "first_native_name": "Luba-Kasai", + "id": "lua" + } + }, + { + "fields": [ + [ + "native_name", + "latvie\u0161u valoda" + ], + [ + "primary_code", + "lv" + ], + [ + "subcode", + null + ], + [ + "name", + "Latvian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lv", + "first_native_name": "latvie\u0161u valoda", + "id": "lv" + } + }, + { + "fields": [ + [ + "native_name", + "Oluwanga" + ], + [ + "primary_code", + "lwg" + ], + [ + "subcode", + null + ], + [ + "name", + "Oluwanga; Oluhanga; Hanga; Kawanga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lwg", + "first_native_name": "Oluwanga", + "id": "lwg" + } + }, + { + "fields": [ + [ + "native_name", + "Malawian Sign Language" + ], + [ + "primary_code", + "lws" + ], + [ + "subcode", + null + ], + [ + "name", + "Malawian Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "lws", + "first_native_name": "Malawian Sign Language", + "id": "lws" + } + }, + { + "fields": [ + [ + "native_name", + "\u0925\u093f\u0932\u0940, \u09ae\u09c8\u09a5\u09bf\u09b2\u09c0" + ], + [ + "primary_code", + "mai" + ], + [ + "subcode", + null + ], + [ + "name", + "Maithili" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mai", + "first_native_name": "\u0925\u093f\u0932\u0940", + "id": "mai" + } + }, + { + "fields": [ + [ + "native_name", + "Malagasy fiteny" + ], + [ + "primary_code", + "mg" + ], + [ + "subcode", + null + ], + [ + "name", + "Malagasy" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mg", + "first_native_name": "Malagasy fiteny", + "id": "mg" + } + }, + { + "fields": [ + [ + "native_name", + "Kajin M\u0327aje\u013c" + ], + [ + "primary_code", + "mh" + ], + [ + "subcode", + null + ], + [ + "name", + "Marshallese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mh", + "first_native_name": "Kajin M\u0327aje\u013c", + "id": "mh" + } + }, + { + "fields": [ + [ + "native_name", + "te reo M\u0101ori" + ], + [ + "primary_code", + "mi" + ], + [ + "subcode", + null + ], + [ + "name", + "M\u0101ori" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mi", + "first_native_name": "te reo M\u0101ori", + "id": "mi" + } + }, + { + "fields": [ + [ + "native_name", + "\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438 \u0458\u0430\u0437\u0438\u043a" + ], + [ + "primary_code", + "mk" + ], + [ + "subcode", + null + ], + [ + "name", + "Macedonian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mk", + "first_native_name": "\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438 \u0458\u0430\u0437\u0438\u043a", + "id": "mk" + } + }, + { + "fields": [ + [ + "native_name", + "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02" + ], + [ + "primary_code", + "ml" + ], + [ + "subcode", + null + ], + [ + "name", + "Malayalam" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ml", + "first_native_name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02", + "id": "ml" + } + }, + { + "fields": [ + [ + "native_name", + "fiteny malagasy" + ], + [ + "primary_code", + "mlg" + ], + [ + "subcode", + null + ], + [ + "name", + "Malagasy" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mlg", + "first_native_name": "fiteny malagasy", + "id": "mlg" + } + }, + { + "fields": [ + [ + "native_name", + "\u043c\u043e\u043d\u0433\u043e\u043b" + ], + [ + "primary_code", + "mn" + ], + [ + "subcode", + null + ], + [ + "name", + "Mongolian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mn", + "first_native_name": "\u043c\u043e\u043d\u0433\u043e\u043b", + "id": "mn" + } + }, + { + "fields": [ + [ + "native_name", + "\u092e\u0930\u093e\u0920\u0940" + ], + [ + "primary_code", + "mr" + ], + [ + "subcode", + null + ], + [ + "name", + "Marathi (Mar\u0101\u1e6dh\u012b)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mr", + "first_native_name": "\u092e\u0930\u093e\u0920\u0940", + "id": "mr" + } + }, + { + "fields": [ + [ + "native_name", + "bahasa Melayu, \u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064a\u0648\u200e" + ], + [ + "primary_code", + "ms" + ], + [ + "subcode", + null + ], + [ + "name", + "Malay" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ms", + "first_native_name": "bahasa Melayu", + "id": "ms" + } + }, + { + "fields": [ + [ + "native_name", + "Malti" + ], + [ + "primary_code", + "mt" + ], + [ + "subcode", + null + ], + [ + "name", + "Maltese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mt", + "first_native_name": "Malti", + "id": "mt" + } + }, + { + "fields": [ + [ + "native_name", + "Multiple languages" + ], + [ + "primary_code", + "mul" + ], + [ + "subcode", + null + ], + [ + "name", + "Multiple languages" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mul", + "first_native_name": "Multiple languages", + "id": "mul" + } + }, + { + "fields": [ + [ + "native_name", + "\u092e\u093e\u0930\u0935\u093e\u0921\u093c\u0940, \u0645\u0627\u0631\u0648\u0627\u0691\u06cc" + ], + [ + "primary_code", + "mwr" + ], + [ + "subcode", + null + ], + [ + "name", + "Marwari; Marwadi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "mwr", + "first_native_name": "\u092e\u093e\u0930\u0935\u093e\u0921\u093c\u0940", + "id": "mwr" + } + }, + { + "fields": [ + [ + "native_name", + "\u1017\u1019\u102c\u1005\u102c" + ], + [ + "primary_code", + "my" + ], + [ + "subcode", + null + ], + [ + "name", + "Burmese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "my", + "first_native_name": "\u1017\u1019\u102c\u1005\u102c", + "id": "my" + } + }, + { + "fields": [ + [ + "native_name", + "Mamara Senoufo" + ], + [ + "primary_code", + "myk" + ], + [ + "subcode", + null + ], + [ + "name", + "Mamara Senoufo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "myk", + "first_native_name": "Mamara Senoufo", + "id": "myk" + } + }, + { + "fields": [ + [ + "native_name", + "Lumasaaba, Masaaba" + ], + [ + "primary_code", + "myx" + ], + [ + "subcode", + null + ], + [ + "name", + "Masaaba; Bagisu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "myx", + "first_native_name": "Lumasaaba", + "id": "myx" + } + }, + { + "fields": [ + [ + "native_name", + "Ekakair\u0169 Naoero" + ], + [ + "primary_code", + "na" + ], + [ + "subcode", + null + ], + [ + "name", + "Nauru" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "na", + "first_native_name": "Ekakair\u0169 Naoero", + "id": "na" + } + }, + { + "fields": [ + [ + "native_name", + "Norsk bokm\u00e5l" + ], + [ + "primary_code", + "nb" + ], + [ + "subcode", + null + ], + [ + "name", + "Norwegian Bokm\u00e5l" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nb", + "first_native_name": "Norsk bokm\u00e5l", + "id": "nb" + } + }, + { + "fields": [ + [ + "native_name", + "isiNdebele" + ], + [ + "primary_code", + "nd" + ], + [ + "subcode", + null + ], + [ + "name", + "North Ndebele" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nd", + "first_native_name": "isiNdebele", + "id": "nd" + } + }, + { + "fields": [ + [ + "native_name", + "\u0928\u0947\u092a\u093e\u0932\u0940" + ], + [ + "primary_code", + "ne" + ], + [ + "subcode", + null + ], + [ + "name", + "Nepali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ne", + "first_native_name": "\u0928\u0947\u092a\u093e\u0932\u0940", + "id": "ne" + } + }, + { + "fields": [ + [ + "native_name", + "\u0928\u0947\u092a\u093e\u0932\u0940" + ], + [ + "primary_code", + "ne" + ], + [ + "subcode", + "NP" + ], + [ + "name", + "Nepali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ne-NP", + "first_native_name": "\u0928\u0947\u092a\u093e\u0932\u0940", + "id": "ne-NP" + } + }, + { + "fields": [ + [ + "native_name", + "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e, \u0928\u0947\u0935\u093e\u0903 \u092d\u093e\u092f\u094d" + ], + [ + "primary_code", + "new" + ], + [ + "subcode", + null + ], + [ + "name", + "Newari" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "new", + "first_native_name": "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e", + "id": "new" + } + }, + { + "fields": [ + [ + "native_name", + "Owambo" + ], + [ + "primary_code", + "ng" + ], + [ + "subcode", + null + ], + [ + "name", + "Ndonga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ng", + "first_native_name": "Owambo", + "id": "ng" + } + }, + { + "fields": [ + [ + "native_name", + "Nederlands, Vlaams" + ], + [ + "primary_code", + "nl" + ], + [ + "subcode", + null + ], + [ + "name", + "Dutch" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nl", + "first_native_name": "Nederlands", + "id": "nl" + } + }, + { + "fields": [ + [ + "native_name", + "Norsk nynorsk" + ], + [ + "primary_code", + "nn" + ], + [ + "subcode", + null + ], + [ + "name", + "Norwegian Nynorsk" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nn", + "first_native_name": "Norsk nynorsk", + "id": "nn" + } + }, + { + "fields": [ + [ + "native_name", + "Norsk" + ], + [ + "primary_code", + "no" + ], + [ + "subcode", + null + ], + [ + "name", + "Norwegian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "no", + "first_native_name": "Norsk", + "id": "no" + } + }, + { + "fields": [ + [ + "native_name", + "isiNdebele" + ], + [ + "primary_code", + "nr" + ], + [ + "subcode", + null + ], + [ + "name", + "South Ndebele" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nr", + "first_native_name": "isiNdebele", + "id": "nr" + } + }, + { + "fields": [ + [ + "native_name", + "Sepedi, Sesotho sa Leboa, Pedi" + ], + [ + "primary_code", + "nso" + ], + [ + "subcode", + null + ], + [ + "name", + "Northern Sotho" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nso", + "first_native_name": "Sepedi", + "id": "nso" + } + }, + { + "fields": [ + [ + "native_name", + "\u0928\u0947\u092a\u093e\u0932\u0940 \u0938\u093e\u0902\u0915\u0947\u0924\u093f\u0915 \u092d\u093e\u0937\u093e" + ], + [ + "primary_code", + "nsp" + ], + [ + "subcode", + null + ], + [ + "name", + "Nepalese Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nsp", + "first_native_name": "\u0928\u0947\u092a\u093e\u0932\u0940 \u0938\u093e\u0902\u0915\u0947\u0924\u093f\u0915 \u092d\u093e\u0937\u093e", + "id": "nsp" + } + }, + { + "fields": [ + [ + "native_name", + "Din\u00e9 bizaad, Din\u00e9k\u02bceh\u01f0\u00ed" + ], + [ + "primary_code", + "nv" + ], + [ + "subcode", + null + ], + [ + "name", + "Navajo; Navaho" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nv", + "first_native_name": "Din\u00e9 bizaad", + "id": "nv" + } + }, + { + "fields": [ + [ + "native_name", + "chiChe\u0175a, chinyanja" + ], + [ + "primary_code", + "ny" + ], + [ + "subcode", + null + ], + [ + "name", + "Chichewa; Chewa; Nyanja" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ny", + "first_native_name": "chiChe\u0175a", + "id": "ny" + } + }, + { + "fields": [ + [ + "native_name", + "chiChe\u0175a" + ], + [ + "primary_code", + "nya" + ], + [ + "subcode", + null + ], + [ + "name", + "Chichewa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nya", + "first_native_name": "chiChe\u0175a", + "id": "nya" + } + }, + { + "fields": [ + [ + "native_name", + "Runyankore" + ], + [ + "primary_code", + "nyn" + ], + [ + "subcode", + null + ], + [ + "name", + "Nyankore; Nkole; Nyankole" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "nyn", + "first_native_name": "Runyankore", + "id": "nyn" + } + }, + { + "fields": [ + [ + "native_name", + "Occitan" + ], + [ + "primary_code", + "oc" + ], + [ + "subcode", + null + ], + [ + "name", + "Occitan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "oc", + "first_native_name": "Occitan", + "id": "oc" + } + }, + { + "fields": [ + [ + "native_name", + "\u140a\u14c2\u1511\u14c8\u142f\u14a7\u140e\u14d0" + ], + [ + "primary_code", + "oj" + ], + [ + "subcode", + null + ], + [ + "name", + "Ojibwe; Ojibwa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "oj", + "first_native_name": "\u140a\u14c2\u1511\u14c8\u142f\u14a7\u140e\u14d0", + "id": "oj" + } + }, + { + "fields": [ + [ + "native_name", + "\u140a\u14c2\u1511\u14c8\u142f\u14a7\u140e\u14d0" + ], + [ + "primary_code", + "oji" + ], + [ + "subcode", + null + ], + [ + "name", + "Ojibwe" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "oji", + "first_native_name": "\u140a\u14c2\u1511\u14c8\u142f\u14a7\u140e\u14d0", + "id": "oji" + } + }, + { + "fields": [ + [ + "native_name", + "Afaan Oromoo" + ], + [ + "primary_code", + "om" + ], + [ + "subcode", + null + ], + [ + "name", + "Oromo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "om", + "first_native_name": "Afaan Oromoo", + "id": "om" + } + }, + { + "fields": [ + [ + "native_name", + "\u0b13\u0b21\u0b3c\u0b3f\u0b06" + ], + [ + "primary_code", + "or" + ], + [ + "subcode", + null + ], + [ + "name", + "Oriya" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "or", + "first_native_name": "\u0b13\u0b21\u0b3c\u0b3f\u0b06", + "id": "or" + } + }, + { + "fields": [ + [ + "native_name", + "\u0438\u0440\u043e\u043d \u00e6\u0432\u0437\u0430\u0433" + ], + [ + "primary_code", + "os" + ], + [ + "subcode", + null + ], + [ + "name", + "Ossetian; Ossetic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "os", + "first_native_name": "\u0438\u0440\u043e\u043d \u00e6\u0432\u0437\u0430\u0433", + "id": "os" + } + }, + { + "fields": [ + [ + "native_name", + "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40, \u067e\u0646\u062c\u0627\u0628\u06cc\u200e" + ], + [ + "primary_code", + "pa" + ], + [ + "subcode", + null + ], + [ + "name", + "Panjabi; Punjabi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pa", + "first_native_name": "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40", + "id": "pa" + } + }, + { + "fields": [ + [ + "native_name", + "Southern Pashto" + ], + [ + "primary_code", + "pbt" + ], + [ + "subcode", + null + ], + [ + "name", + "Southern Pashto" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pbt", + "first_native_name": "Southern Pashto", + "id": "pbt" + } + }, + { + "fields": [ + [ + "native_name", + "Northern Pashto" + ], + [ + "primary_code", + "pbu" + ], + [ + "subcode", + null + ], + [ + "name", + "Northern Pashto" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pbu", + "first_native_name": "Northern Pashto", + "id": "pbu" + } + }, + { + "fields": [ + [ + "native_name", + "Papua New Guinean Sign Language" + ], + [ + "primary_code", + "pgz" + ], + [ + "subcode", + null + ], + [ + "name", + "Papua New Guinean Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pgz", + "first_native_name": "Papua New Guinean Sign Language", + "id": "pgz" + } + }, + { + "fields": [ + [ + "native_name", + "\u092a\u093e\u0934\u093f" + ], + [ + "primary_code", + "pi" + ], + [ + "subcode", + null + ], + [ + "name", + "P\u0101li" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pi", + "first_native_name": "\u092a\u093e\u0934\u093f", + "id": "pi" + } + }, + { + "fields": [ + [ + "native_name", + "Polski" + ], + [ + "primary_code", + "pl" + ], + [ + "subcode", + null + ], + [ + "name", + "Polish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pl", + "first_native_name": "Polski", + "id": "pl" + } + }, + { + "fields": [ + [ + "native_name", + "Piemont\u00e8is" + ], + [ + "primary_code", + "pms" + ], + [ + "subcode", + null + ], + [ + "name", + "Piedmontese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pms", + "first_native_name": "Piemont\u00e8is", + "id": "pms" + } + }, + { + "fields": [ + [ + "native_name", + "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40" + ], + [ + "primary_code", + "pnb" + ], + [ + "subcode", + null + ], + [ + "name", + "Punjabi" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pnb", + "first_native_name": "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40", + "id": "pnb" + } + }, + { + "fields": [ + [ + "native_name", + "\u062f\u0631\u06cc" + ], + [ + "primary_code", + "prs" + ], + [ + "subcode", + null + ], + [ + "name", + "Dari" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "prs", + "first_native_name": "\u062f\u0631\u06cc", + "id": "prs" + } + }, + { + "fields": [ + [ + "native_name", + "\u067e\u069a\u062a\u0648" + ], + [ + "primary_code", + "ps" + ], + [ + "subcode", + null + ], + [ + "name", + "Pashto; Pushto" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ps", + "first_native_name": "\u067e\u069a\u062a\u0648", + "id": "ps" + } + }, + { + "fields": [ + [ + "native_name", + "Portugu\u00eas" + ], + [ + "primary_code", + "pt" + ], + [ + "subcode", + null + ], + [ + "name", + "Portuguese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pt", + "first_native_name": "Portugu\u00eas", + "id": "pt" + } + }, + { + "fields": [ + [ + "native_name", + "Portugu\u00eas (Brasil)" + ], + [ + "primary_code", + "pt" + ], + [ + "subcode", + "BR" + ], + [ + "name", + "Portuguese, Brazil" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pt-BR", + "first_native_name": "Portugu\u00eas (Brasil)", + "id": "pt-BR" + } + }, + { + "fields": [ + [ + "native_name", + "Portugu\u00eas (Portugal)" + ], + [ + "primary_code", + "pt" + ], + [ + "subcode", + "PT" + ], + [ + "name", + "Portuguese, Portugal" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "pt-PT", + "first_native_name": "Portugu\u00eas (Portugal)", + "id": "pt-PT" + } + }, + { + "fields": [ + [ + "native_name", + "Runa Simi, Kichwa" + ], + [ + "primary_code", + "qu" + ], + [ + "subcode", + null + ], + [ + "name", + "Quechua" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "qu", + "first_native_name": "Runa Simi", + "id": "qu" + } + }, + { + "fields": [ + [ + "native_name", + "Runa Simi" + ], + [ + "primary_code", + "que" + ], + [ + "subcode", + null + ], + [ + "name", + "Quechua" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "que", + "first_native_name": "Runa Simi", + "id": "que" + } + }, + { + "fields": [ + [ + "native_name", + "rumantsch grischun" + ], + [ + "primary_code", + "rm" + ], + [ + "subcode", + null + ], + [ + "name", + "Romansh" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "rm", + "first_native_name": "rumantsch grischun", + "id": "rm" + } + }, + { + "fields": [ + [ + "native_name", + "kiRundi" + ], + [ + "primary_code", + "rn" + ], + [ + "subcode", + null + ], + [ + "name", + "Kirundi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "rn", + "first_native_name": "kiRundi", + "id": "rn" + } + }, + { + "fields": [ + [ + "native_name", + "rom\u00e2n\u0103" + ], + [ + "primary_code", + "ro" + ], + [ + "subcode", + null + ], + [ + "name", + "Romanian; Moldavian; Moldovan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ro", + "first_native_name": "rom\u00e2n\u0103", + "id": "ro" + } + }, + { + "fields": [ + [ + "native_name", + "Amarenga y'Ikinyarwanda" + ], + [ + "primary_code", + "rsn" + ], + [ + "subcode", + null + ], + [ + "name", + "Rwandan Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "rsn", + "first_native_name": "Amarenga y'Ikinyarwanda", + "id": "rsn" + } + }, + { + "fields": [ + [ + "native_name", + "\u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a" + ], + [ + "primary_code", + "ru" + ], + [ + "subcode", + null + ], + [ + "name", + "Russian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ru", + "first_native_name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a", + "id": "ru" + } + }, + { + "fields": [ + [ + "native_name", + "\u0440\u0443\u0441\u0438\u043d\u044c\u0441\u043a\u044b\u0439 \u044f\u0437\u044b\u043a" + ], + [ + "primary_code", + "rue" + ], + [ + "subcode", + null + ], + [ + "name", + "Rusyn" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "rue", + "first_native_name": "\u0440\u0443\u0441\u0438\u043d\u044c\u0441\u043a\u044b\u0439 \u044f\u0437\u044b\u043a", + "id": "rue" + } + }, + { + "fields": [ + [ + "native_name", + "Ikinyarwanda" + ], + [ + "primary_code", + "rw" + ], + [ + "subcode", + null + ], + [ + "name", + "Kinyarwanda" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "rw", + "first_native_name": "Ikinyarwanda", + "id": "rw" + } + }, + { + "fields": [ + [ + "native_name", + "\u0938\u0902\u0938\u094d\u0915\u0943\u0924\u092e\u094d" + ], + [ + "primary_code", + "sa" + ], + [ + "subcode", + null + ], + [ + "name", + "Sanskrit (Sa\u1e41sk\u1e5bta)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sa", + "first_native_name": "\u0938\u0902\u0938\u094d\u0915\u0943\u0924\u092e\u094d", + "id": "sa" + } + }, + { + "fields": [ + [ + "native_name", + "sardu" + ], + [ + "primary_code", + "sc" + ], + [ + "subcode", + null + ], + [ + "name", + "Sardinian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sc", + "first_native_name": "sardu", + "id": "sc" + } + }, + { + "fields": [ + [ + "native_name", + "Scots" + ], + [ + "primary_code", + "sco" + ], + [ + "subcode", + null + ], + [ + "name", + "Scots" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sco", + "first_native_name": "Scots", + "id": "sco" + } + }, + { + "fields": [ + [ + "native_name", + "\u0938\u093f\u0928\u094d\u0927\u0940, \u0633\u0646\u068c\u064a\u060c \u0633\u0646\u062f\u06be\u06cc\u200e" + ], + [ + "primary_code", + "sd" + ], + [ + "subcode", + null + ], + [ + "name", + "Sindhi" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sd", + "first_native_name": "\u0938\u093f\u0928\u094d\u0927\u0940", + "id": "sd" + } + }, + { + "fields": [ + [ + "native_name", + "Davvis\u00e1megiella" + ], + [ + "primary_code", + "se" + ], + [ + "subcode", + null + ], + [ + "name", + "Northern Sami" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "se", + "first_native_name": "Davvis\u00e1megiella", + "id": "se" + } + }, + { + "fields": [ + [ + "native_name", + "y\u00e2ng\u00e2 t\u00ee s\u00e4ng\u00f6" + ], + [ + "primary_code", + "sg" + ], + [ + "subcode", + null + ], + [ + "name", + "Sango" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sg", + "first_native_name": "y\u00e2ng\u00e2 t\u00ee s\u00e4ng\u00f6", + "id": "sg" + } + }, + { + "fields": [ + [ + "native_name", + "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd" + ], + [ + "primary_code", + "si" + ], + [ + "subcode", + null + ], + [ + "name", + "Sinhala; Sinhalese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "si", + "first_native_name": "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd", + "id": "si" + } + }, + { + "fields": [ + [ + "native_name", + "Sidaamu Afoo" + ], + [ + "primary_code", + "sid" + ], + [ + "subcode", + null + ], + [ + "name", + "Sidamo; Sidaamu afii; Sidaama; Sidama" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sid", + "first_native_name": "Sidaamu Afoo", + "id": "sid" + } + }, + { + "fields": [ + [ + "native_name", + "sloven\u010dina" + ], + [ + "primary_code", + "sk" + ], + [ + "subcode", + null + ], + [ + "name", + "Slovak" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sk", + "first_native_name": "sloven\u010dina", + "id": "sk" + } + }, + { + "fields": [ + [ + "native_name", + "sloven\u0161\u010dina" + ], + [ + "primary_code", + "sl" + ], + [ + "subcode", + null + ], + [ + "name", + "Slovene" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sl", + "first_native_name": "sloven\u0161\u010dina", + "id": "sl" + } + }, + { + "fields": [ + [ + "native_name", + "gagana faa Samoa" + ], + [ + "primary_code", + "sm" + ], + [ + "subcode", + null + ], + [ + "name", + "Samoan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sm", + "first_native_name": "gagana faa Samoa", + "id": "sm" + } + }, + { + "fields": [ + [ + "native_name", + "chiShona" + ], + [ + "primary_code", + "sn" + ], + [ + "subcode", + null + ], + [ + "name", + "Shona" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sn", + "first_native_name": "chiShona", + "id": "sn" + } + }, + { + "fields": [ + [ + "native_name", + "chiShona" + ], + [ + "primary_code", + "sna" + ], + [ + "subcode", + null + ], + [ + "name", + "Shona" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sna", + "first_native_name": "chiShona", + "id": "sna" + } + }, + { + "fields": [ + [ + "native_name", + "Soninke" + ], + [ + "primary_code", + "snk" + ], + [ + "subcode", + null + ], + [ + "name", + "Soninke" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "snk", + "first_native_name": "Soninke", + "id": "snk" + } + }, + { + "fields": [ + [ + "native_name", + "Soomaaliga, af Soomaali" + ], + [ + "primary_code", + "so" + ], + [ + "subcode", + null + ], + [ + "name", + "Somali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "so", + "first_native_name": "Soomaaliga", + "id": "so" + } + }, + { + "fields": [ + [ + "native_name", + "Soomaaliga" + ], + [ + "primary_code", + "som" + ], + [ + "subcode", + null + ], + [ + "name", + "Somali" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "som", + "first_native_name": "Soomaaliga", + "id": "som" + } + }, + { + "fields": [ + [ + "native_name", + "Sesotho" + ], + [ + "primary_code", + "sot" + ], + [ + "subcode", + null + ], + [ + "name", + "Southern Sotho" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sot", + "first_native_name": "Sesotho", + "id": "sot" + } + }, + { + "fields": [ + [ + "native_name", + "Shqip" + ], + [ + "primary_code", + "sq" + ], + [ + "subcode", + null + ], + [ + "name", + "Albanian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sq", + "first_native_name": "Shqip", + "id": "sq" + } + }, + { + "fields": [ + [ + "native_name", + "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a" + ], + [ + "primary_code", + "sr" + ], + [ + "subcode", + null + ], + [ + "name", + "Serbian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sr", + "first_native_name": "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a", + "id": "sr" + } + }, + { + "fields": [ + [ + "native_name", + "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a" + ], + [ + "primary_code", + "sr" + ], + [ + "subcode", + "CS" + ], + [ + "name", + "Serbian, Cyrillic" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sr-CS", + "first_native_name": "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a", + "id": "sr-CS" + } + }, + { + "fields": [ + [ + "native_name", + "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a" + ], + [ + "primary_code", + "sr" + ], + [ + "subcode", + "LATN" + ], + [ + "name", + "Serbian, Latin" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sr-LATN", + "first_native_name": "\u0441\u0440\u043f\u0441\u043a\u0438 \u0458\u0435\u0437\u0438\u043a", + "id": "sr-LATN" + } + }, + { + "fields": [ + [ + "native_name", + "Seereer" + ], + [ + "primary_code", + "srr" + ], + [ + "subcode", + null + ], + [ + "name", + "Serer" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "srr", + "first_native_name": "Seereer", + "id": "srr" + } + }, + { + "fields": [ + [ + "native_name", + "SiSwati" + ], + [ + "primary_code", + "ss" + ], + [ + "subcode", + null + ], + [ + "name", + "Swati" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ss", + "first_native_name": "SiSwati", + "id": "ss" + } + }, + { + "fields": [ + [ + "native_name", + "Sesotho" + ], + [ + "primary_code", + "st" + ], + [ + "subcode", + null + ], + [ + "name", + "Southern Sotho" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "st", + "first_native_name": "Sesotho", + "id": "st" + } + }, + { + "fields": [ + [ + "native_name", + "Basa Sunda" + ], + [ + "primary_code", + "su" + ], + [ + "subcode", + null + ], + [ + "name", + "Sundanese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "su", + "first_native_name": "Basa Sunda", + "id": "su" + } + }, + { + "fields": [ + [ + "native_name", + "svenska" + ], + [ + "primary_code", + "sv" + ], + [ + "subcode", + null + ], + [ + "name", + "Swedish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sv", + "first_native_name": "svenska", + "id": "sv" + } + }, + { + "fields": [ + [ + "native_name", + "Svenska" + ], + [ + "primary_code", + "sv" + ], + [ + "subcode", + "FI" + ], + [ + "name", + "Swedish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sv-FI", + "first_native_name": "Svenska", + "id": "sv-FI" + } + }, + { + "fields": [ + [ + "native_name", + "Svenska" + ], + [ + "primary_code", + "sv" + ], + [ + "subcode", + "SE" + ], + [ + "name", + "Swedish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sv-SE", + "first_native_name": "Svenska", + "id": "sv-SE" + } + }, + { + "fields": [ + [ + "native_name", + "Kiswahili" + ], + [ + "primary_code", + "sw" + ], + [ + "subcode", + null + ], + [ + "name", + "Swahili" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "sw", + "first_native_name": "Kiswahili", + "id": "sw" + } + }, + { + "fields": [ + [ + "native_name", + "Kiswahili" + ], + [ + "primary_code", + "swa" + ], + [ + "subcode", + null + ], + [ + "name", + "Swahili" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "swa", + "first_native_name": "Kiswahili", + "id": "swa" + } + }, + { + "fields": [ + [ + "native_name", + "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd" + ], + [ + "primary_code", + "ta" + ], + [ + "subcode", + null + ], + [ + "name", + "Tamil" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ta", + "first_native_name": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd", + "id": "ta" + } + }, + { + "fields": [ + [ + "native_name", + "Eastern Tamang" + ], + [ + "primary_code", + "taj" + ], + [ + "subcode", + null + ], + [ + "name", + "Eastern Tamang" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "taj", + "first_native_name": "Eastern Tamang", + "id": "taj" + } + }, + { + "fields": [ + [ + "native_name", + "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41" + ], + [ + "primary_code", + "te" + ], + [ + "subcode", + null + ], + [ + "name", + "Telugu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "te", + "first_native_name": "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41", + "id": "te" + } + }, + { + "fields": [ + [ + "native_name", + "\u0442\u043e\u04b7\u0438\u043a\u04e3, to\u011fik\u012b, \u062a\u0627\u062c\u06cc\u06a9\u06cc\u200e" + ], + [ + "primary_code", + "tg" + ], + [ + "subcode", + null + ], + [ + "name", + "Tajik" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tg", + "first_native_name": "\u0442\u043e\u04b7\u0438\u043a\u04e3", + "id": "tg" + } + }, + { + "fields": [ + [ + "native_name", + "\u0e44\u0e17\u0e22" + ], + [ + "primary_code", + "th" + ], + [ + "subcode", + null + ], + [ + "name", + "Thai" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "th", + "first_native_name": "\u0e44\u0e17\u0e22", + "id": "th" + } + }, + { + "fields": [ + [ + "native_name", + "Dangaura Tharu" + ], + [ + "primary_code", + "thl" + ], + [ + "subcode", + null + ], + [ + "name", + "Dangaura Tharu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "thl", + "first_native_name": "Dangaura Tharu", + "id": "thl" + } + }, + { + "fields": [ + [ + "native_name", + "\u1275\u130d\u122d\u129b" + ], + [ + "primary_code", + "ti" + ], + [ + "subcode", + null + ], + [ + "name", + "Tigrinya" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ti", + "first_native_name": "\u1275\u130d\u122d\u129b", + "id": "ti" + } + }, + { + "fields": [ + [ + "native_name", + "\u1275\u130d\u122d\u129b" + ], + [ + "primary_code", + "tir" + ], + [ + "subcode", + null + ], + [ + "name", + "Tigrinya" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tir", + "first_native_name": "\u1275\u130d\u122d\u129b", + "id": "tir" + } + }, + { + "fields": [ + [ + "native_name", + "T\u00fcrkmen, \u0422\u04af\u0440\u043a\u043c\u0435\u043d" + ], + [ + "primary_code", + "tk" + ], + [ + "subcode", + null + ], + [ + "name", + "Turkmen" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tk", + "first_native_name": "T\u00fcrkmen", + "id": "tk" + } + }, + { + "fields": [ + [ + "native_name", + "Wikang Tagalog" + ], + [ + "primary_code", + "tl" + ], + [ + "subcode", + null + ], + [ + "name", + "Tagalog" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tl", + "first_native_name": "Wikang Tagalog", + "id": "tl" + } + }, + { + "fields": [ + [ + "native_name", + "Setswana" + ], + [ + "primary_code", + "tn" + ], + [ + "subcode", + null + ], + [ + "name", + "Tswana" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tn", + "first_native_name": "Setswana", + "id": "tn" + } + }, + { + "fields": [ + [ + "native_name", + "faka Tonga" + ], + [ + "primary_code", + "to" + ], + [ + "subcode", + null + ], + [ + "name", + "Tonga (Tonga Islands)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "to", + "first_native_name": "faka Tonga", + "id": "to" + } + }, + { + "fields": [ + [ + "native_name", + "Tok Pisin" + ], + [ + "primary_code", + "tpi" + ], + [ + "subcode", + null + ], + [ + "name", + "Tok Pisin" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tpi", + "first_native_name": "Tok Pisin", + "id": "tpi" + } + }, + { + "fields": [ + [ + "native_name", + "T\u00fcrk\u00e7e" + ], + [ + "primary_code", + "tr" + ], + [ + "subcode", + null + ], + [ + "name", + "Turkish" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tr", + "first_native_name": "T\u00fcrk\u00e7e", + "id": "tr" + } + }, + { + "fields": [ + [ + "native_name", + "Xitsonga" + ], + [ + "primary_code", + "ts" + ], + [ + "subcode", + null + ], + [ + "name", + "Tsonga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ts", + "first_native_name": "Xitsonga", + "id": "ts" + } + }, + { + "fields": [ + [ + "native_name", + "Setswana" + ], + [ + "primary_code", + "tsn" + ], + [ + "subcode", + null + ], + [ + "name", + "Tswana" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tsn", + "first_native_name": "Setswana", + "id": "tsn" + } + }, + { + "fields": [ + [ + "native_name", + "\u0442\u0430\u0442\u0430\u0440\u0447\u0430, tatar\u00e7a, \u062a\u0627\u062a\u0627\u0631\u0686\u0627\u200e" + ], + [ + "primary_code", + "tt" + ], + [ + "subcode", + null + ], + [ + "name", + "Tatar" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tt", + "first_native_name": "\u0442\u0430\u0442\u0430\u0440\u0447\u0430", + "id": "tt" + } + }, + { + "fields": [ + [ + "native_name", + "chiTumbuka" + ], + [ + "primary_code", + "tum" + ], + [ + "subcode", + null + ], + [ + "name", + "Tumbuka" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tum", + "first_native_name": "chiTumbuka", + "id": "tum" + } + }, + { + "fields": [ + [ + "native_name", + "Ng\u2019aturkana, Ng'aturkana" + ], + [ + "primary_code", + "tuv" + ], + [ + "subcode", + null + ], + [ + "name", + "Turkana; Turkwana; Buma; Bume" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tuv", + "first_native_name": "Ng\u2019aturkana", + "id": "tuv" + } + }, + { + "fields": [ + [ + "native_name", + "Twi" + ], + [ + "primary_code", + "tw" + ], + [ + "subcode", + null + ], + [ + "name", + "Twi" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "tw", + "first_native_name": "Twi", + "id": "tw" + } + }, + { + "fields": [ + [ + "native_name", + "Reo Tahiti" + ], + [ + "primary_code", + "ty" + ], + [ + "subcode", + null + ], + [ + "name", + "Tahitian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ty", + "first_native_name": "Reo Tahiti", + "id": "ty" + } + }, + { + "fields": [ + [ + "native_name", + "Uy\u01a3urq\u0259, \u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5\u200e" + ], + [ + "primary_code", + "ug" + ], + [ + "subcode", + null + ], + [ + "name", + "Uighur; Uyghur" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ug", + "first_native_name": "Uy\u01a3urq\u0259", + "id": "ug" + } + }, + { + "fields": [ + [ + "native_name", + "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430" + ], + [ + "primary_code", + "uk" + ], + [ + "subcode", + null + ], + [ + "name", + "Ukrainian" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "uk", + "first_native_name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430", + "id": "uk" + } + }, + { + "fields": [ + [ + "native_name", + "Undetermined" + ], + [ + "primary_code", + "und" + ], + [ + "subcode", + null + ], + [ + "name", + "Undetermined" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "und", + "first_native_name": "Undetermined", + "id": "und" + } + }, + { + "fields": [ + [ + "native_name", + "\u0627\u0631\u062f\u0648" + ], + [ + "primary_code", + "ur" + ], + [ + "subcode", + null + ], + [ + "name", + "Urdu" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ur", + "first_native_name": "\u0627\u0631\u062f\u0648", + "id": "ur" + } + }, + { + "fields": [ + [ + "native_name", + "Urdu" + ], + [ + "primary_code", + "ur" + ], + [ + "subcode", + "PK" + ], + [ + "name", + "Urdu" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ur-PK", + "first_native_name": "Urdu", + "id": "ur-PK" + } + }, + { + "fields": [ + [ + "native_name", + "zbek, \u040e\u0437\u0431\u0435\u043a, \u0623\u06c7\u0632\u0628\u06d0\u0643\u200e" + ], + [ + "primary_code", + "uz" + ], + [ + "subcode", + null + ], + [ + "name", + "Uzbek" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "uz", + "first_native_name": "zbek", + "id": "uz" + } + }, + { + "fields": [ + [ + "native_name", + "Tshiven\u1e13a, Tshivenda" + ], + [ + "primary_code", + "ve" + ], + [ + "subcode", + null + ], + [ + "name", + "Venda" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "ve", + "first_native_name": "Tshiven\u1e13a", + "id": "ve" + } + }, + { + "fields": [ + [ + "native_name", + "Ti\u1ebfng Vi\u1ec7t" + ], + [ + "primary_code", + "vi" + ], + [ + "subcode", + null + ], + [ + "name", + "Vietnamese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "vi", + "first_native_name": "Ti\u1ebfng Vi\u1ec7t", + "id": "vi" + } + }, + { + "fields": [ + [ + "native_name", + "Volap\u00fck" + ], + [ + "primary_code", + "vo" + ], + [ + "subcode", + null + ], + [ + "name", + "Volap\u00fck" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "vo", + "first_native_name": "Volap\u00fck", + "id": "vo" + } + }, + { + "fields": [ + [ + "native_name", + "Walon" + ], + [ + "primary_code", + "wa" + ], + [ + "subcode", + null + ], + [ + "name", + "Walloon" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "wa", + "first_native_name": "Walon", + "id": "wa" + } + }, + { + "fields": [ + [ + "native_name", + "Wolaytta" + ], + [ + "primary_code", + "wal" + ], + [ + "subcode", + null + ], + [ + "name", + "Wolaytta; Borodda; Uba; Ometo" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "wal", + "first_native_name": "Wolaytta", + "id": "wal" + } + }, + { + "fields": [ + [ + "native_name", + "Wollof" + ], + [ + "primary_code", + "wo" + ], + [ + "subcode", + null + ], + [ + "name", + "Wolof" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "wo", + "first_native_name": "Wollof", + "id": "wo" + } + }, + { + "fields": [ + [ + "native_name", + "Wollof" + ], + [ + "primary_code", + "wol" + ], + [ + "subcode", + null + ], + [ + "name", + "Wolof" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "wol", + "first_native_name": "Wollof", + "id": "wol" + } + }, + { + "fields": [ + [ + "native_name", + "isiXhosa" + ], + [ + "primary_code", + "xh" + ], + [ + "subcode", + null + ], + [ + "name", + "Xhosa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "xh", + "first_native_name": "isiXhosa", + "id": "xh" + } + }, + { + "fields": [ + [ + "native_name", + "isiXhosa" + ], + [ + "primary_code", + "xho" + ], + [ + "subcode", + null + ], + [ + "name", + "Xhosa" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "xho", + "first_native_name": "isiXhosa", + "id": "xho" + } + }, + { + "fields": [ + [ + "native_name", + "Swahili Lugha ya ishara" + ], + [ + "primary_code", + "xki" + ], + [ + "subcode", + null + ], + [ + "name", + "Kenyan Sign Language" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "xki", + "first_native_name": "Swahili Lugha ya ishara", + "id": "xki" + } + }, + { + "fields": [ + [ + "native_name", + "Lusoga, Olusoga" + ], + [ + "primary_code", + "xog" + ], + [ + "subcode", + null + ], + [ + "name", + "Soga" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "xog", + "first_native_name": "Lusoga", + "id": "xog" + } + }, + { + "fields": [ + [ + "native_name", + "Yao" + ], + [ + "primary_code", + "yao" + ], + [ + "subcode", + null + ], + [ + "name", + "Yao" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "yao", + "first_native_name": "Yao", + "id": "yao" + } + }, + { + "fields": [ + [ + "native_name", + "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9" + ], + [ + "primary_code", + "yi" + ], + [ + "subcode", + null + ], + [ + "name", + "Yiddish" + ], + [ + "text_direction", + "rtl" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "yi", + "first_native_name": "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9", + "id": "yi" + } + }, + { + "fields": [ + [ + "native_name", + "Yor\u00f9b\u00e1" + ], + [ + "primary_code", + "yo" + ], + [ + "subcode", + null + ], + [ + "name", + "Yoruba" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "yo", + "first_native_name": "Yor\u00f9b\u00e1", + "id": "yo" + } + }, + { + "fields": [ + [ + "native_name", + "Yor\u00f9b\u00e1" + ], + [ + "primary_code", + "yor" + ], + [ + "subcode", + null + ], + [ + "name", + "Yoruba" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "yor", + "first_native_name": "Yor\u00f9b\u00e1", + "id": "yor" + } + }, + { + "fields": [ + [ + "native_name", + "Sa\u026f cue\u014b\u0185, Saw cuengh" + ], + [ + "primary_code", + "za" + ], + [ + "subcode", + null + ], + [ + "name", + "Zhuang; Chuang" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "za", + "first_native_name": "Sa\u026f cue\u014b\u0185", + "id": "za" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + null + ], + [ + "name", + "Chinese" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh", + "first_native_name": "\u4e2d\u6587", + "id": "zh" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u4e2d\u56fd\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "CN" + ], + [ + "name", + "Chinese (China)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-CN", + "first_native_name": "\u4e2d\u6587\uff08\u4e2d\u56fd\uff09", + "id": "zh-CN" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7b80\u4f53\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hans" + ], + [ + "name", + "Chinese (Simplified)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hans", + "first_native_name": "\u4e2d\u6587\uff08\u7b80\u4f53\uff09", + "id": "zh-Hans" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7b80\u4f53\uff0c\u4e2d\u56fd\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hans-CN" + ], + [ + "name", + "Chinese (Simplified, China)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hans-CN", + "first_native_name": "\u4e2d\u6587\uff08\u7b80\u4f53\uff0c\u4e2d\u56fd\uff09", + "id": "zh-Hans-CN" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7b80\u4f53\uff0c\u53f0\u6e7e\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hans-TW" + ], + [ + "name", + "Chinese (Simplified, Taiwan)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hans-TW", + "first_native_name": "\u4e2d\u6587\uff08\u7b80\u4f53\uff0c\u53f0\u6e7e\uff09", + "id": "zh-Hans-TW" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7e41\u9ad4\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hant" + ], + [ + "name", + "Chinese (Traditional)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hant", + "first_native_name": "\u4e2d\u6587\uff08\u7e41\u9ad4\uff09", + "id": "zh-Hant" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7e41\u9ad4, \u4e2d\u570b\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hant-CN" + ], + [ + "name", + "Chinese (Traditional, China)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hant-CN", + "first_native_name": "\u4e2d\u6587\uff08\u7e41\u9ad4", + "id": "zh-Hant-CN" + } + }, + { + "fields": [ + [ + "native_name", + "\u4e2d\u6587\uff08\u7e41\u9ad4, \u53f0\u7063\uff09" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "Hant-TW" + ], + [ + "name", + "Chinese (Traditional, Taiwan)" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-Hant-TW", + "first_native_name": "\u4e2d\u6587\uff08\u7e41\u9ad4", + "id": "zh-Hant-TW" + } + }, + { + "fields": [ + [ + "native_name", + "\u6f22\u8a9e (\u81fa\u7063)" + ], + [ + "primary_code", + "zh" + ], + [ + "subcode", + "TW" + ], + [ + "name", + "Chinese, Taiwan" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zh-TW", + "first_native_name": "\u6f22\u8a9e (\u81fa\u7063)", + "id": "zh-TW" + } + }, + { + "fields": [ + [ + "native_name", + "isiZulu" + ], + [ + "primary_code", + "zul" + ], + [ + "subcode", + null + ], + [ + "name", + "Zulu" + ], + [ + "text_direction", + "ltr" + ] + ], + "namedtuple": "Language", + "properties": { + "code": "zul", + "first_native_name": "isiZulu", + "id": "zul" + } + } + ] + }, + "LANGUAGE_DIRECTIONS": { + "tuple": [ + { + "tuple": [ + "ltr", + "Left to Right" + ] + }, + { + "tuple": [ + "rtl", + "Right to Left" + ] + } + ] + }, + "LTR_LANGUAGE": "ltr", + "Language": { + "fields": [ + "native_name", + "primary_code", + "subcode", + "name", + "text_direction" + ], + "namedtuple_class": "Language" + }, + "RTL_LANGUAGE": "rtl", + "generate_list": { + "function": "(constantlist)" + }, + "getlang": { + "function": "(code, default=None)" + }, + "getlang_by_name": { + "function": "(name)" + }, + "getlang_by_native_name": { + "function": "(native_name)" + }, + "getlang_direction": { + "function": "(code)" + } + }, + "licenses": { + "ALL_RIGHTS_RESERVED": "All Rights Reserved", + "CC_BY": "CC BY", + "CC_BY_NC": "CC BY-NC", + "CC_BY_NC_ND": "CC BY-NC-ND", + "CC_BY_NC_SA": "CC BY-NC-SA", + "CC_BY_ND": "CC BY-ND", + "CC_BY_SA": "CC BY-SA", + "LICENSELIST": { + "list": [ + { + "fields": [ + [ + "id", + 1 + ], + [ + "name", + "CC BY" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 2 + ], + [ + "name", + "CC BY-SA" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by-sa/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 3 + ], + [ + "name", + "CC BY-ND" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by-nd/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 4 + ], + [ + "name", + "CC BY-NC" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by-nc/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 5 + ], + [ + "name", + "CC BY-NC-SA" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by-nc-sa/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 6 + ], + [ + "name", + "CC BY-NC-ND" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/licenses/by-nc-nd/4.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 7 + ], + [ + "name", + "All Rights Reserved" + ], + [ + "exists", + true + ], + [ + "url", + "http://www.allrights-reserved.com/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 8 + ], + [ + "name", + "Public Domain" + ], + [ + "exists", + true + ], + [ + "url", + "https://creativecommons.org/publicdomain/mark/1.0/" + ], + [ + "description", + "" + ], + [ + "custom", + false + ], + [ + "copyright_holder_required", + false + ] + ], + "namedtuple": "License", + "properties": {} + }, + { + "fields": [ + [ + "id", + 9 + ], + [ + "name", + "Special Permissions" + ], + [ + "exists", + false + ], + [ + "url", + "" + ], + [ + "description", + "" + ], + [ + "custom", + true + ], + [ + "copyright_holder_required", + true + ] + ], + "namedtuple": "License", + "properties": {} + } + ] + }, + "License": { + "fields": [ + "id", + "name", + "exists", + "url", + "description", + "custom", + "copyright_holder_required" + ], + "namedtuple_class": "License" + }, + "PUBLIC_DOMAIN": "Public Domain", + "SPECIAL_PERMISSIONS": "Special Permissions", + "choices": { + "tuple": [ + { + "tuple": [ + "CC BY", + "CC BY" + ] + }, + { + "tuple": [ + "CC BY-SA", + "CC BY-SA" + ] + }, + { + "tuple": [ + "CC BY-ND", + "CC BY-ND" + ] + }, + { + "tuple": [ + "CC BY-NC", + "CC BY-NC" + ] + }, + { + "tuple": [ + "CC BY-NC-SA", + "CC BY-NC-SA" + ] + }, + { + "tuple": [ + "CC BY-NC-ND", + "CC BY-NC-ND" + ] + }, + { + "tuple": [ + "All Rights Reserved", + "All Rights Reserved" + ] + }, + { + "tuple": [ + "Public Domain", + "Public Domain" + ] + }, + { + "tuple": [ + "Special Permissions", + "Special Permissions" + ] + } + ] + }, + "generate_list": { + "function": "(constantlist)" + } + } +} diff --git a/tests/test_formats.py b/tests/test_formats.py index ce8653b..b87c50b 100644 --- a/tests/test_formats.py +++ b/tests/test_formats.py @@ -1,21 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -import json -import pkgutil - from le_utils.constants import file_formats -def test_file_format_extensions_are_synced(): - formatlookup = json.loads(pkgutil.get_data("le_utils", "resources/formatlookup.json").decode("utf-8")) - - exts_formatlookup = set(dict(formatlookup).keys()) - exts_file_formats = set(dict(file_formats.choices).keys()) - - assert exts_formatlookup == exts_file_formats - - def test_FORMATLIST_exists(): assert file_formats.FORMATLIST, "FORMATLIST did not genereate properly" diff --git a/tests/test_generate_from_specs.py b/tests/test_generate_from_specs.py new file mode 100644 index 0000000..7e519d2 --- /dev/null +++ b/tests/test_generate_from_specs.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import importlib.util +import json +import os +import shutil +import subprocess +from collections import OrderedDict + +import pytest + +_script = importlib.util.spec_from_file_location("generate_from_specs", os.path.join(os.path.dirname(__file__), "..", "scripts", "generate_from_specs.py")) +generate_from_specs = importlib.util.module_from_spec(_script) +_script.loader.exec_module(generate_from_specs) + + +def spec(**overrides): + base = { + "namedtuple": {"name": "Format", "fields": ["id", "mimetype"], "getter": "getformat"}, + "records": [ + { + "constant": "MP4", + "label": "MP4 Video", + "field_constants": ["mimetype"], + "id": "mp4", + "mimetype": "video/mp4", + }, + ], + "choices_order": ["MP4"], + } + base.update(overrides) + return base + + +def assert_spec_raises(tmp_path, invalid_spec): + output_file = str(tmp_path / "formats.py") + with pytest.raises(ValueError): + generate_from_specs.write_namedtuple_python_file(output_file, "FileFormats", invalid_spec) + assert not os.path.exists(output_file) + + +def mp4_record(**overrides): + record = spec()["records"][0].copy() + record.update(overrides) + return record + + +def test_constant_shadowing_record_constant_raises(tmp_path): + assert_spec_raises(tmp_path, spec(constants={"MP4": "avi"})) + + +def test_constant_shadowing_field_constant_raises(tmp_path): + assert_spec_raises(tmp_path, spec(constants={"MP4_MIMETYPE": "video/avi"})) + + +def test_field_constant_shadowing_record_constant_raises(tmp_path): + records = [ + mp4_record(constant="MP4_MIMETYPE", id="a", field_constants=[]), + mp4_record(id="mp4"), + ] + assert_spec_raises(tmp_path, spec(records=records, choices_order=["MP4_MIMETYPE", "MP4"])) + + +def test_duplicate_record_constant_raises(tmp_path): + assert_spec_raises(tmp_path, spec(records=[mp4_record(), mp4_record(id="mp4b")])) + + +def test_duplicate_record_id_raises(tmp_path): + assert_spec_raises(tmp_path, spec(records=[mp4_record(), mp4_record(constant="MP4B")])) + + +def test_choices_order_with_undefined_record_raises(tmp_path): + assert_spec_raises(tmp_path, spec(choices_order=["MP4", "NOPE"])) + + +def test_choices_order_omitting_record_raises(tmp_path): + assert_spec_raises(tmp_path, spec(records=[mp4_record(), mp4_record(constant="WEBM", id="webm")])) + + +def test_choices_order_repeating_record_raises(tmp_path): + assert_spec_raises(tmp_path, spec(choices_order=["MP4", "MP4"])) + + +def test_tuple_with_undefined_constant_raises(tmp_path): + assert_spec_raises(tmp_path, spec(tuples={"VIDEO": ["MP4", "AVI"]})) + + +def test_tuple_repeating_constant_raises(tmp_path): + assert_spec_raises(tmp_path, spec(tuples={"VIDEO": ["MP4", "MP4"]})) + + +def test_record_missing_field_raises(tmp_path): + record = mp4_record() + del record["mimetype"] + assert_spec_raises(tmp_path, spec(records=[record])) + + +def write_and_exec(tmp_path, valid_spec): + output_file = str(tmp_path / "formats.py") + generate_from_specs.write_namedtuple_python_file(output_file, "FileFormats", valid_spec) + namespace = {} + with open(output_file) as f: + exec(f.read(), namespace) + return namespace + + +def test_tuple_with_defined_constants_is_written(tmp_path): + namespace = write_and_exec(tmp_path, spec(constants={"AVI": "avi"}, tuples={"VIDEO": ["MP4", "AVI"]})) + assert namespace["VIDEO"] == ("mp4", "avi") + + +def test_generate_list_yields_records(tmp_path): + namespace = write_and_exec(tmp_path, spec()) + records = list(namespace["generate_list"]({"webm": {"mimetype": "video/webm"}})) + assert records == [namespace["Format"](id="webm", mimetype="video/webm")] + + +def test_spec_without_choices_order_omits_choices(tmp_path): + valid_spec = spec() + del valid_spec["choices_order"] + namespace = write_and_exec(tmp_path, valid_spec) + assert "choices" not in namespace + assert namespace["FORMATLIST"] == [namespace["Format"](id="mp4", mimetype="video/mp4")] + + +def test_spec_without_getter_omits_getter(tmp_path): + valid_spec = spec(namedtuple={"name": "Format", "fields": ["id", "mimetype"]}) + namespace = write_and_exec(tmp_path, valid_spec) + assert "getformat" not in namespace + assert namespace["FORMATLIST"] == [namespace["Format"](id="mp4", mimetype="video/mp4")] + + +@pytest.mark.skipif(shutil.which("node") is None, reason="node is not installed") +def test_js_exports_constants_and_records(tmp_path): + output_file = tmp_path / "Formats.mjs" + generate_from_specs.write_namedtuple_js_file(str(output_file), "FileFormats", spec(constants={"AVI": "avi"})) + script = "import constants, {{ FORMATLIST }} from {!r}; console.log(JSON.stringify([constants, FORMATLIST]));".format(output_file.as_uri()) + output = subprocess.check_output(["node", "--input-type=module", "-e", script]) + constants, records = json.loads(output.decode("utf-8"), object_pairs_hook=OrderedDict) + assert list(constants.items()) == [("MP4", "mp4"), ("MP4_MIMETYPE", "video/mp4"), ("AVI", "avi")] + assert records == [{"id": "mp4", "mimetype": "video/mp4"}] diff --git a/tests/test_getformats.py b/tests/test_getformats.py index c5dbf2a..cdac8c3 100644 --- a/tests/test_getformats.py +++ b/tests/test_getformats.py @@ -15,7 +15,7 @@ def test_known_formats(): format_obj = file_formats.getformat("graphie") assert format_obj is not None, "graphie not found" assert format_obj.id == "graphie", "Wrong id" - assert format_obj.mimetype == ".graphie", "Wrong mimetype" + assert format_obj.mimetype == "application/x-graphie", "Wrong mimetype" format_obj = file_formats.getformat("gif") assert format_obj is not None, "gif not found" @@ -26,3 +26,8 @@ def test_known_formats(): def test_unknown_formats(): format_obj = file_formats.getformat("unknown-id") assert format_obj is None, "Unknown format code returned non-None" + + +def test_unknown_format_returns_default(): + default = object() + assert file_formats.getformat("unknown-id", default) is default diff --git a/tests/test_pinned_api.py b/tests/test_pinned_api.py new file mode 100644 index 0000000..f1b459d --- /dev/null +++ b/tests/test_pinned_api.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import inspect +import io +import json +import os + +from le_utils.constants import content_kinds +from le_utils.constants import file_formats +from le_utils.constants import format_presets +from le_utils.constants import languages +from le_utils.constants import licenses + +IMPORTS = {"json", "logging", "pkgutil", "namedtuple", "unicode_literals"} + +EXCLUDED = { + "content_kinds": {"file_formats"}, + "languages": { + "logger", + "lang_name", + "lang_obj", + "new_items", + "new_name", + "new_names", + "simple_name", + "lang_native_name", + "new_native_name", + "new_native_names", + "simple_native_name", + }, +} + +PINNED_PATH = os.path.join(os.path.dirname(__file__), "pinned_api.json") + +with io.open(PINNED_PATH, encoding="utf-8") as f: + PINNED = json.load(f) + + +def encode(value): + if value is None or isinstance(value, (bool, int, str)): + return value + if isinstance(value, tuple) and hasattr(value, "_fields"): + cls = type(value) + properties = sorted(name for name, attr in vars(cls).items() if isinstance(attr, property)) + return { + "namedtuple": cls.__name__, + "fields": [[field, encode(getattr(value, field))] for field in value._fields], + "properties": {name: encode(getattr(value, name)) for name in properties}, + } + if isinstance(value, tuple): + return {"tuple": [encode(item) for item in value]} + if isinstance(value, list): + return {"list": [encode(item) for item in value]} + if isinstance(value, dict): + return {"dict": {key: encode(item) for key, item in value.items()}} + if inspect.isclass(value) and hasattr(value, "_fields"): + return {"namedtuple_class": value.__name__, "fields": list(value._fields)} + if inspect.isfunction(value): + return {"function": str(inspect.signature(value))} + raise TypeError("Cannot encode {!r}".format(value)) + + +def encode_module(module): + excluded = IMPORTS | EXCLUDED.get(module.__name__.rsplit(".", 1)[-1], set()) + return {key: encode(value) for key, value in vars(module).items() if not key.startswith("_") and key not in excluded} + + +def test_file_formats_api_is_pinned(): + assert encode_module(file_formats) == PINNED["file_formats"] + + +def test_licenses_api_is_pinned(): + assert encode_module(licenses) == PINNED["licenses"] + + +def test_content_kinds_api_is_pinned(): + assert encode_module(content_kinds) == PINNED["content_kinds"] + + +def test_format_presets_api_is_pinned(): + assert encode_module(format_presets) == PINNED["format_presets"] + + +def test_languages_api_is_pinned(): + assert encode_module(languages) == PINNED["languages"]