wikitongues-db 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -219,7 +219,13 @@ var MULTILINGUAL_ALIASES = {
219
219
  sw: "swh",
220
220
  so: "som",
221
221
  zu: "zul",
222
- xh: "xho"
222
+ xh: "xho",
223
+ et: "est",
224
+ az: "aze",
225
+ lv: "lav",
226
+ ne: "nep",
227
+ ff: "ful",
228
+ mg: "mlg"
223
229
  };
224
230
  var MACROLANGUAGE_EXPANSIONS = {
225
231
  fas: ["fas", "pes", "prs"],
@@ -268,7 +274,10 @@ var MACROLANGUAGE_EXPANSIONS = {
268
274
  est: ["est", "ekk", "vro"],
269
275
  aka: ["aka", "twi", "fat"],
270
276
  nep: ["nep", "npi"],
271
- ful: ["ful", "fuf", "fuh", "fub", "fuq"]
277
+ ful: ["ful", "fuf", "fuh", "fub", "fuq"],
278
+ lav: ["lav", "lvs", "ltg"],
279
+ mon: ["mon", "khk", "mvf"],
280
+ mlg: ["mlg", "plt", "skg", "tkg"]
272
281
  };
273
282
  var LanguageResolver = class {
274
283
  isoToName = /* @__PURE__ */ new Map();
@@ -310,6 +319,14 @@ var LanguageResolver = class {
310
319
  this.aliases.set(prefix, iso);
311
320
  }
312
321
  }
322
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
323
+ if (part1 && !this.aliases.has(part1)) {
324
+ this.aliases.set(part1, iso);
325
+ }
326
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
327
+ if (macro && !this.aliases.has(macro)) {
328
+ this.aliases.set(macro, iso);
329
+ }
313
330
  const gc = lang.glottocode;
314
331
  this.glottoToIso.set(gc, iso);
315
332
  this.isoToGlotto.set(iso, gc);
@@ -375,7 +392,7 @@ var LanguageResolver = class {
375
392
  }
376
393
  }
377
394
  }
378
- if (matchedIsos.size === 0) {
395
+ if (matchedIsos.size === 0 && norm.length >= 4) {
379
396
  for (const [autoKey, isoSet] of this.autonymToIso.entries()) {
380
397
  if (autoKey.includes(norm)) {
381
398
  for (const iso of isoSet) {
@@ -488,6 +505,12 @@ var reference_default = {
488
505
  type: "L",
489
506
  invertedName: "Albanian, Tosk"
490
507
  },
508
+ alt: {
509
+ name: "Southern Altai",
510
+ scope: "I",
511
+ type: "L",
512
+ invertedName: "Altai, Southern"
513
+ },
491
514
  amh: {
492
515
  name: "Amharic",
493
516
  scope: "I",
@@ -1655,6 +1678,12 @@ var reference_default = {
1655
1678
  type: "L",
1656
1679
  invertedName: "Kabiy\xE8"
1657
1680
  },
1681
+ kcg: {
1682
+ name: "Tyap",
1683
+ scope: "I",
1684
+ type: "L",
1685
+ invertedName: "Tyap"
1686
+ },
1658
1687
  kdd: {
1659
1688
  name: "Yankunytjatjara",
1660
1689
  scope: "I",
@@ -1743,6 +1772,12 @@ var reference_default = {
1743
1772
  type: "L",
1744
1773
  invertedName: "Khmu"
1745
1774
  },
1775
+ kls: {
1776
+ name: "Kalasha",
1777
+ scope: "I",
1778
+ type: "L",
1779
+ invertedName: "Kalasha"
1780
+ },
1746
1781
  klu: {
1747
1782
  name: "Klao",
1748
1783
  scope: "I",
@@ -5223,6 +5258,14 @@ var reference_default = {
5223
5258
  longitude: 47.776611,
5224
5259
  familyId: "nakh1245"
5225
5260
  },
5261
+ kala1372: {
5262
+ name: "Chitral Kalasha",
5263
+ level: "language",
5264
+ macroarea: "Eurasia",
5265
+ latitude: 35.6415,
5266
+ longitude: 71.6657,
5267
+ familyId: "indo1319"
5268
+ },
5226
5269
  kala1399: {
5227
5270
  name: "Kalaallisut",
5228
5271
  level: "language",
@@ -6541,6 +6584,15 @@ var reference_default = {
6541
6584
  latitude: 16.74515934758395,
6542
6585
  longitude: -94.92819268907601
6543
6586
  },
6587
+ ower1238: {
6588
+ name: "Owerri",
6589
+ level: "dialect",
6590
+ macroarea: "Africa",
6591
+ latitude: 4.62705,
6592
+ longitude: 7.23441,
6593
+ familyId: "atla1278",
6594
+ parentLanguageId: "nucl1417"
6595
+ },
6544
6596
  paip1241: {
6545
6597
  name: "Paipai",
6546
6598
  level: "language",
@@ -7006,6 +7058,15 @@ var reference_default = {
7006
7058
  familyId: "sino1245",
7007
7059
  parentLanguageId: "wuch1236"
7008
7060
  },
7061
+ shet1241: {
7062
+ name: "Shaetlan",
7063
+ level: "dialect",
7064
+ macroarea: "Eurasia",
7065
+ latitude: 55.886945,
7066
+ longitude: -3.710133,
7067
+ familyId: "indo1319",
7068
+ parentLanguageId: "scot1243"
7069
+ },
7009
7070
  shin1264: {
7010
7071
  name: "Shina",
7011
7072
  level: "language",
@@ -7186,6 +7247,14 @@ var reference_default = {
7186
7247
  longitude: 27,
7187
7248
  familyId: "ural1272"
7188
7249
  },
7250
+ sout2694: {
7251
+ name: "Southern Altai",
7252
+ level: "language",
7253
+ macroarea: "Eurasia",
7254
+ latitude: 50.1347,
7255
+ longitude: 86.8705,
7256
+ familyId: "turk1311"
7257
+ },
7189
7258
  sout2772: {
7190
7259
  name: "Southern Daly",
7191
7260
  level: "family",
@@ -7706,6 +7775,14 @@ var reference_default = {
7706
7775
  familyId: "atla1278",
7707
7776
  parentLanguageId: "akan1250"
7708
7777
  },
7778
+ tyap1238: {
7779
+ name: "Tyap",
7780
+ level: "language",
7781
+ macroarea: "Africa",
7782
+ latitude: 9.75568,
7783
+ longitude: 8.3082,
7784
+ familyId: "atla1278"
7785
+ },
7709
7786
  uigh1240: {
7710
7787
  name: "Uighur",
7711
7788
  level: "language",
@@ -8071,6 +8148,9 @@ var reference_default = {
8071
8148
  description: "Tosk Albanian",
8072
8149
  macrolanguage: "sq"
8073
8150
  },
8151
+ alt: {
8152
+ description: "Southern Altai"
8153
+ },
8074
8154
  am: {
8075
8155
  description: "Amharic",
8076
8156
  suppressScript: "Ethi"
@@ -8689,6 +8769,9 @@ var reference_default = {
8689
8769
  kbp: {
8690
8770
  description: "Kabiy\xE8"
8691
8771
  },
8772
+ kcg: {
8773
+ description: "Tyap"
8774
+ },
8692
8775
  kdd: {
8693
8776
  description: "Yankunytjatjara"
8694
8777
  },
@@ -8734,6 +8817,9 @@ var reference_default = {
8734
8817
  description: "Kalaallisut; Greenlandic",
8735
8818
  suppressScript: "Latn"
8736
8819
  },
8820
+ kls: {
8821
+ description: "Kalasha"
8822
+ },
8737
8823
  klu: {
8738
8824
  description: "Klao"
8739
8825
  },
@@ -9720,6 +9806,9 @@ var reference_default = {
9720
9806
  sy: {
9721
9807
  description: "Syrian Arab Republic"
9722
9808
  },
9809
+ tw: {
9810
+ description: "Taiwan, Province of China"
9811
+ },
9723
9812
  us: {
9724
9813
  description: "United States"
9725
9814
  }
@@ -9830,6 +9919,7 @@ var ReferenceHydrator = class {
9830
9919
  }
9831
9920
  const resolved = { tag: raw, primarySubtag: primary, variantSubtags: [] };
9832
9921
  if (lang.description) resolved.description = lang.description;
9922
+ if (lang.macrolanguage) resolved.macrolanguage = lang.macrolanguage;
9833
9923
  let state = 0;
9834
9924
  for (const sub of parts.slice(1)) {
9835
9925
  const lower = sub.toLowerCase();
@@ -10111,6 +10201,8 @@ var Video = class _Video {
10111
10201
  const set = /* @__PURE__ */ new Set();
10112
10202
  for (const lang of this.allLanguages) {
10113
10203
  if (lang.iso639_3) set.add(lang.iso639_3);
10204
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10205
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10114
10206
  }
10115
10207
  return set;
10116
10208
  }
@@ -10121,6 +10213,9 @@ var Video = class _Video {
10121
10213
  const set = /* @__PURE__ */ new Set();
10122
10214
  for (const lang of this.allLanguages) {
10123
10215
  if (lang.bcp47) set.add(lang.bcp47);
10216
+ if (lang.iso639_3) set.add(lang.iso639_3);
10217
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10218
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10124
10219
  }
10125
10220
  return set;
10126
10221
  }
@@ -10158,6 +10253,8 @@ var Video = class _Video {
10158
10253
  const qNorm = normalizeText(q);
10159
10254
  for (const lang of this.allLanguages) {
10160
10255
  if (lang.iso639_3 === qLower) return true;
10256
+ if (lang.standards.iso639_3.part1?.toLowerCase() === qLower) return true;
10257
+ if (lang.standards.bcp47.macrolanguage?.toLowerCase() === qLower) return true;
10161
10258
  const bcp = lang.bcp47.toLowerCase();
10162
10259
  if (bcp === qLower || bcp.startsWith(`${qLower}-`)) return true;
10163
10260
  if (lang.glottocode === qLower) return true;
@@ -10166,7 +10263,8 @@ var Video = class _Video {
10166
10263
  const labelNorm = normalizeText(label);
10167
10264
  if (labelNorm === qNorm || ` ${labelNorm} `.includes(` ${qNorm} `)) return true;
10168
10265
  }
10169
- if (lang.autonym.toLowerCase().includes(qLower)) return true;
10266
+ const autoLower = lang.autonym.toLowerCase();
10267
+ if (autoLower === qLower || qLower.length >= 4 && autoLower.includes(qLower)) return true;
10170
10268
  }
10171
10269
  return false;
10172
10270
  }
@@ -10274,6 +10372,12 @@ var VideoCollection = class _VideoCollection {
10274
10372
  }
10275
10373
  return this._videos.some((v) => v.id === item.id);
10276
10374
  }
10375
+ /**
10376
+ * Check if any video in the collection matches the given language query.
10377
+ */
10378
+ hasLanguage(query) {
10379
+ return this._videos.some((v) => v.hasLanguage(query));
10380
+ }
10277
10381
  // -------------------------------------------------------------------------
10278
10382
  // Aggregation & Summary Properties
10279
10383
  // -------------------------------------------------------------------------
@@ -10579,7 +10683,7 @@ var DatasetIndex = class {
10579
10683
  const list = map.get(key);
10580
10684
  if (!list) {
10581
10685
  map.set(key, [video]);
10582
- } else {
10686
+ } else if (!list.some((v) => v.id === video.id)) {
10583
10687
  list.push(video);
10584
10688
  }
10585
10689
  }
@@ -10592,12 +10696,30 @@ var DatasetIndex = class {
10592
10696
  if (plIso) {
10593
10697
  this.appendToMap(this.byIsoPrimary, plIso, video);
10594
10698
  this.appendToMap(this.byIso, plIso, video);
10699
+ const part1 = video.primaryLanguage.standards.iso639_3.part1?.toLowerCase();
10700
+ if (part1 && part1 !== plIso) {
10701
+ this.appendToMap(this.byIsoPrimary, part1, video);
10702
+ this.appendToMap(this.byIso, part1, video);
10703
+ }
10704
+ const macro = video.primaryLanguage.standards.bcp47.macrolanguage?.toLowerCase();
10705
+ if (macro && macro !== plIso && macro !== part1) {
10706
+ this.appendToMap(this.byIsoPrimary, macro, video);
10707
+ this.appendToMap(this.byIso, macro, video);
10708
+ }
10595
10709
  }
10596
10710
  for (const addLang of video.additionalLanguages) {
10597
10711
  const aIso = addLang.iso639_3;
10598
- if (aIso && aIso !== plIso) {
10712
+ if (aIso) {
10599
10713
  this.appendToMap(this.byIso, aIso, video);
10600
10714
  }
10715
+ const part1 = addLang.standards.iso639_3.part1?.toLowerCase();
10716
+ if (part1 && part1 !== aIso) {
10717
+ this.appendToMap(this.byIso, part1, video);
10718
+ }
10719
+ const macro = addLang.standards.bcp47.macrolanguage?.toLowerCase();
10720
+ if (macro && macro !== aIso && macro !== part1) {
10721
+ this.appendToMap(this.byIso, macro, video);
10722
+ }
10601
10723
  }
10602
10724
  for (const lang of video.allLanguages) {
10603
10725
  const bcp = lang.bcp47.toLowerCase().trim();
@@ -10608,6 +10730,18 @@ var DatasetIndex = class {
10608
10730
  this.appendToMap(this.byBcp47, prefix, video);
10609
10731
  }
10610
10732
  }
10733
+ const iso = lang.iso639_3?.toLowerCase().trim();
10734
+ if (iso && iso !== bcp) {
10735
+ this.appendToMap(this.byBcp47, iso, video);
10736
+ }
10737
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase().trim();
10738
+ if (part1 && part1 !== bcp && part1 !== iso) {
10739
+ this.appendToMap(this.byBcp47, part1, video);
10740
+ }
10741
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase().trim();
10742
+ if (macro && macro !== bcp && macro !== iso && macro !== part1) {
10743
+ this.appendToMap(this.byBcp47, macro, video);
10744
+ }
10611
10745
  }
10612
10746
  for (const lang of video.allLanguages) {
10613
10747
  this.appendToMap(this.byGlottocode, lang.glottocode, video);
@@ -10850,6 +10984,14 @@ var QueryBuilder = class _QueryBuilder {
10850
10984
  if (matchedIsos.has(lIso) || lIso === rawLower) {
10851
10985
  return true;
10852
10986
  }
10987
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
10988
+ if (part1 && (matchedIsos.has(part1) || part1 === rawLower)) {
10989
+ return true;
10990
+ }
10991
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
10992
+ if (macro && (matchedIsos.has(macro) || macro === rawLower)) {
10993
+ return true;
10994
+ }
10853
10995
  const lBcp = lang.bcp47.toLowerCase();
10854
10996
  if (lBcp === rawLower || lBcp.startsWith(`${rawLower}-`)) {
10855
10997
  return true;
@@ -10862,7 +11004,9 @@ var QueryBuilder = class _QueryBuilder {
10862
11004
  const lNorm = normalizeText(label);
10863
11005
  if (lNorm === norm || pattern && pattern.test(lNorm)) return true;
10864
11006
  }
10865
- if (lang.autonym.toLowerCase().includes(rawLower)) return true;
11007
+ const autoLower = lang.autonym.toLowerCase();
11008
+ if (autoLower === rawLower) return true;
11009
+ if (rawLower.length >= 4 && autoLower.includes(rawLower)) return true;
10866
11010
  }
10867
11011
  return false;
10868
11012
  };
@@ -10885,13 +11029,17 @@ var QueryBuilder = class _QueryBuilder {
10885
11029
  iso(code, includeAdditional = true) {
10886
11030
  const codeClean = code.trim().toLowerCase();
10887
11031
  const predicate = (v) => {
10888
- if (v.primaryLanguage.iso639_3.toLowerCase() === codeClean) {
11032
+ const matchIso = (l) => {
11033
+ if (l.iso639_3.toLowerCase() === codeClean) return true;
11034
+ if (l.standards.iso639_3.part1?.toLowerCase() === codeClean) return true;
11035
+ if (l.standards.bcp47.macrolanguage?.toLowerCase() === codeClean) return true;
11036
+ return false;
11037
+ };
11038
+ if (matchIso(v.primaryLanguage)) {
10889
11039
  return true;
10890
11040
  }
10891
11041
  if (includeAdditional) {
10892
- return v.additionalLanguages.some(
10893
- (al) => al.iso639_3.toLowerCase() === codeClean
10894
- );
11042
+ return v.additionalLanguages.some(matchIso);
10895
11043
  }
10896
11044
  return false;
10897
11045
  };
@@ -10903,10 +11051,13 @@ var QueryBuilder = class _QueryBuilder {
10903
11051
  const predicate = (v) => {
10904
11052
  for (const lang of v.allLanguages) {
10905
11053
  const lTag = lang.bcp47.toLowerCase();
11054
+ const lIso = lang.iso639_3.toLowerCase();
11055
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
11056
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
10906
11057
  if (exact) {
10907
- if (lTag === tagClean) return true;
11058
+ if (lTag === tagClean || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10908
11059
  } else {
10909
- if (lTag === tagClean || lTag.startsWith(`${tagClean}-`)) return true;
11060
+ if (lTag === tagClean || lTag.startsWith(`${tagClean}-`) || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10910
11061
  }
10911
11062
  }
10912
11063
  return false;
@@ -63952,140 +64103,2500 @@ Best wishes to everybody at home, and I'm looking forward to be surrounded by re
63952
64103
  "2019 International Year of Indigenous Languages"
63953
64104
  ]
63954
64105
  }
63955
- }
63956
- ];
63957
-
63958
- // src/dataset.ts
63959
- var dataset = wikitongues_normalized_default;
63960
-
63961
- // src/client.ts
63962
- var WikitonguesDB = class _WikitonguesDB {
63963
- _videos = [];
63964
- hydrator;
63965
- resolver;
63966
- index;
63967
- searchEngine;
63968
- /**
63969
- * Loads and hydrates every record. Throws HydrationError on the first record whose
63970
- * standards do not resolve against the reference tables (see CLASSIFICATION_RULES.md §3.1.1).
63971
- */
63972
- constructor(options) {
63973
- this.hydrator = new ReferenceHydrator(options?.reference);
63974
- this.resolver = new LanguageResolver();
63975
- const rawRecords = options?.data || options?.records || dataset;
63976
- for (const record of rawRecords) {
63977
- const video = record instanceof Video ? record : Video.fromDict(record, this.hydrator);
63978
- this._videos.push(video);
63979
- for (const lang of video.allLanguages) {
63980
- this.resolver.registerDatasetLanguage(lang);
64106
+ },
64107
+ {
64108
+ id: "MxvdCaFjJZo",
64109
+ url: "https://www.youtube.com/watch?v=MxvdCaFjJZo",
64110
+ duration_seconds: 25,
64111
+ upload_date: "2026-09-18",
64112
+ license: "ALL_RIGHTS_RESERVED",
64113
+ content_type: "oral_history",
64114
+ primary_language: {
64115
+ standards: {
64116
+ iso639_3: "zul",
64117
+ glottocode: "zulu1248",
64118
+ bcp47: "zu"
64119
+ },
64120
+ speaker_claim: null,
64121
+ wikitongues_classification: "Zulu",
64122
+ wikitongues_lineage: null,
64123
+ autonym: "isiZulu"
64124
+ },
64125
+ additional_languages: [],
64126
+ speakers: [
64127
+ {
64128
+ name: "Halala Shezi (Lolly)",
64129
+ role: "native",
64130
+ origin: "South Africa"
63981
64131
  }
64132
+ ],
64133
+ provenance: {
64134
+ country_code: "ZA",
64135
+ country_name: "South Africa",
64136
+ region: null,
64137
+ city: null,
64138
+ recorded_by: null,
64139
+ recording_date: null
64140
+ },
64141
+ transcription: {
64142
+ has_subtitles: false,
64143
+ available_subtitles: [],
64144
+ native_text: null,
64145
+ english_translation: null
64146
+ },
64147
+ raw_metadata: {
64148
+ title: "Lolly speaking Zulu",
64149
+ tags: [
64150
+ "Wikitongues"
64151
+ ]
63982
64152
  }
63983
- this.index = new DatasetIndex(this._videos);
63984
- this.searchEngine = new SearchEngine(this._videos, this.resolver);
63985
- }
63986
- get length() {
63987
- return this._videos.length;
63988
- }
63989
- // -------------------------------------------------------------------------
63990
- // Static Factory Methods
63991
- // -------------------------------------------------------------------------
63992
- /**
63993
- * Create a WikitonguesDB instance directly from an in-memory list of dicts or Videos.
63994
- */
63995
- static fromRecords(records) {
63996
- return new _WikitonguesDB({ records });
63997
- }
63998
- /**
63999
- * Create a WikitonguesDB instance from a JSON string or JSON array.
64000
- */
64001
- static fromJSON(json) {
64002
- const data = typeof json === "string" ? JSON.parse(json) : json;
64003
- return new _WikitonguesDB({ data });
64004
- }
64005
- /**
64006
- * Create a WikitonguesDB instance from a JSON or JSONL file path (Node.js environments).
64007
- */
64008
- static fromFile(filepath) {
64009
- try {
64010
- const fs = __require("fs");
64011
- const content = fs.readFileSync(filepath, "utf-8");
64012
- const trimmed = content.trim();
64013
- let records = [];
64014
- if (trimmed.startsWith("[")) {
64015
- records = JSON.parse(trimmed);
64016
- } else {
64017
- records = trimmed.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
64153
+ },
64154
+ {
64155
+ id: "WgbfWSs0YaY",
64156
+ url: "https://www.youtube.com/watch?v=WgbfWSs0YaY",
64157
+ duration_seconds: 26,
64158
+ upload_date: "2026-09-16",
64159
+ license: "ALL_RIGHTS_RESERVED",
64160
+ content_type: "oral_history",
64161
+ primary_language: {
64162
+ standards: {
64163
+ iso639_3: "zul",
64164
+ glottocode: "zulu1248",
64165
+ bcp47: "zu"
64166
+ },
64167
+ speaker_claim: null,
64168
+ wikitongues_classification: "Zulu",
64169
+ wikitongues_lineage: null,
64170
+ autonym: "isiZulu"
64171
+ },
64172
+ additional_languages: [],
64173
+ speakers: [
64174
+ {
64175
+ name: "Halala Shezi (Lolly)",
64176
+ role: "native",
64177
+ origin: "South Africa"
64018
64178
  }
64019
- return new _WikitonguesDB({ data: records });
64020
- } catch (err) {
64021
- throw new Error(`Failed to load dataset from file '${filepath}': ${err.message}`);
64179
+ ],
64180
+ provenance: {
64181
+ country_code: "ZA",
64182
+ country_name: "South Africa",
64183
+ region: null,
64184
+ city: null,
64185
+ recorded_by: null,
64186
+ recording_date: null
64187
+ },
64188
+ transcription: {
64189
+ has_subtitles: false,
64190
+ available_subtitles: [],
64191
+ native_text: null,
64192
+ english_translation: null
64193
+ },
64194
+ raw_metadata: {
64195
+ title: "Lolly speaking Zulu",
64196
+ tags: [
64197
+ "Wikitongues"
64198
+ ]
64022
64199
  }
64023
- }
64024
- // -------------------------------------------------------------------------
64025
- // Direct Lookups (O(1))
64026
- // -------------------------------------------------------------------------
64027
- /**
64028
- * Lookup a video by its YouTube ID in O(1) time.
64029
- */
64030
- get(videoId) {
64031
- return this.index.byId.get(videoId.trim()) || null;
64032
- }
64033
- /**
64034
- * Lookup videos matching a 3-letter SIL ISO 639-3 code in O(1) time.
64035
- */
64036
- getByIso(code) {
64037
- const list = this.index.byIso.get(code.trim().toLowerCase());
64038
- return new VideoCollection(list || []);
64039
- }
64040
- /**
64041
- * Lookup videos matching a BCP 47 language tag in O(1) time.
64042
- */
64043
- getByBcp47(tag) {
64044
- const list = this.index.byBcp47.get(tag.trim().toLowerCase());
64045
- return new VideoCollection(list || []);
64046
- }
64047
- /**
64048
- * Lookup videos matching a Glottolog code in O(1) time. A language node also matches videos
64049
- * classified under one of its dialect nodes (e.g. `port1283` returns `braz1246` recordings).
64050
- */
64051
- getByGlottocode(glottocode) {
64052
- const list = this.index.byGlottocode.get(glottocode.trim().toLowerCase());
64053
- return new VideoCollection(list || []);
64054
- }
64055
- /**
64056
- * Lookup videos matching an ISO 3166-1 alpha-2 code or country name in O(1) time.
64057
- */
64058
- getByCountry(countryCodeOrName) {
64059
- const c = countryCodeOrName.trim();
64060
- if (c.length === 2 && this.index.byCountryCode.has(c.toUpperCase())) {
64061
- return new VideoCollection(this.index.byCountryCode.get(c.toUpperCase()) || []);
64200
+ },
64201
+ {
64202
+ id: "kF-HQw0BQNk",
64203
+ url: "https://www.youtube.com/watch?v=kF-HQw0BQNk",
64204
+ duration_seconds: 26,
64205
+ upload_date: "2026-09-14",
64206
+ license: "ALL_RIGHTS_RESERVED",
64207
+ content_type: "oral_history",
64208
+ primary_language: {
64209
+ standards: {
64210
+ iso639_3: "quc",
64211
+ glottocode: "kich1262",
64212
+ bcp47: "quc"
64213
+ },
64214
+ speaker_claim: null,
64215
+ wikitongues_classification: "K'iche'",
64216
+ wikitongues_lineage: null,
64217
+ autonym: "Qatzijob'al"
64218
+ },
64219
+ additional_languages: [],
64220
+ speakers: [
64221
+ {
64222
+ name: "Lorenzo",
64223
+ role: "native",
64224
+ origin: "Guatemala"
64225
+ }
64226
+ ],
64227
+ provenance: {
64228
+ country_code: "GT",
64229
+ country_name: "Guatemala",
64230
+ region: null,
64231
+ city: null,
64232
+ recorded_by: null,
64233
+ recording_date: null
64234
+ },
64235
+ transcription: {
64236
+ has_subtitles: false,
64237
+ available_subtitles: [],
64238
+ native_text: null,
64239
+ english_translation: null
64240
+ },
64241
+ raw_metadata: {
64242
+ title: "Lorenzo speaking K'iche",
64243
+ tags: [
64244
+ "Wikitongues"
64245
+ ]
64062
64246
  }
64063
- const normName = normalizeText(c);
64064
- if (this.index.byCountryName.has(normName)) {
64065
- return new VideoCollection(this.index.byCountryName.get(normName) || []);
64247
+ },
64248
+ {
64249
+ id: "mp6Tj1hE55o",
64250
+ url: "https://www.youtube.com/watch?v=mp6Tj1hE55o",
64251
+ duration_seconds: 23,
64252
+ upload_date: "2026-09-11",
64253
+ license: "ALL_RIGHTS_RESERVED",
64254
+ content_type: "oral_history",
64255
+ primary_language: {
64256
+ standards: {
64257
+ iso639_3: "quc",
64258
+ glottocode: "kich1262",
64259
+ bcp47: "quc"
64260
+ },
64261
+ speaker_claim: null,
64262
+ wikitongues_classification: "K'iche'",
64263
+ wikitongues_lineage: null,
64264
+ autonym: "Qatzijob'al"
64265
+ },
64266
+ additional_languages: [],
64267
+ speakers: [
64268
+ {
64269
+ name: "Lorenzo",
64270
+ role: "native",
64271
+ origin: "Guatemala"
64272
+ }
64273
+ ],
64274
+ provenance: {
64275
+ country_code: "GT",
64276
+ country_name: "Guatemala",
64277
+ region: null,
64278
+ city: null,
64279
+ recorded_by: null,
64280
+ recording_date: null
64281
+ },
64282
+ transcription: {
64283
+ has_subtitles: false,
64284
+ available_subtitles: [],
64285
+ native_text: null,
64286
+ english_translation: null
64287
+ },
64288
+ raw_metadata: {
64289
+ title: "Lorenzo speaking K'iche",
64290
+ tags: [
64291
+ "Wikitongues"
64292
+ ]
64066
64293
  }
64067
- return this.query().country(c).all();
64068
- }
64069
- /**
64070
- * Lookup videos for a given speaker name.
64071
- */
64072
- getBySpeaker(name) {
64073
- const normName = normalizeText(name);
64074
- if (this.index.bySpeakerName.has(normName)) {
64075
- return new VideoCollection(this.index.bySpeakerName.get(normName) || []);
64294
+ },
64295
+ {
64296
+ id: "LIcFLAdGTuw",
64297
+ url: "https://www.youtube.com/watch?v=LIcFLAdGTuw",
64298
+ duration_seconds: 38,
64299
+ upload_date: "2026-09-09",
64300
+ license: "ALL_RIGHTS_RESERVED",
64301
+ content_type: "oral_history",
64302
+ primary_language: {
64303
+ standards: {
64304
+ iso639_3: "quc",
64305
+ glottocode: "kich1262",
64306
+ bcp47: "quc"
64307
+ },
64308
+ speaker_claim: null,
64309
+ wikitongues_classification: "K'iche'",
64310
+ wikitongues_lineage: null,
64311
+ autonym: "Qatzijob'al"
64312
+ },
64313
+ additional_languages: [],
64314
+ speakers: [
64315
+ {
64316
+ name: "Lorenzo",
64317
+ role: "native",
64318
+ origin: "Guatemala"
64319
+ }
64320
+ ],
64321
+ provenance: {
64322
+ country_code: "GT",
64323
+ country_name: "Guatemala",
64324
+ region: null,
64325
+ city: null,
64326
+ recorded_by: null,
64327
+ recording_date: null
64328
+ },
64329
+ transcription: {
64330
+ has_subtitles: false,
64331
+ available_subtitles: [],
64332
+ native_text: null,
64333
+ english_translation: null
64334
+ },
64335
+ raw_metadata: {
64336
+ title: "Lorenzo speaking K'iche",
64337
+ tags: [
64338
+ "Wikitongues"
64339
+ ]
64076
64340
  }
64077
- return this.query().speaker({ name }).all();
64078
- }
64079
- // -------------------------------------------------------------------------
64080
- // Smart Lookups & Shortcut Queries
64081
- // -------------------------------------------------------------------------
64082
- /**
64083
- * Intelligent language search: resolves natural names, multilingual aliases ('russe'),
64084
- * ISO 639-3 ('rus'), BCP 47 ('ru'), Glottocodes, autonyms ('Русский'), Wikitongues
64085
- * classifications, Glottolog / ISO names and speaker claims.
64086
- */
64087
- findByLanguage(languageQuery, includeAdditional = true) {
64088
- return this.query().language(languageQuery, includeAdditional).all();
64341
+ },
64342
+ {
64343
+ id: "KK1boSHTmIk",
64344
+ url: "https://www.youtube.com/watch?v=KK1boSHTmIk",
64345
+ duration_seconds: 46,
64346
+ upload_date: "2026-04-23",
64347
+ license: "ALL_RIGHTS_RESERVED",
64348
+ content_type: "oral_history",
64349
+ primary_language: {
64350
+ standards: {
64351
+ iso639_3: "cmn",
64352
+ glottocode: "mand1415",
64353
+ bcp47: "cmn"
64354
+ },
64355
+ speaker_claim: null,
64356
+ wikitongues_classification: "Mandarin",
64357
+ wikitongues_lineage: null,
64358
+ autonym: "\u666E\u901A\u8BDD"
64359
+ },
64360
+ additional_languages: [],
64361
+ speakers: [
64362
+ {
64363
+ name: "Wanyu",
64364
+ role: "native",
64365
+ origin: "China"
64366
+ }
64367
+ ],
64368
+ provenance: {
64369
+ country_code: "CN",
64370
+ country_name: "China",
64371
+ region: null,
64372
+ city: null,
64373
+ recorded_by: null,
64374
+ recording_date: null
64375
+ },
64376
+ transcription: {
64377
+ has_subtitles: false,
64378
+ available_subtitles: [],
64379
+ native_text: null,
64380
+ english_translation: null
64381
+ },
64382
+ raw_metadata: {
64383
+ title: "Wanyu speaking Mandarin",
64384
+ tags: [
64385
+ "Wikitongues",
64386
+ "IYIL2019",
64387
+ "2019 International Year of Indigenous Languages"
64388
+ ]
64389
+ }
64390
+ },
64391
+ {
64392
+ id: "oGz_R-r-HLY",
64393
+ url: "https://www.youtube.com/watch?v=oGz_R-r-HLY",
64394
+ duration_seconds: 58,
64395
+ upload_date: "2026-04-21",
64396
+ license: "ALL_RIGHTS_RESERVED",
64397
+ content_type: "oral_history",
64398
+ primary_language: {
64399
+ standards: {
64400
+ iso639_3: "cmn",
64401
+ glottocode: "mand1415",
64402
+ bcp47: "cmn"
64403
+ },
64404
+ speaker_claim: null,
64405
+ wikitongues_classification: "Mandarin",
64406
+ wikitongues_lineage: null,
64407
+ autonym: "\u666E\u901A\u8BDD"
64408
+ },
64409
+ additional_languages: [],
64410
+ speakers: [
64411
+ {
64412
+ name: "Wanyu",
64413
+ role: "native",
64414
+ origin: "China"
64415
+ }
64416
+ ],
64417
+ provenance: {
64418
+ country_code: "CN",
64419
+ country_name: "China",
64420
+ region: null,
64421
+ city: null,
64422
+ recorded_by: null,
64423
+ recording_date: null
64424
+ },
64425
+ transcription: {
64426
+ has_subtitles: false,
64427
+ available_subtitles: [],
64428
+ native_text: null,
64429
+ english_translation: null
64430
+ },
64431
+ raw_metadata: {
64432
+ title: "Wanyu speaking Mandarin",
64433
+ tags: [
64434
+ "Wikitongues",
64435
+ "IYIL2019",
64436
+ "2019 International Year of Indigenous Languages"
64437
+ ]
64438
+ }
64439
+ },
64440
+ {
64441
+ id: "Tg2w5WKPIOw",
64442
+ url: "https://www.youtube.com/watch?v=Tg2w5WKPIOw",
64443
+ duration_seconds: 39,
64444
+ upload_date: "2026-04-19",
64445
+ license: "ALL_RIGHTS_RESERVED",
64446
+ content_type: "oral_history",
64447
+ primary_language: {
64448
+ standards: {
64449
+ iso639_3: "eng",
64450
+ glottocode: "stan1293",
64451
+ bcp47: "en-BM"
64452
+ },
64453
+ speaker_claim: null,
64454
+ wikitongues_classification: "Bermudian English",
64455
+ wikitongues_lineage: null,
64456
+ autonym: "English"
64457
+ },
64458
+ additional_languages: [],
64459
+ speakers: [
64460
+ {
64461
+ name: "Trey",
64462
+ role: "native",
64463
+ origin: "Bermuda"
64464
+ }
64465
+ ],
64466
+ provenance: {
64467
+ country_code: "BM",
64468
+ country_name: "Bermuda",
64469
+ region: null,
64470
+ city: null,
64471
+ recorded_by: null,
64472
+ recording_date: null
64473
+ },
64474
+ transcription: {
64475
+ has_subtitles: false,
64476
+ available_subtitles: [],
64477
+ native_text: null,
64478
+ english_translation: null
64479
+ },
64480
+ raw_metadata: {
64481
+ title: "Trey speaking Bermudian English",
64482
+ tags: [
64483
+ "Wikitongues",
64484
+ "IYIL2019",
64485
+ "2019 International Year of Indigenous Languages"
64486
+ ]
64487
+ }
64488
+ },
64489
+ {
64490
+ id: "-cbdIMW-cpU",
64491
+ url: "https://www.youtube.com/watch?v=-cbdIMW-cpU",
64492
+ duration_seconds: 33,
64493
+ upload_date: "2026-04-17",
64494
+ license: "ALL_RIGHTS_RESERVED",
64495
+ content_type: "oral_history",
64496
+ primary_language: {
64497
+ standards: {
64498
+ iso639_3: "eng",
64499
+ glottocode: "stan1293",
64500
+ bcp47: "en-BM"
64501
+ },
64502
+ speaker_claim: null,
64503
+ wikitongues_classification: "Bermudian English",
64504
+ wikitongues_lineage: null,
64505
+ autonym: "English"
64506
+ },
64507
+ additional_languages: [],
64508
+ speakers: [
64509
+ {
64510
+ name: "Trey",
64511
+ role: "native",
64512
+ origin: "Bermuda"
64513
+ }
64514
+ ],
64515
+ provenance: {
64516
+ country_code: "BM",
64517
+ country_name: "Bermuda",
64518
+ region: null,
64519
+ city: null,
64520
+ recorded_by: null,
64521
+ recording_date: null
64522
+ },
64523
+ transcription: {
64524
+ has_subtitles: false,
64525
+ available_subtitles: [],
64526
+ native_text: null,
64527
+ english_translation: null
64528
+ },
64529
+ raw_metadata: {
64530
+ title: "Trey speaking Bermudian English",
64531
+ tags: [
64532
+ "Wikitongues",
64533
+ "IYIL2019",
64534
+ "2019 International Year of Indigenous Languages"
64535
+ ]
64536
+ }
64537
+ },
64538
+ {
64539
+ id: "inmozOx5Gos",
64540
+ url: "https://www.youtube.com/watch?v=inmozOx5Gos",
64541
+ duration_seconds: 78,
64542
+ upload_date: "2026-04-15",
64543
+ license: "ALL_RIGHTS_RESERVED",
64544
+ content_type: "oral_history",
64545
+ primary_language: {
64546
+ standards: {
64547
+ iso639_3: "eng",
64548
+ glottocode: "stan1293",
64549
+ bcp47: "en-BM"
64550
+ },
64551
+ speaker_claim: null,
64552
+ wikitongues_classification: "Bermudian English",
64553
+ wikitongues_lineage: null,
64554
+ autonym: "English"
64555
+ },
64556
+ additional_languages: [],
64557
+ speakers: [
64558
+ {
64559
+ name: "Trey",
64560
+ role: "native",
64561
+ origin: "Bermuda"
64562
+ }
64563
+ ],
64564
+ provenance: {
64565
+ country_code: "BM",
64566
+ country_name: "Bermuda",
64567
+ region: null,
64568
+ city: null,
64569
+ recorded_by: null,
64570
+ recording_date: null
64571
+ },
64572
+ transcription: {
64573
+ has_subtitles: false,
64574
+ available_subtitles: [],
64575
+ native_text: null,
64576
+ english_translation: null
64577
+ },
64578
+ raw_metadata: {
64579
+ title: "Trey speaks Bermudian English",
64580
+ tags: [
64581
+ "Wikitongues",
64582
+ "IYIL2019",
64583
+ "2019 International Year of Indigenous Languages"
64584
+ ]
64585
+ }
64586
+ },
64587
+ {
64588
+ id: "2S-P_O-_1N8",
64589
+ url: "https://www.youtube.com/watch?v=2S-P_O-_1N8",
64590
+ duration_seconds: 45,
64591
+ upload_date: "2026-03-22",
64592
+ license: "ALL_RIGHTS_RESERVED",
64593
+ content_type: "oral_history",
64594
+ primary_language: {
64595
+ standards: {
64596
+ iso639_3: "cym",
64597
+ glottocode: "wels1247",
64598
+ bcp47: "cy"
64599
+ },
64600
+ speaker_claim: null,
64601
+ wikitongues_classification: "Welsh",
64602
+ wikitongues_lineage: null,
64603
+ autonym: "Cymraeg"
64604
+ },
64605
+ additional_languages: [],
64606
+ speakers: [
64607
+ {
64608
+ name: "Hywel",
64609
+ role: "native",
64610
+ origin: "Wales"
64611
+ }
64612
+ ],
64613
+ provenance: {
64614
+ country_code: "GB",
64615
+ country_name: "United Kingdom",
64616
+ region: "Wales",
64617
+ city: null,
64618
+ recorded_by: null,
64619
+ recording_date: null
64620
+ },
64621
+ transcription: {
64622
+ has_subtitles: false,
64623
+ available_subtitles: [],
64624
+ native_text: null,
64625
+ english_translation: null
64626
+ },
64627
+ raw_metadata: {
64628
+ title: "Hywel speaking Welsh",
64629
+ tags: []
64630
+ }
64631
+ },
64632
+ {
64633
+ id: "N4q_mynBip0",
64634
+ url: "https://www.youtube.com/watch?v=N4q_mynBip0",
64635
+ duration_seconds: 30,
64636
+ upload_date: "2026-03-20",
64637
+ license: "ALL_RIGHTS_RESERVED",
64638
+ content_type: "oral_history",
64639
+ primary_language: {
64640
+ standards: {
64641
+ iso639_3: "cym",
64642
+ glottocode: "wels1247",
64643
+ bcp47: "cy"
64644
+ },
64645
+ speaker_claim: null,
64646
+ wikitongues_classification: "Welsh",
64647
+ wikitongues_lineage: null,
64648
+ autonym: "Cymraeg"
64649
+ },
64650
+ additional_languages: [],
64651
+ speakers: [
64652
+ {
64653
+ name: "Hywel",
64654
+ role: "native",
64655
+ origin: "Wales"
64656
+ }
64657
+ ],
64658
+ provenance: {
64659
+ country_code: "GB",
64660
+ country_name: "United Kingdom",
64661
+ region: "Wales",
64662
+ city: null,
64663
+ recorded_by: null,
64664
+ recording_date: null
64665
+ },
64666
+ transcription: {
64667
+ has_subtitles: false,
64668
+ available_subtitles: [],
64669
+ native_text: null,
64670
+ english_translation: null
64671
+ },
64672
+ raw_metadata: {
64673
+ title: "Hywel speaking Welsh",
64674
+ tags: []
64675
+ }
64676
+ },
64677
+ {
64678
+ id: "FyWJnhCa-ng",
64679
+ url: "https://www.youtube.com/watch?v=FyWJnhCa-ng",
64680
+ duration_seconds: 25,
64681
+ upload_date: "2026-03-16",
64682
+ license: "ALL_RIGHTS_RESERVED",
64683
+ content_type: "oral_history",
64684
+ primary_language: {
64685
+ standards: {
64686
+ iso639_3: "cym",
64687
+ glottocode: "wels1247",
64688
+ bcp47: "cy"
64689
+ },
64690
+ speaker_claim: null,
64691
+ wikitongues_classification: "Welsh",
64692
+ wikitongues_lineage: null,
64693
+ autonym: "Cymraeg"
64694
+ },
64695
+ additional_languages: [],
64696
+ speakers: [
64697
+ {
64698
+ name: "Hywel",
64699
+ role: "native",
64700
+ origin: "Wales"
64701
+ }
64702
+ ],
64703
+ provenance: {
64704
+ country_code: "GB",
64705
+ country_name: "United Kingdom",
64706
+ region: "Wales",
64707
+ city: null,
64708
+ recorded_by: null,
64709
+ recording_date: null
64710
+ },
64711
+ transcription: {
64712
+ has_subtitles: false,
64713
+ available_subtitles: [],
64714
+ native_text: null,
64715
+ english_translation: null
64716
+ },
64717
+ raw_metadata: {
64718
+ title: "Hywel speaking Welsh",
64719
+ tags: []
64720
+ }
64721
+ },
64722
+ {
64723
+ id: "gB6x-lINQXM",
64724
+ url: "https://www.youtube.com/watch?v=gB6x-lINQXM",
64725
+ duration_seconds: 40,
64726
+ upload_date: "2026-03-14",
64727
+ license: "ALL_RIGHTS_RESERVED",
64728
+ content_type: "oral_history",
64729
+ primary_language: {
64730
+ standards: {
64731
+ iso639_3: "deu",
64732
+ glottocode: "stan1295",
64733
+ bcp47: "de-US"
64734
+ },
64735
+ speaker_claim: null,
64736
+ wikitongues_classification: "Texas German",
64737
+ wikitongues_lineage: null,
64738
+ autonym: "Texasdeutsch"
64739
+ },
64740
+ additional_languages: [],
64741
+ speakers: [
64742
+ {
64743
+ name: "Vernell",
64744
+ role: "native",
64745
+ origin: "Texas"
64746
+ }
64747
+ ],
64748
+ provenance: {
64749
+ country_code: "US",
64750
+ country_name: "United States",
64751
+ region: "Texas",
64752
+ city: "Fredericksburg",
64753
+ recorded_by: null,
64754
+ recording_date: null
64755
+ },
64756
+ transcription: {
64757
+ has_subtitles: false,
64758
+ available_subtitles: [],
64759
+ native_text: null,
64760
+ english_translation: null
64761
+ },
64762
+ raw_metadata: {
64763
+ title: "Vernell speaks Texas German",
64764
+ tags: []
64765
+ }
64766
+ },
64767
+ {
64768
+ id: "3L_akwiAvPI",
64769
+ url: "https://www.youtube.com/watch?v=3L_akwiAvPI",
64770
+ duration_seconds: 29,
64771
+ upload_date: "2026-03-12",
64772
+ license: "ALL_RIGHTS_RESERVED",
64773
+ content_type: "oral_history",
64774
+ primary_language: {
64775
+ standards: {
64776
+ iso639_3: "deu",
64777
+ glottocode: "stan1295",
64778
+ bcp47: "de-US"
64779
+ },
64780
+ speaker_claim: null,
64781
+ wikitongues_classification: "Texas German",
64782
+ wikitongues_lineage: null,
64783
+ autonym: "Texasdeutsch"
64784
+ },
64785
+ additional_languages: [],
64786
+ speakers: [
64787
+ {
64788
+ name: "Vernell",
64789
+ role: "native",
64790
+ origin: "Texas"
64791
+ }
64792
+ ],
64793
+ provenance: {
64794
+ country_code: "US",
64795
+ country_name: "United States",
64796
+ region: "Texas",
64797
+ city: "Fredericksburg",
64798
+ recorded_by: null,
64799
+ recording_date: null
64800
+ },
64801
+ transcription: {
64802
+ has_subtitles: false,
64803
+ available_subtitles: [],
64804
+ native_text: null,
64805
+ english_translation: null
64806
+ },
64807
+ raw_metadata: {
64808
+ title: "Vernell speaks Texas German",
64809
+ tags: []
64810
+ }
64811
+ },
64812
+ {
64813
+ id: "ACkloeSPfFA",
64814
+ url: "https://www.youtube.com/watch?v=ACkloeSPfFA",
64815
+ duration_seconds: 73,
64816
+ upload_date: "2026-03-11",
64817
+ license: "ALL_RIGHTS_RESERVED",
64818
+ content_type: "oral_history",
64819
+ primary_language: {
64820
+ standards: {
64821
+ iso639_3: "frc",
64822
+ glottocode: "caju1236",
64823
+ bcp47: "frc"
64824
+ },
64825
+ speaker_claim: null,
64826
+ wikitongues_classification: "Louisiana French",
64827
+ wikitongues_lineage: null,
64828
+ autonym: "Fran\xE7ais louisianais"
64829
+ },
64830
+ additional_languages: [],
64831
+ speakers: [
64832
+ {
64833
+ name: "Sam Craft",
64834
+ role: "heritage",
64835
+ origin: "Louisiana"
64836
+ }
64837
+ ],
64838
+ provenance: {
64839
+ country_code: "US",
64840
+ country_name: "United States",
64841
+ region: "Louisiana",
64842
+ city: null,
64843
+ recorded_by: null,
64844
+ recording_date: null
64845
+ },
64846
+ transcription: {
64847
+ has_subtitles: false,
64848
+ available_subtitles: [],
64849
+ native_text: null,
64850
+ english_translation: null
64851
+ },
64852
+ raw_metadata: {
64853
+ title: "Sam speaking Louisiana French (Part 3)",
64854
+ tags: []
64855
+ }
64856
+ },
64857
+ {
64858
+ id: "TwwLkiLNkBg",
64859
+ url: "https://www.youtube.com/watch?v=TwwLkiLNkBg",
64860
+ duration_seconds: 58,
64861
+ upload_date: "2026-03-10",
64862
+ license: "ALL_RIGHTS_RESERVED",
64863
+ content_type: "oral_history",
64864
+ primary_language: {
64865
+ standards: {
64866
+ iso639_3: "frc",
64867
+ glottocode: "caju1236",
64868
+ bcp47: "frc"
64869
+ },
64870
+ speaker_claim: null,
64871
+ wikitongues_classification: "Louisiana French",
64872
+ wikitongues_lineage: null,
64873
+ autonym: "Fran\xE7ais louisianais"
64874
+ },
64875
+ additional_languages: [],
64876
+ speakers: [
64877
+ {
64878
+ name: "Sam Craft",
64879
+ role: "heritage",
64880
+ origin: "Louisiana"
64881
+ }
64882
+ ],
64883
+ provenance: {
64884
+ country_code: "US",
64885
+ country_name: "United States",
64886
+ region: "Louisiana",
64887
+ city: null,
64888
+ recorded_by: null,
64889
+ recording_date: null
64890
+ },
64891
+ transcription: {
64892
+ has_subtitles: false,
64893
+ available_subtitles: [],
64894
+ native_text: null,
64895
+ english_translation: null
64896
+ },
64897
+ raw_metadata: {
64898
+ title: "Sam speaking Louisiana French (Part 2)",
64899
+ tags: [
64900
+ "Wikitongues"
64901
+ ]
64902
+ }
64903
+ },
64904
+ {
64905
+ id: "su4ynRj560Q",
64906
+ url: "https://www.youtube.com/watch?v=su4ynRj560Q",
64907
+ duration_seconds: 87,
64908
+ upload_date: "2026-03-10",
64909
+ license: "ALL_RIGHTS_RESERVED",
64910
+ content_type: "oral_history",
64911
+ primary_language: {
64912
+ standards: {
64913
+ iso639_3: "frc",
64914
+ glottocode: "caju1236",
64915
+ bcp47: "frc"
64916
+ },
64917
+ speaker_claim: null,
64918
+ wikitongues_classification: "Louisiana French",
64919
+ wikitongues_lineage: null,
64920
+ autonym: "Fran\xE7ais louisianais"
64921
+ },
64922
+ additional_languages: [],
64923
+ speakers: [
64924
+ {
64925
+ name: "Sam Craft",
64926
+ role: "heritage",
64927
+ origin: "Louisiana"
64928
+ }
64929
+ ],
64930
+ provenance: {
64931
+ country_code: "US",
64932
+ country_name: "United States",
64933
+ region: "Louisiana",
64934
+ city: null,
64935
+ recorded_by: null,
64936
+ recording_date: null
64937
+ },
64938
+ transcription: {
64939
+ has_subtitles: false,
64940
+ available_subtitles: [],
64941
+ native_text: null,
64942
+ english_translation: null
64943
+ },
64944
+ raw_metadata: {
64945
+ title: "Sam speaking Louisiana French (Part 1)",
64946
+ tags: [
64947
+ "Wikitongues",
64948
+ "IYIL2019",
64949
+ "2019 International Year of Indigenous Languages"
64950
+ ]
64951
+ }
64952
+ },
64953
+ {
64954
+ id: "JFC9iGDrDTA",
64955
+ url: "https://www.youtube.com/watch?v=JFC9iGDrDTA",
64956
+ duration_seconds: 103,
64957
+ upload_date: "2026-02-13",
64958
+ license: "ALL_RIGHTS_RESERVED",
64959
+ content_type: "reading_or_song",
64960
+ primary_language: {
64961
+ standards: {
64962
+ iso639_3: "sco",
64963
+ glottocode: "shet1241",
64964
+ bcp47: "sco"
64965
+ },
64966
+ speaker_claim: null,
64967
+ wikitongues_classification: "Shetlandic",
64968
+ wikitongues_lineage: null,
64969
+ autonym: "Shaetlan"
64970
+ },
64971
+ additional_languages: [
64972
+ {
64973
+ standards: {
64974
+ iso639_3: "eng",
64975
+ glottocode: "stan1293",
64976
+ bcp47: "en"
64977
+ },
64978
+ speaker_claim: null,
64979
+ wikitongues_classification: "English",
64980
+ wikitongues_lineage: null,
64981
+ autonym: "English"
64982
+ }
64983
+ ],
64984
+ speakers: [
64985
+ {
64986
+ name: "Christine De Luca",
64987
+ role: "native",
64988
+ origin: "Shetland"
64989
+ }
64990
+ ],
64991
+ provenance: {
64992
+ country_code: "GB",
64993
+ country_name: "United Kingdom",
64994
+ region: "Scotland",
64995
+ city: "Edinburgh",
64996
+ recorded_by: null,
64997
+ recording_date: null
64998
+ },
64999
+ transcription: {
65000
+ has_subtitles: false,
65001
+ available_subtitles: [],
65002
+ native_text: null,
65003
+ english_translation: null
65004
+ },
65005
+ raw_metadata: {
65006
+ title: "Christine reads a poem in English and Shetlandic",
65007
+ tags: [
65008
+ "Wikitongues",
65009
+ "IYIL2019",
65010
+ "2019 International Year of Indigenous Languages"
65011
+ ]
65012
+ }
65013
+ },
65014
+ {
65015
+ id: "p6QqAeuzuGY",
65016
+ url: "https://www.youtube.com/watch?v=p6QqAeuzuGY",
65017
+ duration_seconds: 78,
65018
+ upload_date: "2026-02-11",
65019
+ license: "ALL_RIGHTS_RESERVED",
65020
+ content_type: "oral_history",
65021
+ primary_language: {
65022
+ standards: {
65023
+ iso639_3: "sco",
65024
+ glottocode: "shet1241",
65025
+ bcp47: "sco"
65026
+ },
65027
+ speaker_claim: null,
65028
+ wikitongues_classification: "Shetlandic",
65029
+ wikitongues_lineage: null,
65030
+ autonym: "Shaetlan"
65031
+ },
65032
+ additional_languages: [],
65033
+ speakers: [
65034
+ {
65035
+ name: "Christine De Luca",
65036
+ role: "native",
65037
+ origin: "Shetland"
65038
+ }
65039
+ ],
65040
+ provenance: {
65041
+ country_code: "GB",
65042
+ country_name: "United Kingdom",
65043
+ region: "Scotland",
65044
+ city: "Edinburgh",
65045
+ recorded_by: null,
65046
+ recording_date: null
65047
+ },
65048
+ transcription: {
65049
+ has_subtitles: false,
65050
+ available_subtitles: [],
65051
+ native_text: null,
65052
+ english_translation: null
65053
+ },
65054
+ raw_metadata: {
65055
+ title: "Christine was taught English. Writing led her back to her mother tongue.",
65056
+ tags: [
65057
+ "Wikitongues",
65058
+ "IYIL2019",
65059
+ "2019 International Year of Indigenous Languages"
65060
+ ]
65061
+ }
65062
+ },
65063
+ {
65064
+ id: "FDYuB3KfViY",
65065
+ url: "https://www.youtube.com/watch?v=FDYuB3KfViY",
65066
+ duration_seconds: 65,
65067
+ upload_date: "2026-02-09",
65068
+ license: "ALL_RIGHTS_RESERVED",
65069
+ content_type: "oral_history",
65070
+ primary_language: {
65071
+ standards: {
65072
+ iso639_3: "sco",
65073
+ glottocode: "shet1241",
65074
+ bcp47: "sco"
65075
+ },
65076
+ speaker_claim: null,
65077
+ wikitongues_classification: "Shetlandic",
65078
+ wikitongues_lineage: null,
65079
+ autonym: "Shaetlan"
65080
+ },
65081
+ additional_languages: [],
65082
+ speakers: [
65083
+ {
65084
+ name: "Christine De Luca",
65085
+ role: "native",
65086
+ origin: "Shetland"
65087
+ }
65088
+ ],
65089
+ provenance: {
65090
+ country_code: "GB",
65091
+ country_name: "United Kingdom",
65092
+ region: "Scotland",
65093
+ city: "Edinburgh",
65094
+ recorded_by: null,
65095
+ recording_date: null
65096
+ },
65097
+ transcription: {
65098
+ has_subtitles: false,
65099
+ available_subtitles: [],
65100
+ native_text: null,
65101
+ english_translation: null
65102
+ },
65103
+ raw_metadata: {
65104
+ title: `Edinburgh's Poet Laureate (2014-2017) challenges the idea that Shetlandic is "less than"`,
65105
+ tags: [
65106
+ "Wikitongues",
65107
+ "IYIL2019",
65108
+ "2019 International Year of Indigenous Languages"
65109
+ ]
65110
+ }
65111
+ },
65112
+ {
65113
+ id: "bicQILtQ8is",
65114
+ url: "https://www.youtube.com/watch?v=bicQILtQ8is",
65115
+ duration_seconds: 82,
65116
+ upload_date: "2026-02-06",
65117
+ license: "ALL_RIGHTS_RESERVED",
65118
+ content_type: "reading_or_song",
65119
+ primary_language: {
65120
+ standards: {
65121
+ iso639_3: "gul",
65122
+ glottocode: "gull1241",
65123
+ bcp47: "gul-US"
65124
+ },
65125
+ speaker_claim: null,
65126
+ wikitongues_classification: "Gullah",
65127
+ wikitongues_lineage: null,
65128
+ autonym: "Gullah"
65129
+ },
65130
+ additional_languages: [],
65131
+ speakers: [
65132
+ {
65133
+ name: "Caroline",
65134
+ role: "native",
65135
+ origin: "South Carolina"
65136
+ }
65137
+ ],
65138
+ provenance: {
65139
+ country_code: "US",
65140
+ country_name: "United States",
65141
+ region: "South Carolina",
65142
+ city: "Charleston",
65143
+ recorded_by: null,
65144
+ recording_date: null
65145
+ },
65146
+ transcription: {
65147
+ has_subtitles: false,
65148
+ available_subtitles: [],
65149
+ native_text: null,
65150
+ english_translation: null
65151
+ },
65152
+ raw_metadata: {
65153
+ title: "The New Testament, read in Gullah",
65154
+ tags: [
65155
+ "Wikitongues",
65156
+ "IYIL2019",
65157
+ "2019 International Year of Indigenous Languages"
65158
+ ]
65159
+ }
65160
+ },
65161
+ {
65162
+ id: "ig9niswAGCk",
65163
+ url: "https://www.youtube.com/watch?v=ig9niswAGCk",
65164
+ duration_seconds: 75,
65165
+ upload_date: "2026-02-04",
65166
+ license: "ALL_RIGHTS_RESERVED",
65167
+ content_type: "oral_history",
65168
+ primary_language: {
65169
+ standards: {
65170
+ iso639_3: "gul",
65171
+ glottocode: "gull1241",
65172
+ bcp47: "gul-US"
65173
+ },
65174
+ speaker_claim: null,
65175
+ wikitongues_classification: "Gullah",
65176
+ wikitongues_lineage: null,
65177
+ autonym: "Gullah"
65178
+ },
65179
+ additional_languages: [],
65180
+ speakers: [
65181
+ {
65182
+ name: "Caroline",
65183
+ role: "native",
65184
+ origin: "South Carolina"
65185
+ }
65186
+ ],
65187
+ provenance: {
65188
+ country_code: "US",
65189
+ country_name: "United States",
65190
+ region: "South Carolina",
65191
+ city: "Charleston",
65192
+ recorded_by: null,
65193
+ recording_date: null
65194
+ },
65195
+ transcription: {
65196
+ has_subtitles: false,
65197
+ available_subtitles: [],
65198
+ native_text: null,
65199
+ english_translation: null
65200
+ },
65201
+ raw_metadata: {
65202
+ title: "Caroline used to be corrected for speaking Gullah, now she teaches it.",
65203
+ tags: [
65204
+ "Wikitongues",
65205
+ "IYIL2019",
65206
+ "2019 International Year of Indigenous Languages"
65207
+ ]
65208
+ }
65209
+ },
65210
+ {
65211
+ id: "2Y5aRpz4k30",
65212
+ url: "https://www.youtube.com/watch?v=2Y5aRpz4k30",
65213
+ duration_seconds: 54,
65214
+ upload_date: "2026-02-02",
65215
+ license: "ALL_RIGHTS_RESERVED",
65216
+ content_type: "language_lesson",
65217
+ primary_language: {
65218
+ standards: {
65219
+ iso639_3: "gul",
65220
+ glottocode: "gull1241",
65221
+ bcp47: "gul-US"
65222
+ },
65223
+ speaker_claim: null,
65224
+ wikitongues_classification: "Gullah",
65225
+ wikitongues_lineage: null,
65226
+ autonym: "Gullah"
65227
+ },
65228
+ additional_languages: [],
65229
+ speakers: [
65230
+ {
65231
+ name: "Caroline",
65232
+ role: "native",
65233
+ origin: "South Carolina"
65234
+ }
65235
+ ],
65236
+ provenance: {
65237
+ country_code: "US",
65238
+ country_name: "United States",
65239
+ region: "South Carolina",
65240
+ city: "Charleston",
65241
+ recorded_by: null,
65242
+ recording_date: null
65243
+ },
65244
+ transcription: {
65245
+ has_subtitles: false,
65246
+ available_subtitles: [],
65247
+ native_text: null,
65248
+ english_translation: null
65249
+ },
65250
+ raw_metadata: {
65251
+ title: "Gullah: a living language from the U.S. South",
65252
+ tags: [
65253
+ "Wikitongues",
65254
+ "IYIL2019",
65255
+ "2019 International Year of Indigenous Languages"
65256
+ ]
65257
+ }
65258
+ },
65259
+ {
65260
+ id: "nGeLETLlFXA",
65261
+ url: "https://www.youtube.com/watch?v=nGeLETLlFXA",
65262
+ duration_seconds: 100,
65263
+ upload_date: "2025-12-10",
65264
+ license: "CC-BY-NC-4.0",
65265
+ content_type: "oral_history",
65266
+ primary_language: {
65267
+ standards: {
65268
+ iso639_3: "quh",
65269
+ glottocode: "sout2991",
65270
+ bcp47: "quh"
65271
+ },
65272
+ speaker_claim: null,
65273
+ wikitongues_classification: "South Bolivian Quechua",
65274
+ wikitongues_lineage: "Quechuan",
65275
+ autonym: "Qhichwa"
65276
+ },
65277
+ additional_languages: [],
65278
+ speakers: [
65279
+ {
65280
+ name: "Nicaela",
65281
+ role: "native",
65282
+ origin: "Bolivia"
65283
+ }
65284
+ ],
65285
+ provenance: {
65286
+ country_code: "BO",
65287
+ country_name: "Bolivia",
65288
+ region: null,
65289
+ city: null,
65290
+ recorded_by: null,
65291
+ recording_date: null
65292
+ },
65293
+ transcription: {
65294
+ has_subtitles: false,
65295
+ available_subtitles: [],
65296
+ native_text: null,
65297
+ english_translation: null
65298
+ },
65299
+ raw_metadata: {
65300
+ title: "Nicaela speaking South Bolivian Quechua | Quechuan | Language of the Americas | Wikitongues",
65301
+ tags: [
65302
+ "Wikitongues",
65303
+ "IYIL2019",
65304
+ "2019 International Year of Indigenous Languages"
65305
+ ]
65306
+ }
65307
+ },
65308
+ {
65309
+ id: "0jzN1GREMv0",
65310
+ url: "https://www.youtube.com/watch?v=0jzN1GREMv0",
65311
+ duration_seconds: 48,
65312
+ upload_date: "2025-02-21",
65313
+ license: "CC-BY-NC-4.0",
65314
+ content_type: "language_lesson",
65315
+ primary_language: {
65316
+ standards: {
65317
+ iso639_3: "gle",
65318
+ glottocode: "iris1253",
65319
+ bcp47: "ga"
65320
+ },
65321
+ speaker_claim: null,
65322
+ wikitongues_classification: "Irish",
65323
+ wikitongues_lineage: null,
65324
+ autonym: "Gaeilge"
65325
+ },
65326
+ additional_languages: [],
65327
+ speakers: [
65328
+ {
65329
+ name: "Ahmad",
65330
+ role: "second_language",
65331
+ origin: "Syria"
65332
+ }
65333
+ ],
65334
+ provenance: {
65335
+ country_code: null,
65336
+ country_name: null,
65337
+ region: null,
65338
+ city: null,
65339
+ recorded_by: "Wikitongues",
65340
+ recording_date: null
65341
+ },
65342
+ transcription: {
65343
+ has_subtitles: false,
65344
+ available_subtitles: [],
65345
+ native_text: null,
65346
+ english_translation: null
65347
+ },
65348
+ raw_metadata: {
65349
+ title: "Learn Irish with Ahmad | International Mother Language Day | Wikitongues",
65350
+ tags: [
65351
+ "Wikitongues",
65352
+ "IYIL2019",
65353
+ "2019 International Year of Indigenous Languages"
65354
+ ]
65355
+ }
65356
+ },
65357
+ {
65358
+ id: "7Se_-1IX2j4",
65359
+ url: "https://www.youtube.com/watch?v=7Se_-1IX2j4",
65360
+ duration_seconds: 71,
65361
+ upload_date: "2025-02-21",
65362
+ license: "CC-BY-NC-4.0",
65363
+ content_type: "language_lesson",
65364
+ primary_language: {
65365
+ standards: {
65366
+ iso639_3: "yor",
65367
+ glottocode: "yoru1245",
65368
+ bcp47: "yo"
65369
+ },
65370
+ speaker_claim: null,
65371
+ wikitongues_classification: "Yoruba",
65372
+ wikitongues_lineage: null,
65373
+ autonym: "\xC8d\xE8 Yor\xF9b\xE1"
65374
+ },
65375
+ additional_languages: [],
65376
+ speakers: [
65377
+ {
65378
+ name: "Hanifa",
65379
+ role: "native",
65380
+ origin: "Nigeria"
65381
+ }
65382
+ ],
65383
+ provenance: {
65384
+ country_code: "NG",
65385
+ country_name: "Nigeria",
65386
+ region: null,
65387
+ city: null,
65388
+ recorded_by: null,
65389
+ recording_date: null
65390
+ },
65391
+ transcription: {
65392
+ has_subtitles: false,
65393
+ available_subtitles: [],
65394
+ native_text: null,
65395
+ english_translation: null
65396
+ },
65397
+ raw_metadata: {
65398
+ title: "Yoruba with Hanifa | International Mother Language Day | Wikitongues",
65399
+ tags: [
65400
+ "Wikitongues",
65401
+ "IYIL2019",
65402
+ "2019 International Year of Indigenous Languages"
65403
+ ]
65404
+ }
65405
+ },
65406
+ {
65407
+ id: "rHVxTCtfqrw",
65408
+ url: "https://www.youtube.com/watch?v=rHVxTCtfqrw",
65409
+ duration_seconds: 96,
65410
+ upload_date: "2025-02-21",
65411
+ license: "CC-BY-NC-4.0",
65412
+ content_type: "language_lesson",
65413
+ primary_language: {
65414
+ standards: {
65415
+ iso639_3: "ibo",
65416
+ glottocode: "nucl1417",
65417
+ bcp47: "ig"
65418
+ },
65419
+ speaker_claim: null,
65420
+ wikitongues_classification: "Central Igbo",
65421
+ wikitongues_lineage: null,
65422
+ autonym: "As\u1EE5s\u1EE5 Igbo"
65423
+ },
65424
+ additional_languages: [],
65425
+ speakers: [
65426
+ {
65427
+ name: "Oluchukwu",
65428
+ role: "native",
65429
+ origin: "Nigeria"
65430
+ }
65431
+ ],
65432
+ provenance: {
65433
+ country_code: "NG",
65434
+ country_name: "Nigeria",
65435
+ region: null,
65436
+ city: null,
65437
+ recorded_by: null,
65438
+ recording_date: null
65439
+ },
65440
+ transcription: {
65441
+ has_subtitles: false,
65442
+ available_subtitles: [],
65443
+ native_text: null,
65444
+ english_translation: null
65445
+ },
65446
+ raw_metadata: {
65447
+ title: "Learn Central Igbo with Oluchukwu | International Mother Language Day | Wikitongues",
65448
+ tags: [
65449
+ "Wikitongues",
65450
+ "IYIL2019",
65451
+ "2019 International Year of Indigenous Languages"
65452
+ ]
65453
+ }
65454
+ },
65455
+ {
65456
+ id: "6i0neXrFZfg",
65457
+ url: "https://www.youtube.com/watch?v=6i0neXrFZfg",
65458
+ duration_seconds: 57,
65459
+ upload_date: "2025-02-21",
65460
+ license: "CC-BY-SA-4.0",
65461
+ content_type: "language_lesson",
65462
+ primary_language: {
65463
+ standards: {
65464
+ iso639_3: "kcg",
65465
+ glottocode: "tyap1238",
65466
+ bcp47: "kcg"
65467
+ },
65468
+ speaker_claim: null,
65469
+ wikitongues_classification: "Tyap",
65470
+ wikitongues_lineage: null,
65471
+ autonym: "Tyap"
65472
+ },
65473
+ additional_languages: [],
65474
+ speakers: [
65475
+ {
65476
+ name: "Kambai",
65477
+ role: "native",
65478
+ origin: "Nigeria"
65479
+ }
65480
+ ],
65481
+ provenance: {
65482
+ country_code: "NG",
65483
+ country_name: "Nigeria",
65484
+ region: null,
65485
+ city: null,
65486
+ recorded_by: null,
65487
+ recording_date: null
65488
+ },
65489
+ transcription: {
65490
+ has_subtitles: false,
65491
+ available_subtitles: [],
65492
+ native_text: null,
65493
+ english_translation: null
65494
+ },
65495
+ raw_metadata: {
65496
+ title: "Learn Tyap with Kambai | International Mother Language Day | Wikitongues",
65497
+ tags: [
65498
+ "Wikitongues",
65499
+ "IYIL2019",
65500
+ "2019 International Year of Indigenous Languages"
65501
+ ]
65502
+ }
65503
+ },
65504
+ {
65505
+ id: "B1Yu1EuUyUQ",
65506
+ url: "https://www.youtube.com/watch?v=B1Yu1EuUyUQ",
65507
+ duration_seconds: 42,
65508
+ upload_date: "2025-02-21",
65509
+ license: "CC-BY-SA-4.0",
65510
+ content_type: "language_lesson",
65511
+ primary_language: {
65512
+ standards: {
65513
+ iso639_3: "ind",
65514
+ glottocode: "stin1234",
65515
+ bcp47: "id"
65516
+ },
65517
+ speaker_claim: null,
65518
+ wikitongues_classification: "Bahasa Indonesia",
65519
+ wikitongues_lineage: null,
65520
+ autonym: "Bahasa Indonesia"
65521
+ },
65522
+ additional_languages: [],
65523
+ speakers: [
65524
+ {
65525
+ name: "Neysa",
65526
+ role: "native",
65527
+ origin: "Indonesia"
65528
+ }
65529
+ ],
65530
+ provenance: {
65531
+ country_code: "ID",
65532
+ country_name: "Indonesia",
65533
+ region: null,
65534
+ city: null,
65535
+ recorded_by: null,
65536
+ recording_date: null
65537
+ },
65538
+ transcription: {
65539
+ has_subtitles: false,
65540
+ available_subtitles: [],
65541
+ native_text: null,
65542
+ english_translation: null
65543
+ },
65544
+ raw_metadata: {
65545
+ title: "Learn Bahasa Indonesia with Neysa | International Mother Language Day | Wikitongues",
65546
+ tags: [
65547
+ "Wikitongues",
65548
+ "IYIL2019",
65549
+ "2019 International Year of Indigenous Languages"
65550
+ ]
65551
+ }
65552
+ },
65553
+ {
65554
+ id: "5WKzRb2_Tt0",
65555
+ url: "https://www.youtube.com/watch?v=5WKzRb2_Tt0",
65556
+ duration_seconds: 60,
65557
+ upload_date: "2025-02-21",
65558
+ license: "CC-BY-SA-4.0",
65559
+ content_type: "language_lesson",
65560
+ primary_language: {
65561
+ standards: {
65562
+ iso639_3: "ibo",
65563
+ glottocode: "ower1238",
65564
+ bcp47: "ig"
65565
+ },
65566
+ speaker_claim: null,
65567
+ wikitongues_classification: "Owerri Igbo",
65568
+ wikitongues_lineage: null,
65569
+ autonym: "As\u1EE5s\u1EE5 Igbo"
65570
+ },
65571
+ additional_languages: [],
65572
+ speakers: [
65573
+ {
65574
+ name: "Lucy",
65575
+ role: "native",
65576
+ origin: "Nigeria"
65577
+ }
65578
+ ],
65579
+ provenance: {
65580
+ country_code: "NG",
65581
+ country_name: "Nigeria",
65582
+ region: null,
65583
+ city: null,
65584
+ recorded_by: null,
65585
+ recording_date: null
65586
+ },
65587
+ transcription: {
65588
+ has_subtitles: false,
65589
+ available_subtitles: [],
65590
+ native_text: null,
65591
+ english_translation: null
65592
+ },
65593
+ raw_metadata: {
65594
+ title: "Learn Owerri Igbo with Lucy | International Mother Language Day | Wikitongues",
65595
+ tags: [
65596
+ "Wikitongues",
65597
+ "IYIL2019",
65598
+ "2019 International Year of Indigenous Languages"
65599
+ ]
65600
+ }
65601
+ },
65602
+ {
65603
+ id: "W4CM82mvMv8",
65604
+ url: "https://www.youtube.com/watch?v=W4CM82mvMv8",
65605
+ duration_seconds: 52,
65606
+ upload_date: "2025-02-21",
65607
+ license: "CC-BY-NC-4.0",
65608
+ content_type: "language_lesson",
65609
+ primary_language: {
65610
+ standards: {
65611
+ iso639_3: "fin",
65612
+ glottocode: "finn1318",
65613
+ bcp47: "fi"
65614
+ },
65615
+ speaker_claim: null,
65616
+ wikitongues_classification: "Finnish",
65617
+ wikitongues_lineage: null,
65618
+ autonym: "Suomi"
65619
+ },
65620
+ additional_languages: [],
65621
+ speakers: [
65622
+ {
65623
+ name: "Kristen",
65624
+ role: "second_language",
65625
+ origin: null
65626
+ }
65627
+ ],
65628
+ provenance: {
65629
+ country_code: null,
65630
+ country_name: null,
65631
+ region: null,
65632
+ city: null,
65633
+ recorded_by: "Wikitongues",
65634
+ recording_date: null
65635
+ },
65636
+ transcription: {
65637
+ has_subtitles: false,
65638
+ available_subtitles: [],
65639
+ native_text: null,
65640
+ english_translation: null
65641
+ },
65642
+ raw_metadata: {
65643
+ title: "Learn Finnish with Kristen | International Mother Language Day | Wikitongues",
65644
+ tags: [
65645
+ "Wikitongues",
65646
+ "IYIL2019",
65647
+ "2019 International Year of Indigenous Languages"
65648
+ ]
65649
+ }
65650
+ },
65651
+ {
65652
+ id: "l3F1h1XyXEY",
65653
+ url: "https://www.youtube.com/watch?v=l3F1h1XyXEY",
65654
+ duration_seconds: 60,
65655
+ upload_date: "2025-02-21",
65656
+ license: "CC-BY-SA-4.0",
65657
+ content_type: "language_lesson",
65658
+ primary_language: {
65659
+ standards: {
65660
+ iso639_3: "hau",
65661
+ glottocode: "haus1257",
65662
+ bcp47: "ha"
65663
+ },
65664
+ speaker_claim: null,
65665
+ wikitongues_classification: "Hausa",
65666
+ wikitongues_lineage: null,
65667
+ autonym: "Harshen Hausa"
65668
+ },
65669
+ additional_languages: [],
65670
+ speakers: [
65671
+ {
65672
+ name: "Sadam",
65673
+ role: "native",
65674
+ origin: "Nigeria"
65675
+ }
65676
+ ],
65677
+ provenance: {
65678
+ country_code: "NG",
65679
+ country_name: "Nigeria",
65680
+ region: null,
65681
+ city: null,
65682
+ recorded_by: null,
65683
+ recording_date: null
65684
+ },
65685
+ transcription: {
65686
+ has_subtitles: false,
65687
+ available_subtitles: [],
65688
+ native_text: null,
65689
+ english_translation: null
65690
+ },
65691
+ raw_metadata: {
65692
+ title: "Learn Hausa with Sadam | International Mother Language Day | Wikitongues",
65693
+ tags: [
65694
+ "Wikitongues",
65695
+ "IYIL2019",
65696
+ "2019 International Year of Indigenous Languages"
65697
+ ]
65698
+ }
65699
+ },
65700
+ {
65701
+ id: "yasjvWgLkqU",
65702
+ url: "https://www.youtube.com/watch?v=yasjvWgLkqU",
65703
+ duration_seconds: 60,
65704
+ upload_date: "2024-11-19",
65705
+ license: "ALL_RIGHTS_RESERVED",
65706
+ content_type: "meta",
65707
+ primary_language: {
65708
+ standards: {
65709
+ iso639_3: "eng",
65710
+ glottocode: "stan1293",
65711
+ bcp47: "en"
65712
+ },
65713
+ speaker_claim: null,
65714
+ wikitongues_classification: "English",
65715
+ wikitongues_lineage: null,
65716
+ autonym: "English"
65717
+ },
65718
+ additional_languages: [],
65719
+ speakers: [],
65720
+ provenance: {
65721
+ country_code: null,
65722
+ country_name: null,
65723
+ region: null,
65724
+ city: null,
65725
+ recorded_by: "Wikitongues",
65726
+ recording_date: null
65727
+ },
65728
+ transcription: {
65729
+ has_subtitles: false,
65730
+ available_subtitles: [],
65731
+ native_text: null,
65732
+ english_translation: null
65733
+ },
65734
+ raw_metadata: {
65735
+ title: "Discover N\xFCshu: The secret script created by women, for women!",
65736
+ tags: []
65737
+ }
65738
+ },
65739
+ {
65740
+ id: "5gZ7muELrXw",
65741
+ url: "https://www.youtube.com/watch?v=5gZ7muELrXw",
65742
+ duration_seconds: 1697,
65743
+ upload_date: "2022-11-05",
65744
+ license: "ALL_RIGHTS_RESERVED",
65745
+ content_type: "meta",
65746
+ primary_language: {
65747
+ standards: {
65748
+ iso639_3: "eng",
65749
+ glottocode: "stan1293",
65750
+ bcp47: "en"
65751
+ },
65752
+ speaker_claim: null,
65753
+ wikitongues_classification: "English",
65754
+ wikitongues_lineage: null,
65755
+ autonym: "English"
65756
+ },
65757
+ additional_languages: [],
65758
+ speakers: [],
65759
+ provenance: {
65760
+ country_code: null,
65761
+ country_name: null,
65762
+ region: null,
65763
+ city: null,
65764
+ recorded_by: "Wikitongues",
65765
+ recording_date: null
65766
+ },
65767
+ transcription: {
65768
+ has_subtitles: false,
65769
+ available_subtitles: [],
65770
+ native_text: null,
65771
+ english_translation: null
65772
+ },
65773
+ raw_metadata: {
65774
+ title: "Language Revitalization Accelerator Q&A",
65775
+ tags: []
65776
+ }
65777
+ },
65778
+ {
65779
+ id: "faidns4sK3Q",
65780
+ url: "https://www.youtube.com/watch?v=faidns4sK3Q",
65781
+ duration_seconds: 1611,
65782
+ upload_date: "2022-04-14",
65783
+ license: "ALL_RIGHTS_RESERVED",
65784
+ content_type: "meta",
65785
+ primary_language: {
65786
+ standards: {
65787
+ iso639_3: "eng",
65788
+ glottocode: "stan1293",
65789
+ bcp47: "en"
65790
+ },
65791
+ speaker_claim: null,
65792
+ wikitongues_classification: "English",
65793
+ wikitongues_lineage: null,
65794
+ autonym: "English"
65795
+ },
65796
+ additional_languages: [],
65797
+ speakers: [],
65798
+ provenance: {
65799
+ country_code: null,
65800
+ country_name: null,
65801
+ region: null,
65802
+ city: null,
65803
+ recorded_by: "Wikitongues",
65804
+ recording_date: null
65805
+ },
65806
+ transcription: {
65807
+ has_subtitles: false,
65808
+ available_subtitles: [],
65809
+ native_text: null,
65810
+ english_translation: null
65811
+ },
65812
+ raw_metadata: {
65813
+ title: "Announcing the 2022 grant recipients",
65814
+ tags: []
65815
+ }
65816
+ },
65817
+ {
65818
+ id: "6UctiHFsUrE",
65819
+ url: "https://www.youtube.com/watch?v=6UctiHFsUrE",
65820
+ duration_seconds: 3921,
65821
+ upload_date: "2020-11-11",
65822
+ license: "ALL_RIGHTS_RESERVED",
65823
+ content_type: "meta",
65824
+ primary_language: {
65825
+ standards: {
65826
+ iso639_3: "eng",
65827
+ glottocode: "stan1293",
65828
+ bcp47: "en"
65829
+ },
65830
+ speaker_claim: null,
65831
+ wikitongues_classification: "English",
65832
+ wikitongues_lineage: null,
65833
+ autonym: "English"
65834
+ },
65835
+ additional_languages: [],
65836
+ speakers: [
65837
+ {
65838
+ name: "Cordel Green",
65839
+ role: "fellow_activist",
65840
+ origin: "Jamaica"
65841
+ },
65842
+ {
65843
+ name: "Daniel Sikazwe",
65844
+ role: "fellow_activist",
65845
+ origin: "Zambia"
65846
+ }
65847
+ ],
65848
+ provenance: {
65849
+ country_code: null,
65850
+ country_name: null,
65851
+ region: null,
65852
+ city: null,
65853
+ recorded_by: "Wikitongues",
65854
+ recording_date: null
65855
+ },
65856
+ transcription: {
65857
+ has_subtitles: false,
65858
+ available_subtitles: [],
65859
+ native_text: null,
65860
+ english_translation: null
65861
+ },
65862
+ raw_metadata: {
65863
+ title: "Radio in Language Diversity | Conversations from Jamaica and Zambia | Wikitongues",
65864
+ tags: [
65865
+ "language diversity in media",
65866
+ "radio",
65867
+ "language diversity",
65868
+ "linguistic diversity",
65869
+ "language toolkit",
65870
+ "radio for language",
65871
+ "multilingual radio",
65872
+ "multilingual radio stations",
65873
+ "jamaica",
65874
+ "jamaican radio",
65875
+ "jamaican languages",
65876
+ "zambia",
65877
+ "zambian radio",
65878
+ "zambian languages",
65879
+ "language education",
65880
+ "jamaicain patois lessons",
65881
+ "radio jam upchurch",
65882
+ "speaking on the radio",
65883
+ "all walks of life",
65884
+ "sociolinguistics",
65885
+ "jamaican music",
65886
+ "jamaican patois lessons",
65887
+ "indigenous langauges",
65888
+ "how to promote language",
65889
+ "gullah",
65890
+ "wikitongues"
65891
+ ]
65892
+ }
65893
+ },
65894
+ {
65895
+ id: "iDPp2yORw94",
65896
+ url: "https://www.youtube.com/watch?v=iDPp2yORw94",
65897
+ duration_seconds: 4151,
65898
+ upload_date: "2020-10-11",
65899
+ license: "ALL_RIGHTS_RESERVED",
65900
+ content_type: "meta",
65901
+ primary_language: {
65902
+ standards: {
65903
+ iso639_3: "eng",
65904
+ glottocode: "stan1293",
65905
+ bcp47: "en"
65906
+ },
65907
+ speaker_claim: null,
65908
+ wikitongues_classification: "English",
65909
+ wikitongues_lineage: null,
65910
+ autonym: "English"
65911
+ },
65912
+ additional_languages: [],
65913
+ speakers: [
65914
+ {
65915
+ name: "Ryan Andrew Milov-Cordoba (Call Me C\xF3rdoba)",
65916
+ role: "fellow_activist",
65917
+ origin: "United States"
65918
+ }
65919
+ ],
65920
+ provenance: {
65921
+ country_code: null,
65922
+ country_name: null,
65923
+ region: null,
65924
+ city: null,
65925
+ recorded_by: "Wikitongues",
65926
+ recording_date: null
65927
+ },
65928
+ transcription: {
65929
+ has_subtitles: false,
65930
+ available_subtitles: [],
65931
+ native_text: null,
65932
+ english_translation: null
65933
+ },
65934
+ raw_metadata: {
65935
+ title: "Music in Language Diversity | Conversation and music with Call Me C\xF3rdoba | Wikitongues",
65936
+ tags: [
65937
+ "music in language diversity",
65938
+ "language diversity in education",
65939
+ "linguistic diversity",
65940
+ "indigenous peoples day",
65941
+ "call me cordoba",
65942
+ "arabic contemporary music",
65943
+ "Save my language",
65944
+ "global issues",
65945
+ "language learning",
65946
+ "language revitalization",
65947
+ "language preservation",
65948
+ "endangered languages",
65949
+ "endangered languages project",
65950
+ "Living Tongues Institute",
65951
+ "Wikitongues",
65952
+ "David Harrison",
65953
+ "Mother tongue",
65954
+ "Linguistics",
65955
+ "Indigenous languages",
65956
+ "arabic language learning",
65957
+ "\u0627\u0644\u062A\u0646\u0648\u0639 \u0627\u0644\u0644\u063A\u0648\u064A",
65958
+ "bahau"
65959
+ ]
65960
+ }
65961
+ },
65962
+ {
65963
+ id: "HaYhISDoVyM",
65964
+ url: "https://www.youtube.com/watch?v=HaYhISDoVyM",
65965
+ duration_seconds: 1576,
65966
+ upload_date: "2020-09-28",
65967
+ license: "ALL_RIGHTS_RESERVED",
65968
+ content_type: "meta",
65969
+ primary_language: {
65970
+ standards: {
65971
+ iso639_3: "eng",
65972
+ glottocode: "stan1293",
65973
+ bcp47: "en"
65974
+ },
65975
+ speaker_claim: null,
65976
+ wikitongues_classification: "English",
65977
+ wikitongues_lineage: null,
65978
+ autonym: "English"
65979
+ },
65980
+ additional_languages: [],
65981
+ speakers: [],
65982
+ provenance: {
65983
+ country_code: null,
65984
+ country_name: null,
65985
+ region: null,
65986
+ city: null,
65987
+ recorded_by: "Wikitongues",
65988
+ recording_date: null
65989
+ },
65990
+ transcription: {
65991
+ has_subtitles: false,
65992
+ available_subtitles: [],
65993
+ native_text: null,
65994
+ english_translation: null
65995
+ },
65996
+ raw_metadata: {
65997
+ title: "Wikitongues Updates, September 2020",
65998
+ tags: []
65999
+ }
66000
+ },
66001
+ {
66002
+ id: "2UmHjJvPGec",
66003
+ url: "https://www.youtube.com/watch?v=2UmHjJvPGec",
66004
+ duration_seconds: 10161,
66005
+ upload_date: "2020-08-02",
66006
+ license: "ALL_RIGHTS_RESERVED",
66007
+ content_type: "meta",
66008
+ primary_language: {
66009
+ standards: {
66010
+ iso639_3: "eng",
66011
+ glottocode: "stan1293",
66012
+ bcp47: "en"
66013
+ },
66014
+ speaker_claim: null,
66015
+ wikitongues_classification: "English",
66016
+ wikitongues_lineage: null,
66017
+ autonym: "English"
66018
+ },
66019
+ additional_languages: [],
66020
+ speakers: [],
66021
+ provenance: {
66022
+ country_code: null,
66023
+ country_name: null,
66024
+ region: null,
66025
+ city: null,
66026
+ recorded_by: "Wikitongues",
66027
+ recording_date: null
66028
+ },
66029
+ transcription: {
66030
+ has_subtitles: false,
66031
+ available_subtitles: [],
66032
+ native_text: null,
66033
+ english_translation: null
66034
+ },
66035
+ raw_metadata: {
66036
+ title: "Wikitongues Virtual Birthday Party",
66037
+ tags: [
66038
+ "birthday party",
66039
+ "birthday party coronavirus",
66040
+ "zoom university",
66041
+ "virtual birthday party",
66042
+ "Wikitongues",
66043
+ "wikitongues birthday party",
66044
+ "virtual birthday party ideas",
66045
+ "wikitongues virtual birthday party",
66046
+ "international coronavirus response",
66047
+ "how to have fun in pandemic",
66048
+ "everything is online now",
66049
+ "annual language celebration",
66050
+ "good things that came from coronavirus",
66051
+ "how to have fun when the world is ending",
66052
+ "New York",
66053
+ "eastern europe",
66054
+ "jakarta",
66055
+ "sociolinguistics",
66056
+ "language variation and change",
66057
+ "gullah"
66058
+ ]
66059
+ }
66060
+ },
66061
+ {
66062
+ id: "1UutaDfzaqc",
66063
+ url: "https://www.youtube.com/watch?v=1UutaDfzaqc",
66064
+ duration_seconds: 3906,
66065
+ upload_date: "2020-06-26",
66066
+ license: "ALL_RIGHTS_RESERVED",
66067
+ content_type: "meta",
66068
+ primary_language: {
66069
+ standards: {
66070
+ iso639_3: "eng",
66071
+ glottocode: "stan1293",
66072
+ bcp47: "en"
66073
+ },
66074
+ speaker_claim: null,
66075
+ wikitongues_classification: "English",
66076
+ wikitongues_lineage: null,
66077
+ autonym: "English"
66078
+ },
66079
+ additional_languages: [],
66080
+ speakers: [],
66081
+ provenance: {
66082
+ country_code: null,
66083
+ country_name: null,
66084
+ region: null,
66085
+ city: null,
66086
+ recorded_by: "Wikitongues",
66087
+ recording_date: null
66088
+ },
66089
+ transcription: {
66090
+ has_subtitles: false,
66091
+ available_subtitles: [],
66092
+ native_text: null,
66093
+ english_translation: null
66094
+ },
66095
+ raw_metadata: {
66096
+ title: "How do I save my language? Introducing the Language Sustainability Toolkit",
66097
+ tags: [
66098
+ "Save my language",
66099
+ "My language",
66100
+ "global issues",
66101
+ "Language",
66102
+ "language learning",
66103
+ "language learning apps",
66104
+ "language revitalization canada",
66105
+ "hawaiian language revitalization",
66106
+ "native american language revitalization",
66107
+ "ojibwe language revitalization",
66108
+ "language revitalization",
66109
+ "language preservation",
66110
+ "endangered languages",
66111
+ "endangered languages project",
66112
+ "Living Tongues Institute",
66113
+ "Wikitongues",
66114
+ "David Harrison",
66115
+ "Anna Luisa Daigneault",
66116
+ "Mother tongue",
66117
+ "Linguistics",
66118
+ "Indigenous languages",
66119
+ "Sustainability"
66120
+ ]
66121
+ }
66122
+ },
66123
+ {
66124
+ id: "pEU_EC7OcdE",
66125
+ url: "https://www.youtube.com/watch?v=pEU_EC7OcdE",
66126
+ duration_seconds: 3878,
66127
+ upload_date: "2020-06-24",
66128
+ license: "ALL_RIGHTS_RESERVED",
66129
+ content_type: "meta",
66130
+ primary_language: {
66131
+ standards: {
66132
+ iso639_3: "eng",
66133
+ glottocode: "stan1293",
66134
+ bcp47: "en"
66135
+ },
66136
+ speaker_claim: null,
66137
+ wikitongues_classification: "English",
66138
+ wikitongues_lineage: null,
66139
+ autonym: "English"
66140
+ },
66141
+ additional_languages: [],
66142
+ speakers: [
66143
+ {
66144
+ name: "Tim Brooks",
66145
+ role: "fellow_activist",
66146
+ origin: "United States"
66147
+ }
66148
+ ],
66149
+ provenance: {
66150
+ country_code: null,
66151
+ country_name: null,
66152
+ region: null,
66153
+ city: null,
66154
+ recorded_by: "Wikitongues",
66155
+ recording_date: null
66156
+ },
66157
+ transcription: {
66158
+ has_subtitles: false,
66159
+ available_subtitles: [],
66160
+ native_text: null,
66161
+ english_translation: null
66162
+ },
66163
+ raw_metadata: {
66164
+ title: "Tim Brooks from Endangered Alphabets | FIRST-EVER Wikitongues live-stream!",
66165
+ tags: [
66166
+ "Tim Brooks",
66167
+ "Endangered Alphabets",
66168
+ "Alphabets",
66169
+ "alphabet in spanish",
66170
+ "writing systems",
66171
+ "Writing systems of the world",
66172
+ "writing systems in europe",
66173
+ "Wikitongues",
66174
+ "sociolinguistics",
66175
+ "balinese language",
66176
+ "languages of the philippines",
66177
+ "Easter Island",
66178
+ "Rapa Nui",
66179
+ "rongorongo script",
66180
+ "rongorongo language",
66181
+ "semitic abjads alphabet",
66182
+ "Hebrew alphabet",
66183
+ "samaritans",
66184
+ "israel and palestine",
66185
+ "israel and philippines relationship",
66186
+ "Louisiana French",
66187
+ "english conversation",
66188
+ "british accent vs american accent",
66189
+ "Mongolian"
66190
+ ]
66191
+ }
66192
+ },
66193
+ {
66194
+ id: "pd0YZ9o22QI",
66195
+ url: "https://www.youtube.com/watch?v=pd0YZ9o22QI",
66196
+ duration_seconds: 33,
66197
+ upload_date: "2020-02-27",
66198
+ license: "CC-BY-NC-4.0",
66199
+ content_type: "oral_history",
66200
+ primary_language: {
66201
+ standards: {
66202
+ iso639_3: "kls",
66203
+ glottocode: "kala1372",
66204
+ bcp47: "kls"
66205
+ },
66206
+ speaker_claim: null,
66207
+ wikitongues_classification: "Kalasha",
66208
+ wikitongues_lineage: null,
66209
+ autonym: "Kalashamondr"
66210
+ },
66211
+ additional_languages: [],
66212
+ speakers: [
66213
+ {
66214
+ name: "Najib",
66215
+ role: "native",
66216
+ origin: "Pakistan"
66217
+ }
66218
+ ],
66219
+ provenance: {
66220
+ country_code: "PK",
66221
+ country_name: "Pakistan",
66222
+ region: "Khyber Pakhtunkhwa",
66223
+ city: "Chitral",
66224
+ recorded_by: "Rizwan Hussain",
66225
+ recording_date: null
66226
+ },
66227
+ transcription: {
66228
+ has_subtitles: false,
66229
+ available_subtitles: [],
66230
+ native_text: null,
66231
+ english_translation: null
66232
+ },
66233
+ raw_metadata: {
66234
+ title: "WIKITONGUES: Najib speaking Kalasha",
66235
+ tags: [
66236
+ "Wikitongues",
66237
+ "IYIL2019",
66238
+ "2019 International Year of Indigenous Languages",
66239
+ "Kalasha language",
66240
+ "Kalasha-mun",
66241
+ "Pakistan",
66242
+ "Pakistani people",
66243
+ "South Asian people",
66244
+ "Dardic languages"
66245
+ ]
66246
+ }
66247
+ },
66248
+ {
66249
+ id: "gUWkNeLUZsg",
66250
+ url: "https://www.youtube.com/watch?v=gUWkNeLUZsg",
66251
+ duration_seconds: 30,
66252
+ upload_date: "2020-02-16",
66253
+ license: "CC-BY-SA-4.0",
66254
+ content_type: "oral_history",
66255
+ primary_language: {
66256
+ standards: {
66257
+ iso639_3: "mlt",
66258
+ glottocode: "malt1254",
66259
+ bcp47: "mt"
66260
+ },
66261
+ speaker_claim: null,
66262
+ wikitongues_classification: "Maltese",
66263
+ wikitongues_lineage: null,
66264
+ autonym: "Malti"
66265
+ },
66266
+ additional_languages: [],
66267
+ speakers: [
66268
+ {
66269
+ name: "Keith",
66270
+ role: "native",
66271
+ origin: "Malta"
66272
+ }
66273
+ ],
66274
+ provenance: {
66275
+ country_code: "MT",
66276
+ country_name: "Malta",
66277
+ region: null,
66278
+ city: "Valletta",
66279
+ recorded_by: "Irena Dahl",
66280
+ recording_date: null
66281
+ },
66282
+ transcription: {
66283
+ has_subtitles: false,
66284
+ available_subtitles: [],
66285
+ native_text: null,
66286
+ english_translation: null
66287
+ },
66288
+ raw_metadata: {
66289
+ title: "WIKITONGUES: Keith speaking Maltese",
66290
+ tags: [
66291
+ "Wikitongues",
66292
+ "IYIL2019",
66293
+ "2019 International Year of Indigenous Languages",
66294
+ "Maltese",
66295
+ "Maltese language",
66296
+ "Maltese people",
66297
+ "Malta",
66298
+ "Semitic languages",
66299
+ "Arabic dialects",
66300
+ "European languages"
66301
+ ]
66302
+ }
66303
+ },
66304
+ {
66305
+ id: "gE11A0fmkR0",
66306
+ url: "https://www.youtube.com/watch?v=gE11A0fmkR0",
66307
+ duration_seconds: 21,
66308
+ upload_date: "2019-08-30",
66309
+ license: "CC-BY-SA-4.0",
66310
+ content_type: "oral_history",
66311
+ primary_language: {
66312
+ standards: {
66313
+ iso639_3: "alt",
66314
+ glottocode: "sout2694",
66315
+ bcp47: "alt"
66316
+ },
66317
+ speaker_claim: null,
66318
+ wikitongues_classification: "Altai",
66319
+ wikitongues_lineage: null,
66320
+ autonym: "\u0410\u043B\u0442\u0430\u0439 \u0442\u0438\u043B"
66321
+ },
66322
+ additional_languages: [],
66323
+ speakers: [
66324
+ {
66325
+ name: "Dmitry",
66326
+ role: "native",
66327
+ origin: "Russia"
66328
+ }
66329
+ ],
66330
+ provenance: {
66331
+ country_code: "RU",
66332
+ country_name: "Russia",
66333
+ region: "Altai Republic",
66334
+ city: null,
66335
+ recorded_by: "Archyn Termishev",
66336
+ recording_date: null
66337
+ },
66338
+ transcription: {
66339
+ has_subtitles: false,
66340
+ available_subtitles: [],
66341
+ native_text: null,
66342
+ english_translation: null
66343
+ },
66344
+ raw_metadata: {
66345
+ title: "WIKITONGUES: Dmitry speaking Altai",
66346
+ tags: [
66347
+ "Wikitongues",
66348
+ "IYIL2019",
66349
+ "2019 International Year of Indigenous Languages"
66350
+ ]
66351
+ }
66352
+ },
66353
+ {
66354
+ id: "TotFWZLrQAY",
66355
+ url: "https://www.youtube.com/watch?v=TotFWZLrQAY",
66356
+ duration_seconds: 55,
66357
+ upload_date: "2014-08-07",
66358
+ license: "ALL_RIGHTS_RESERVED",
66359
+ content_type: "oral_history",
66360
+ primary_language: {
66361
+ standards: {
66362
+ iso639_3: "epo",
66363
+ glottocode: "espe1235",
66364
+ bcp47: "eo"
66365
+ },
66366
+ speaker_claim: null,
66367
+ wikitongues_classification: "Esperanto",
66368
+ wikitongues_lineage: null,
66369
+ autonym: "Esperanto"
66370
+ },
66371
+ additional_languages: [],
66372
+ speakers: [
66373
+ {
66374
+ name: "Hilliard (Hiljardo)",
66375
+ role: "second_language",
66376
+ origin: "United States"
66377
+ }
66378
+ ],
66379
+ provenance: {
66380
+ country_code: "US",
66381
+ country_name: "United States",
66382
+ region: "Connecticut",
66383
+ city: null,
66384
+ recorded_by: null,
66385
+ recording_date: null
66386
+ },
66387
+ transcription: {
66388
+ has_subtitles: false,
66389
+ available_subtitles: [],
66390
+ native_text: "Saluton. Mia nomo estas Hiljardo, en Esperanto, kaj mi parolis Esperanton dum du monatoj. Mi havas dek kvar de jaroj. Mi lernis Esperanton por lerni pri aliaj kulturoj kaj aliaj popoloj. Esperanto helpas min multe. Mi ofte konversacias kun homoj de la mondo. Mi lo\u011Das en Konektikuto en Usono. Mi amas lerni pri lingvoj kaj historio. Mi anka\u016D parolas anglan lingvon, francan lingvon, rusan lingvon, nederlandan lingvon, kaj afrikanson. Mi amas lerni novajn lingvojn , \u0109ar \u011Di estas sana, kaj \u011Di estas bona ekzerco por la cerbo. Dankon por rigardi.",
66391
+ english_translation: 'Hi. Mi name is "Hiljardo" [Hilliard], in Esperanto, and I have spoken Esperanto for two months. I am fourteen years old. I learned Esperanto to learn about foreign cultures and foreign peoples. Esperanto helps me a lot. I often converse with people from the world. I live in Connecticut in the United States of America. I like to learn about languages and history. I also speak English, French, Russian, Dutch, and Afrikaans. I like to learn new languages, because it is healthy, and it is a good exercise for the brain. Thanks for watching.'
66392
+ },
66393
+ raw_metadata: {
66394
+ title: "WIKITONGUES: Hiljiardo speaking Esperanto",
66395
+ tags: [
66396
+ "Wikitongues",
66397
+ "Esperanto Language (Human Language)"
66398
+ ]
66399
+ }
66400
+ },
66401
+ {
66402
+ id: "--DnU743JLU",
66403
+ url: "https://www.youtube.com/watch?v=--DnU743JLU",
66404
+ duration_seconds: 40,
66405
+ upload_date: "2013-02-18",
66406
+ license: "ALL_RIGHTS_RESERVED",
66407
+ content_type: "oral_history",
66408
+ primary_language: {
66409
+ standards: {
66410
+ iso639_3: "nan",
66411
+ glottocode: "minn1241",
66412
+ bcp47: "nan-TW"
66413
+ },
66414
+ speaker_claim: null,
66415
+ wikitongues_classification: "Taiwanese Min Nan",
66416
+ wikitongues_lineage: null,
66417
+ autonym: "\u81FA\u7063\u8A71"
66418
+ },
66419
+ additional_languages: [],
66420
+ speakers: [
66421
+ {
66422
+ name: "Liang Cheng Chia (Sunny)",
66423
+ role: "native",
66424
+ origin: "Taiwan"
66425
+ }
66426
+ ],
66427
+ provenance: {
66428
+ country_code: "TW",
66429
+ country_name: "Taiwan",
66430
+ region: null,
66431
+ city: "Kaohsiung",
66432
+ recorded_by: null,
66433
+ recording_date: null
66434
+ },
66435
+ transcription: {
66436
+ has_subtitles: false,
66437
+ available_subtitles: [],
66438
+ native_text: null,
66439
+ english_translation: null
66440
+ },
66441
+ raw_metadata: {
66442
+ title: "WIKITONGUES: Sunny speaking Taiwanese Min Nan",
66443
+ tags: [
66444
+ "Taiwanese",
66445
+ "Hokkien",
66446
+ "Taiwan",
66447
+ "nation",
66448
+ "country",
66449
+ "Vietnam",
66450
+ "USA",
66451
+ "languages of Taiwan",
66452
+ "Min Nan",
66453
+ "Chinese"
66454
+ ]
66455
+ }
66456
+ }
66457
+ ];
66458
+
66459
+ // src/dataset.ts
66460
+ var dataset = wikitongues_normalized_default;
66461
+
66462
+ // src/client.ts
66463
+ var WikitonguesDB = class _WikitonguesDB {
66464
+ _videos = [];
66465
+ hydrator;
66466
+ resolver;
66467
+ index;
66468
+ searchEngine;
66469
+ /**
66470
+ * Loads and hydrates every record. Throws HydrationError on the first record whose
66471
+ * standards do not resolve against the reference tables (see CLASSIFICATION_RULES.md §3.1.1).
66472
+ */
66473
+ constructor(options) {
66474
+ this.hydrator = new ReferenceHydrator(options?.reference);
66475
+ this.resolver = new LanguageResolver();
66476
+ const rawRecords = options?.data || options?.records || dataset;
66477
+ for (const record of rawRecords) {
66478
+ const video = record instanceof Video ? record : Video.fromDict(record, this.hydrator);
66479
+ this._videos.push(video);
66480
+ for (const lang of video.allLanguages) {
66481
+ this.resolver.registerDatasetLanguage(lang);
66482
+ }
66483
+ }
66484
+ this.index = new DatasetIndex(this._videos);
66485
+ this.searchEngine = new SearchEngine(this._videos, this.resolver);
66486
+ }
66487
+ get length() {
66488
+ return this._videos.length;
66489
+ }
66490
+ // -------------------------------------------------------------------------
66491
+ // Static Factory Methods
66492
+ // -------------------------------------------------------------------------
66493
+ /**
66494
+ * Create a WikitonguesDB instance directly from an in-memory list of dicts or Videos.
66495
+ */
66496
+ static fromRecords(records) {
66497
+ return new _WikitonguesDB({ records });
66498
+ }
66499
+ /**
66500
+ * Create a WikitonguesDB instance from a JSON string or JSON array.
66501
+ */
66502
+ static fromJSON(json) {
66503
+ const data = typeof json === "string" ? JSON.parse(json) : json;
66504
+ return new _WikitonguesDB({ data });
66505
+ }
66506
+ /**
66507
+ * Create a WikitonguesDB instance from a JSON or JSONL file path (Node.js environments).
66508
+ */
66509
+ static fromFile(filepath) {
66510
+ try {
66511
+ const fs = __require("fs");
66512
+ const content = fs.readFileSync(filepath, "utf-8");
66513
+ const trimmed = content.trim();
66514
+ let records = [];
66515
+ if (trimmed.startsWith("[")) {
66516
+ records = JSON.parse(trimmed);
66517
+ } else {
66518
+ records = trimmed.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
66519
+ }
66520
+ return new _WikitonguesDB({ data: records });
66521
+ } catch (err) {
66522
+ throw new Error(`Failed to load dataset from file '${filepath}': ${err.message}`);
66523
+ }
66524
+ }
66525
+ // -------------------------------------------------------------------------
66526
+ // Direct Lookups (O(1))
66527
+ // -------------------------------------------------------------------------
66528
+ /**
66529
+ * Lookup a video by its YouTube ID in O(1) time.
66530
+ */
66531
+ get(videoId) {
66532
+ return this.index.byId.get(videoId.trim()) || null;
66533
+ }
66534
+ /**
66535
+ * Lookup videos matching a 3-letter SIL ISO 639-3 code in O(1) time.
66536
+ */
66537
+ getByIso(code) {
66538
+ const list = this.index.byIso.get(code.trim().toLowerCase());
66539
+ return new VideoCollection(list || []);
66540
+ }
66541
+ /**
66542
+ * Lookup videos matching a BCP 47 language tag in O(1) time.
66543
+ */
66544
+ getByBcp47(tag) {
66545
+ const list = this.index.byBcp47.get(tag.trim().toLowerCase());
66546
+ return new VideoCollection(list || []);
66547
+ }
66548
+ /**
66549
+ * Lookup videos matching a Glottolog code in O(1) time. A language node also matches videos
66550
+ * classified under one of its dialect nodes (e.g. `port1283` returns `braz1246` recordings).
66551
+ */
66552
+ getByGlottocode(glottocode) {
66553
+ const list = this.index.byGlottocode.get(glottocode.trim().toLowerCase());
66554
+ return new VideoCollection(list || []);
66555
+ }
66556
+ /**
66557
+ * Lookup videos matching an ISO 3166-1 alpha-2 code or country name in O(1) time.
66558
+ */
66559
+ getByCountry(countryCodeOrName) {
66560
+ const c = countryCodeOrName.trim();
66561
+ if (c.length === 2 && this.index.byCountryCode.has(c.toUpperCase())) {
66562
+ return new VideoCollection(this.index.byCountryCode.get(c.toUpperCase()) || []);
66563
+ }
66564
+ const normName = normalizeText(c);
66565
+ if (this.index.byCountryName.has(normName)) {
66566
+ return new VideoCollection(this.index.byCountryName.get(normName) || []);
66567
+ }
66568
+ return this.query().country(c).all();
66569
+ }
66570
+ /**
66571
+ * Lookup videos for a given speaker name.
66572
+ */
66573
+ getBySpeaker(name) {
66574
+ const normName = normalizeText(name);
66575
+ if (this.index.bySpeakerName.has(normName)) {
66576
+ return new VideoCollection(this.index.bySpeakerName.get(normName) || []);
66577
+ }
66578
+ return this.query().speaker({ name }).all();
66579
+ }
66580
+ // -------------------------------------------------------------------------
66581
+ // Smart Lookups & Shortcut Queries
66582
+ // -------------------------------------------------------------------------
66583
+ /**
66584
+ * Intelligent language search: resolves natural names, multilingual aliases ('russe'),
66585
+ * ISO 639-3 ('rus'), BCP 47 ('ru'), Glottocodes, autonyms ('Русский'), Wikitongues
66586
+ * classifications, Glottolog / ISO names and speaker claims.
66587
+ */
66588
+ findByLanguage(languageQuery, includeAdditional = true) {
66589
+ return this.query().language(languageQuery, includeAdditional).all();
66590
+ }
66591
+ /**
66592
+ * Check if the database contains any video matching the language query
66593
+ * (by ISO 639-3, ISO 639-1, BCP 47, macrolanguage, or name).
66594
+ */
66595
+ hasLanguage(query) {
66596
+ const qClean = query.trim().toLowerCase();
66597
+ if (this.index.byIso.has(qClean)) return true;
66598
+ if (this.index.byBcp47.has(qClean)) return true;
66599
+ return this.findByLanguage(query).length > 0;
64089
66600
  }
64090
66601
  /**
64091
66602
  * Shortcut method to filter videos by common criteria.