1 Commits

Author SHA1 Message Date
searxng-bot
c6707dc0b6 [data] update searx.data - update_engine_traits.py 2026-06-29 00:44:13 +00:00
18 changed files with 4549 additions and 7381 deletions

View File

@@ -23,6 +23,6 @@ coloredlogs==15.0.1
docutils>=0.21.2;python_version <= "3.11" docutils>=0.21.2;python_version <= "3.11"
docutils>=0.22.4; python_version > "3.11" docutils>=0.22.4; python_version > "3.11"
parameterized==0.9.0 parameterized==0.9.0
granian[reload]==2.7.7 granian[reload]==2.7.6
basedpyright==1.39.8 basedpyright==1.39.8
types-lxml==2026.2.16 types-lxml==2026.2.16

View File

@@ -1,2 +1,2 @@
granian==2.7.7 granian==2.7.6
granian[pname]==2.7.7 granian[pname]==2.7.6

File diff suppressed because it is too large Load Diff

View File

@@ -773,7 +773,7 @@
"nl": "Boliviaanse boliviano", "nl": "Boliviaanse boliviano",
"oc": "Boliviano", "oc": "Boliviano",
"pa": "ਬੋਲੀਵੀਆਨੋ", "pa": "ਬੋਲੀਵੀਆਨੋ",
"pl": "boliwiano", "pl": "boliviano",
"pt": "Boliviano", "pt": "Boliviano",
"ro": "boliviano", "ro": "boliviano",
"ru": "боливиано", "ru": "боливиано",
@@ -1107,7 +1107,7 @@
"fi": "Kongon frangi", "fi": "Kongon frangi",
"fr": "franc congolais", "fr": "franc congolais",
"ga": "franc an Chongó", "ga": "franc an Chongó",
"gl": "franco congolés", "gl": "Franco congolés",
"he": "פרנק קונגולזי", "he": "פרנק קונגולזי",
"hr": "Kongoanski franak", "hr": "Kongoanski franak",
"hu": "kongói frank", "hu": "kongói frank",
@@ -1636,7 +1636,7 @@
"fi": "Algerian dinaari", "fi": "Algerian dinaari",
"fr": "dinar algérien", "fr": "dinar algérien",
"ga": "dinar na hAilgéire", "ga": "dinar na hAilgéire",
"gl": "dinar alxeriano", "gl": "Dinar alxeriano",
"he": "דינר אלג'ירי", "he": "דינר אלג'ירי",
"hr": "Alžirski dinar", "hr": "Alžirski dinar",
"hu": "algériai dinár", "hu": "algériai dinár",
@@ -1651,7 +1651,7 @@
"pap": "dinar argelino", "pap": "dinar argelino",
"pl": "dinar algierski", "pl": "dinar algierski",
"pt": "dinar argelino", "pt": "dinar argelino",
"ro": "dinar algerian", "ro": "Dinar algerian",
"ru": "алжирский динар", "ru": "алжирский динар",
"sk": "Alžírský dinár", "sk": "Alžírský dinár",
"sl": "alžirski dinar", "sl": "alžirski dinar",
@@ -1786,7 +1786,7 @@
"cy": "Ewro", "cy": "Ewro",
"da": "Euro", "da": "Euro",
"de": "Euro", "de": "Euro",
"en": "euro", "en": "Euro",
"eo": "eŭro", "eo": "eŭro",
"es": "Euro", "es": "Euro",
"et": "Euro", "et": "Euro",
@@ -1803,7 +1803,7 @@
"it": "Euro", "it": "Euro",
"ja": "ユーロ", "ja": "ユーロ",
"ko": "유로", "ko": "유로",
"lt": "euras", "lt": "Euras",
"lv": "eiro", "lv": "eiro",
"ml": "യൂറോ", "ml": "യൂറോ",
"ms": "Euro", "ms": "Euro",
@@ -2759,7 +2759,7 @@
"pa": "ਜਪਾਨੀ ਯੈੱਨ", "pa": "ਜਪਾਨੀ ਯੈੱਨ",
"pl": "jen", "pl": "jen",
"pt": "iene", "pt": "iene",
"ro": "yen", "ro": "yeni",
"ru": "японская иена", "ru": "японская иена",
"sk": "jen", "sk": "jen",
"sl": "japonski jen", "sl": "japonski jen",
@@ -3337,7 +3337,6 @@
"fi": "Libyan dinaari", "fi": "Libyan dinaari",
"fr": "dinar libyen", "fr": "dinar libyen",
"ga": "dinar na Libia", "ga": "dinar na Libia",
"gl": "dinar libio",
"he": "דינר לובי ", "he": "דינר לובי ",
"hr": "Libijski dinar", "hr": "Libijski dinar",
"hu": "líbiai dinár", "hu": "líbiai dinár",
@@ -3540,7 +3539,6 @@
"ja": "チャット", "ja": "チャット",
"ko": "미얀마 짯", "ko": "미얀마 짯",
"lt": "Kijatas", "lt": "Kijatas",
"lv": "Kjats",
"ml": "ബർമ്മീസ് ക്യാറ്റ്", "ml": "ബർമ്മീസ് ക്യാറ്റ്",
"nl": "Myanmarese kyat", "nl": "Myanmarese kyat",
"oc": "Kyat", "oc": "Kyat",
@@ -4312,7 +4310,7 @@
"ar": "بيسو فلبيني", "ar": "بيسو فلبيني",
"bg": "Филипинско песо", "bg": "Филипинско песо",
"ca": "peso filipí", "ca": "peso filipí",
"cs": "filipínské peso", "cs": "Filipínské peso",
"de": "philippinischer Peso", "de": "philippinischer Peso",
"en": "Philippine peso", "en": "Philippine peso",
"eo": "filipina peso", "eo": "filipina peso",
@@ -4616,7 +4614,7 @@
"fi": "Serbian dinaari", "fi": "Serbian dinaari",
"fr": "dinar serbe", "fr": "dinar serbe",
"ga": "Dinar na Seirbia", "ga": "Dinar na Seirbia",
"gl": "dinar serbio", "gl": "Dinar serbio",
"he": "דינר סרבי", "he": "דינר סרבי",
"hr": "srpski dinar", "hr": "srpski dinar",
"hu": "szerb dinár", "hu": "szerb dinár",
@@ -5333,7 +5331,7 @@
"pa": "ਤਾਜਿਕਿਸਤਾਨੀ ਸੋਮੋਨੀ", "pa": "ਤਾਜਿਕਿਸਤਾਨੀ ਸੋਮੋਨੀ",
"pl": "Somoni", "pl": "Somoni",
"pt": "Somoni", "pt": "Somoni",
"ro": "somoni tadjic", "ro": "Somoni tadjic",
"ru": "таджикский сомони", "ru": "таджикский сомони",
"sk": "tadžický som", "sk": "tadžický som",
"sl": "tadžikistanski somoni", "sl": "tadžikistanski somoni",
@@ -5396,7 +5394,6 @@
"fi": "Tunisian dinaari", "fi": "Tunisian dinaari",
"fr": "dinar tunisien", "fr": "dinar tunisien",
"ga": "dinar na Túinéise", "ga": "dinar na Túinéise",
"gl": "dinar tunisiano",
"he": "דינר תוניסאי", "he": "דינר תוניסאי",
"hr": "tuniski dinar", "hr": "tuniski dinar",
"hu": "tunéziai dinár", "hu": "tunéziai dinár",
@@ -5769,7 +5766,7 @@
"fi": "Uruguayn peso", "fi": "Uruguayn peso",
"fr": "peso uruguayen", "fr": "peso uruguayen",
"ga": "peso Uragua", "ga": "peso Uragua",
"gl": "peso uruguaio", "gl": "Peso uruguaio",
"he": "פסו של אורוגוואי", "he": "פסו של אורוגוואי",
"hr": "Urugvajski pezo", "hr": "Urugvajski pezo",
"hu": "uruguayi peso", "hu": "uruguayi peso",
@@ -6150,7 +6147,7 @@
"oc": "Drechs de tiratge Especials", "oc": "Drechs de tiratge Especials",
"pl": "specjalne prawa ciągnienia", "pl": "specjalne prawa ciągnienia",
"pt": "direitos especiais de saque", "pt": "direitos especiais de saque",
"ro": "drepturi speciale de tragere", "ro": "Drepturi speciale de tragere",
"ru": "специальные права заимствования", "ru": "специальные права заимствования",
"sk": "Zvláštne práva čerpania", "sk": "Zvláštne práva čerpania",
"sl": "posebne pravice črpanja", "sl": "posebne pravice črpanja",
@@ -6228,7 +6225,6 @@
"ja": "CFPフラン", "ja": "CFPフラン",
"ko": "CFP 프랑", "ko": "CFP 프랑",
"lt": "CFP frankas", "lt": "CFP frankas",
"lv": "Klusā okeāna franks",
"ms": "Franc CFP", "ms": "Franc CFP",
"nl": "CFP-frank", "nl": "CFP-frank",
"oc": "Franc CFP", "oc": "Franc CFP",
@@ -7059,7 +7055,6 @@
"bolivjano": "BOB", "bolivjano": "BOB",
"bolivya bolivianosu": "BOB", "bolivya bolivianosu": "BOB",
"bolivya bolivyanosu": "BOB", "bolivya bolivyanosu": "BOB",
"boliwiano": "BOB",
"bolívar digital": "VED", "bolívar digital": "VED",
"bolívar soberano": "VES", "bolívar soberano": "VES",
"bolívar sobirà": "VES", "bolívar sobirà": "VES",
@@ -8430,7 +8425,6 @@
"drame arménio": "AMD", "drame arménio": "AMD",
"dramm": "AMD", "dramm": "AMD",
"drechs de tiratge especials": "XDR", "drechs de tiratge especials": "XDR",
"drept special de tragere": "XDR",
"drepturi speciale de tragere": "XDR", "drepturi speciale de tragere": "XDR",
"drets especials de gir": "XDR", "drets especials de gir": "XDR",
"droits de tirage speciaux": "XDR", "droits de tirage speciaux": "XDR",
@@ -9524,8 +9518,6 @@
"kíp lào": "LAK", "kíp lào": "LAK",
"kīp": "LAK", "kīp": "LAK",
"kjat": "MMK", "kjat": "MMK",
"kjats": "MMK",
"klusā okeāna franks": "XPF",
"km": "BAM", "km": "BAM",
"kmf": "KMF", "kmf": "KMF",
"koeweitse dinar": "KWD", "koeweitse dinar": "KWD",
@@ -10031,7 +10023,6 @@
"lire sterline": "GBP", "lire sterline": "GBP",
"lire turque": "TRY", "lire turque": "TRY",
"lisente": "LSL", "lisente": "LSL",
"list of syrian coins": "SYP",
"liura de gibartar": "GIP", "liura de gibartar": "GIP",
"liura egipciana": "EGP", "liura egipciana": "EGP",
"liura esterlina": "GBP", "liura esterlina": "GBP",
@@ -11322,6 +11313,7 @@
"riel camboxano": "KHR", "riel camboxano": "KHR",
"riel camboyano": "KHR", "riel camboyano": "KHR",
"riel campuchia": "KHR", "riel campuchia": "KHR",
"riel kambodżański": "KHR",
"riel kamboja": "KHR", "riel kamboja": "KHR",
"riel na cambóide": "KHR", "riel na cambóide": "KHR",
"rietumāfrikas franks": "XOF", "rietumāfrikas franks": "XOF",
@@ -12265,7 +12257,6 @@
"thaise baht": "THB", "thaise baht": "THB",
"thajský baht": "THB", "thajský baht": "THB",
"thb": "THB", "thb": "THB",
"the australian dollar": "AUD",
"thebe": "BWP", "thebe": "BWP",
"third belarusian ruble": "BYN", "third belarusian ruble": "BYN",
"tical": "THB", "tical": "THB",
@@ -12749,7 +12740,6 @@
"yen": "JPY", "yen": "JPY",
"yen giapponese": "JPY", "yen giapponese": "JPY",
"yen japones": "JPY", "yen japones": "JPY",
"yen japonez": "JPY",
"yen japonés": "JPY", "yen japonés": "JPY",
"yeni": "JPY", "yeni": "JPY",
"yeni i̇srail şekeli": "ILS", "yeni i̇srail şekeli": "ILS",
@@ -12816,6 +12806,7 @@
"zimbabwe zig": "ZWG", "zimbabwe zig": "ZWG",
"zimbabwean dollar": "ZWL", "zimbabwean dollar": "ZWL",
"zimbabwean gold": "ZWG", "zimbabwean gold": "ZWG",
"zimbabwean zig": "ZWG",
"zimbabwen kulta": "ZWG", "zimbabwen kulta": "ZWG",
"zimbabwiansky zlatý": "ZWG", "zimbabwiansky zlatý": "ZWG",
"zimbabwský dolar": "ZWL", "zimbabwský dolar": "ZWL",
@@ -12974,7 +12965,6 @@
"FKP", "FKP",
"EGP" "EGP"
], ],
"£S": "SYP",
"£e": "EGP", "£e": "EGP",
"£s": "SYP", "£s": "SYP",
"¥": [ "¥": [
@@ -14969,8 +14959,6 @@
"فورنت مجري": "HUF", "فورنت مجري": "HUF",
"فورينت مجري": "HUF", "فورينت مجري": "HUF",
"فِرَنْكٌ رُوَنْدِيٌّ": "RWF", "فِرَنْكٌ رُوَنْدِيٌّ": "RWF",
"قائمة النقود المعدنية السورية": "SYP",
"قائمة عملات سوريا المعدنية": "SYP",
"ك": "KWD", "ك": "KWD",
"كتزال غواتيمالي": "GTQ", "كتزال غواتيمالي": "GTQ",
"كرونة آيسلندية": "ISK", "كرونة آيسلندية": "ISK",

View File

@@ -6544,103 +6544,6 @@
"to-TO": "to" "to-TO": "to"
} }
}, },
"neosearch": {
"all_locale": null,
"custom": {
"countrycodes": [
"AE",
"AM",
"AR",
"AT",
"AU",
"AZ",
"BE",
"BG",
"BH",
"BO",
"BR",
"BY",
"CA",
"CH",
"CL",
"CN",
"CO",
"CY",
"CZ",
"DE",
"DK",
"DZ",
"EC",
"EE",
"EG",
"ES",
"FI",
"FR",
"GB",
"GE",
"GH",
"GR",
"HK",
"HR",
"HU",
"ID",
"IE",
"IL",
"IN",
"IT",
"JO",
"JP",
"KE",
"KG",
"KR",
"KW",
"KZ",
"LB",
"LT",
"LU",
"LV",
"MA",
"MD",
"MT",
"MX",
"MY",
"NG",
"NL",
"NO",
"NZ",
"OM",
"PE",
"PH",
"PL",
"PT",
"PY",
"QA",
"RO",
"RU",
"SA",
"SE",
"SG",
"SI",
"SK",
"TH",
"TJ",
"TM",
"TN",
"TR",
"TW",
"UA",
"US",
"UY",
"UZ",
"VE",
"VN",
"ZA"
]
},
"data_type": "traits_v1",
"languages": {},
"regions": {}
},
"odysee": { "odysee": {
"all_locale": null, "all_locale": null,
"custom": {}, "custom": {},
@@ -7262,6 +7165,7 @@
"IR", "IR",
"IS", "IS",
"IT", "IT",
"JE",
"JM", "JM",
"JO", "JO",
"JP", "JP",
@@ -7291,6 +7195,7 @@
"MC", "MC",
"MD", "MD",
"ME", "ME",
"MF",
"MG", "MG",
"MH", "MH",
"MK", "MK",
@@ -7357,6 +7262,7 @@
"SS", "SS",
"ST", "ST",
"SV", "SV",
"SX",
"SY", "SY",
"SZ", "SZ",
"TC", "TC",
@@ -7504,6 +7410,7 @@
"th": "thai", "th": "thai",
"ti": "tigrinya", "ti": "tigrinya",
"tk": "turkmen", "tk": "turkmen",
"to": "tonga",
"tr": "turkish", "tr": "turkish",
"tt": "tatar", "tt": "tatar",
"uk": "ukrainian", "uk": "ukrainian",
@@ -7784,460 +7691,22 @@
"all_locale": null, "all_locale": null,
"custom": {}, "custom": {},
"data_type": "traits_v1", "data_type": "traits_v1",
"languages": { "languages": {},
"af": "afrikaans", "regions": {}
"am": "amharic",
"ar": "arabic",
"az": "azerbaijani",
"be": "belarusian",
"bg": "bulgarian",
"bn": "bengali",
"bs": "bosnian",
"ca": "catalan",
"cs": "czech",
"cy": "welsh",
"da": "dansk",
"de": "deutsch",
"el": "greek",
"en": "english",
"eo": "esperanto",
"es": "espanol",
"et": "estonian",
"eu": "basque",
"fa": "persian",
"fi": "suomi",
"fo": "faroese",
"fr": "francais",
"fy": "frisian",
"ga": "irish",
"gd": "gaelic",
"gl": "galician",
"gu": "gujarati",
"he": "hebrew",
"hi": "hindi",
"hr": "croatian",
"hu": "hungarian",
"ia": "interlingua",
"id": "indonesian",
"is": "icelandic",
"it": "italiano",
"ja": "nihongo",
"jv": "javanese",
"ka": "georgian",
"kn": "kannada",
"ko": "hangul",
"la": "latin",
"lt": "lithuanian",
"lv": "latvian",
"mai": "bihari",
"mk": "macedonian",
"ml": "malayalam",
"mr": "marathi",
"ms": "malay",
"mt": "maltese",
"nb": "norsk",
"ne": "nepali",
"nl": "nederlands",
"oc": "occitan",
"pa": "punjabi",
"pl": "polski",
"pt": "portugues",
"pt_BR": "brazilian",
"ro": "romanian",
"ru": "russian",
"si": "sinhalese",
"sk": "slovak",
"sl": "slovenian",
"sq": "albanian",
"sr": "serbian",
"su": "sudanese",
"sv": "svenska",
"sw": "swahili",
"ta": "tamil",
"te": "telugu",
"th": "thai",
"ti": "tigrinya",
"tl": "tagalog",
"tr": "turkce",
"uk": "ukrainian",
"ur": "urdu",
"uz": "uzbek",
"vi": "vietnamese",
"xh": "xhosa",
"zh": "jiantizhongwen",
"zh_Hant": "fantizhengwen",
"zu": "zulu"
},
"regions": {
"ar-EG": "ar_EG",
"bg-BG": "bg_BG",
"ca-ES": "ca_ES",
"cs-CZ": "cs_CZ",
"da-DK": "da_DK",
"de-AT": "de_AT",
"de-CH": "de_CH",
"de-DE": "de_DE",
"el-GR": "el_GR",
"en-AU": "en_AU",
"en-CA": "en_CA",
"en-GB": "en-GB_GB",
"en-ID": "en_ID",
"en-IE": "en_IE",
"en-IN": "en_IN",
"en-MY": "en_MY",
"en-NZ": "en_NZ",
"en-PH": "en_PH",
"en-SG": "en_SG",
"en-US": "en_US",
"en-ZA": "en_ZA",
"es-AR": "es_AR",
"es-CL": "es_CL",
"es-CO": "es_CO",
"es-ES": "es_ES",
"es-MX": "es_MX",
"es-PE": "es_PE",
"es-US": "es_US",
"es-UY": "es_UY",
"es-VE": "es_VE",
"et-EE": "et_EE",
"fi-FI": "fi_FI",
"fil-PH": "fil_PH",
"fr-BE": "fr_BE",
"fr-CA": "fr_CA",
"fr-CH": "fr_CH",
"fr-FR": "fr_FR",
"hi-IN": "hi_IN",
"hu-HU": "hu_HU",
"id-ID": "id_ID",
"it-CH": "it_CH",
"it-IT": "it_IT",
"ja-JP": "ja_JP",
"ko-KR": "ko_KR",
"ms-MY": "ms_MY",
"ms-SG": "ms_SG",
"nb-NO": "no_NO",
"nl-BE": "nl_BE",
"nl-NL": "nl_NL",
"pl-PL": "pl_PL",
"pt-BR": "pt-BR_BR",
"pt-PT": "pt_PT",
"ro-RO": "ro_RO",
"ru-BY": "ru_BY",
"ru-RU": "ru_RU",
"sv-SE": "sv_SE",
"tr-TR": "tr_TR",
"uk-UA": "uk_UA",
"vi-VN": "vi_VN",
"zh-CN": "zh-CN_CN",
"zh-HK": "zh-TW_HK",
"zh-TW": "zh-TW_TW"
}
}, },
"startpage images": { "startpage images": {
"all_locale": null, "all_locale": null,
"custom": {}, "custom": {},
"data_type": "traits_v1", "data_type": "traits_v1",
"languages": { "languages": {},
"af": "afrikaans", "regions": {}
"am": "amharic",
"ar": "arabic",
"az": "azerbaijani",
"be": "belarusian",
"bg": "bulgarian",
"bn": "bengali",
"bs": "bosnian",
"ca": "catalan",
"cs": "czech",
"cy": "welsh",
"da": "dansk",
"de": "deutsch",
"el": "greek",
"en": "english",
"eo": "esperanto",
"es": "espanol",
"et": "estonian",
"eu": "basque",
"fa": "persian",
"fi": "suomi",
"fo": "faroese",
"fr": "francais",
"fy": "frisian",
"ga": "irish",
"gd": "gaelic",
"gl": "galician",
"gu": "gujarati",
"he": "hebrew",
"hi": "hindi",
"hr": "croatian",
"hu": "hungarian",
"ia": "interlingua",
"id": "indonesian",
"is": "icelandic",
"it": "italiano",
"ja": "nihongo",
"jv": "javanese",
"ka": "georgian",
"kn": "kannada",
"ko": "hangul",
"la": "latin",
"lt": "lithuanian",
"lv": "latvian",
"mai": "bihari",
"mk": "macedonian",
"ml": "malayalam",
"mr": "marathi",
"ms": "malay",
"mt": "maltese",
"nb": "norsk",
"ne": "nepali",
"nl": "nederlands",
"oc": "occitan",
"pa": "punjabi",
"pl": "polski",
"pt": "portugues",
"pt_BR": "brazilian",
"ro": "romanian",
"ru": "russian",
"si": "sinhalese",
"sk": "slovak",
"sl": "slovenian",
"sq": "albanian",
"sr": "serbian",
"su": "sudanese",
"sv": "svenska",
"sw": "swahili",
"ta": "tamil",
"te": "telugu",
"th": "thai",
"ti": "tigrinya",
"tl": "tagalog",
"tr": "turkce",
"uk": "ukrainian",
"ur": "urdu",
"uz": "uzbek",
"vi": "vietnamese",
"xh": "xhosa",
"zh": "jiantizhongwen",
"zh_Hant": "fantizhengwen",
"zu": "zulu"
},
"regions": {
"ar-EG": "ar_EG",
"bg-BG": "bg_BG",
"ca-ES": "ca_ES",
"cs-CZ": "cs_CZ",
"da-DK": "da_DK",
"de-AT": "de_AT",
"de-CH": "de_CH",
"de-DE": "de_DE",
"el-GR": "el_GR",
"en-AU": "en_AU",
"en-CA": "en_CA",
"en-GB": "en-GB_GB",
"en-ID": "en_ID",
"en-IE": "en_IE",
"en-IN": "en_IN",
"en-MY": "en_MY",
"en-NZ": "en_NZ",
"en-PH": "en_PH",
"en-SG": "en_SG",
"en-US": "en_US",
"en-ZA": "en_ZA",
"es-AR": "es_AR",
"es-CL": "es_CL",
"es-CO": "es_CO",
"es-ES": "es_ES",
"es-MX": "es_MX",
"es-PE": "es_PE",
"es-US": "es_US",
"es-UY": "es_UY",
"es-VE": "es_VE",
"et-EE": "et_EE",
"fi-FI": "fi_FI",
"fil-PH": "fil_PH",
"fr-BE": "fr_BE",
"fr-CA": "fr_CA",
"fr-CH": "fr_CH",
"fr-FR": "fr_FR",
"hi-IN": "hi_IN",
"hu-HU": "hu_HU",
"id-ID": "id_ID",
"it-CH": "it_CH",
"it-IT": "it_IT",
"ja-JP": "ja_JP",
"ko-KR": "ko_KR",
"ms-MY": "ms_MY",
"ms-SG": "ms_SG",
"nb-NO": "no_NO",
"nl-BE": "nl_BE",
"nl-NL": "nl_NL",
"pl-PL": "pl_PL",
"pt-BR": "pt-BR_BR",
"pt-PT": "pt_PT",
"ro-RO": "ro_RO",
"ru-BY": "ru_BY",
"ru-RU": "ru_RU",
"sv-SE": "sv_SE",
"tr-TR": "tr_TR",
"uk-UA": "uk_UA",
"vi-VN": "vi_VN",
"zh-CN": "zh-CN_CN",
"zh-HK": "zh-TW_HK",
"zh-TW": "zh-TW_TW"
}
}, },
"startpage news": { "startpage news": {
"all_locale": null, "all_locale": null,
"custom": {}, "custom": {},
"data_type": "traits_v1", "data_type": "traits_v1",
"languages": { "languages": {},
"af": "afrikaans", "regions": {}
"am": "amharic",
"ar": "arabic",
"az": "azerbaijani",
"be": "belarusian",
"bg": "bulgarian",
"bn": "bengali",
"bs": "bosnian",
"ca": "catalan",
"cs": "czech",
"cy": "welsh",
"da": "dansk",
"de": "deutsch",
"el": "greek",
"en": "english",
"eo": "esperanto",
"es": "espanol",
"et": "estonian",
"eu": "basque",
"fa": "persian",
"fi": "suomi",
"fo": "faroese",
"fr": "francais",
"fy": "frisian",
"ga": "irish",
"gd": "gaelic",
"gl": "galician",
"gu": "gujarati",
"he": "hebrew",
"hi": "hindi",
"hr": "croatian",
"hu": "hungarian",
"ia": "interlingua",
"id": "indonesian",
"is": "icelandic",
"it": "italiano",
"ja": "nihongo",
"jv": "javanese",
"ka": "georgian",
"kn": "kannada",
"ko": "hangul",
"la": "latin",
"lt": "lithuanian",
"lv": "latvian",
"mai": "bihari",
"mk": "macedonian",
"ml": "malayalam",
"mr": "marathi",
"ms": "malay",
"mt": "maltese",
"nb": "norsk",
"ne": "nepali",
"nl": "nederlands",
"oc": "occitan",
"pa": "punjabi",
"pl": "polski",
"pt": "portugues",
"pt_BR": "brazilian",
"ro": "romanian",
"ru": "russian",
"si": "sinhalese",
"sk": "slovak",
"sl": "slovenian",
"sq": "albanian",
"sr": "serbian",
"su": "sudanese",
"sv": "svenska",
"sw": "swahili",
"ta": "tamil",
"te": "telugu",
"th": "thai",
"ti": "tigrinya",
"tl": "tagalog",
"tr": "turkce",
"uk": "ukrainian",
"ur": "urdu",
"uz": "uzbek",
"vi": "vietnamese",
"xh": "xhosa",
"zh": "jiantizhongwen",
"zh_Hant": "fantizhengwen",
"zu": "zulu"
},
"regions": {
"ar-EG": "ar_EG",
"bg-BG": "bg_BG",
"ca-ES": "ca_ES",
"cs-CZ": "cs_CZ",
"da-DK": "da_DK",
"de-AT": "de_AT",
"de-CH": "de_CH",
"de-DE": "de_DE",
"el-GR": "el_GR",
"en-AU": "en_AU",
"en-CA": "en_CA",
"en-GB": "en-GB_GB",
"en-ID": "en_ID",
"en-IE": "en_IE",
"en-IN": "en_IN",
"en-MY": "en_MY",
"en-NZ": "en_NZ",
"en-PH": "en_PH",
"en-SG": "en_SG",
"en-US": "en_US",
"en-ZA": "en_ZA",
"es-AR": "es_AR",
"es-CL": "es_CL",
"es-CO": "es_CO",
"es-ES": "es_ES",
"es-MX": "es_MX",
"es-PE": "es_PE",
"es-US": "es_US",
"es-UY": "es_UY",
"es-VE": "es_VE",
"et-EE": "et_EE",
"fi-FI": "fi_FI",
"fil-PH": "fil_PH",
"fr-BE": "fr_BE",
"fr-CA": "fr_CA",
"fr-CH": "fr_CH",
"fr-FR": "fr_FR",
"hi-IN": "hi_IN",
"hu-HU": "hu_HU",
"id-ID": "id_ID",
"it-CH": "it_CH",
"it-IT": "it_IT",
"ja-JP": "ja_JP",
"ko-KR": "ko_KR",
"ms-MY": "ms_MY",
"ms-SG": "ms_SG",
"nb-NO": "no_NO",
"nl-BE": "nl_BE",
"nl-NL": "nl_NL",
"pl-PL": "pl_PL",
"pt-BR": "pt-BR_BR",
"pt-PT": "pt_PT",
"ro-RO": "ro_RO",
"ru-BY": "ru_BY",
"ru-RU": "ru_RU",
"sv-SE": "sv_SE",
"tr-TR": "tr_TR",
"uk-UA": "uk_UA",
"vi-VN": "vi_VN",
"zh-CN": "zh-CN_CN",
"zh-HK": "zh-TW_HK",
"zh-TW": "zh-TW_TW"
}
}, },
"wikidata": { "wikidata": {
"all_locale": null, "all_locale": null,
@@ -8491,6 +7960,7 @@
"inh", "inh",
"io", "io",
"is", "is",
"isv",
"it", "it",
"iu", "iu",
"ja", "ja",
@@ -8539,6 +8009,7 @@
"ltg", "ltg",
"lv", "lv",
"mad", "mad",
"mag",
"mai", "mai",
"map-bms", "map-bms",
"mdf", "mdf",

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
], ],
"ua": "Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}", "ua": "Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}",
"versions": [ "versions": [
"152.0", "151.0",
"151.0" "150.0"
] ]
} }

View File

@@ -3272,7 +3272,7 @@
"Q128822": { "Q128822": {
"si_name": "Q182429", "si_name": "Q182429",
"symbol": "kn", "symbol": "kn",
"to_si_factor": 0.514 "to_si_factor": 0.5144444444444445
}, },
"Q12912288": { "Q12912288": {
"si_name": null, "si_name": null,

View File

@@ -7,17 +7,13 @@
# There exits a https://github.com/ohblue/baidu-serp-api/ # There exits a https://github.com/ohblue/baidu-serp-api/
# but we don't use it here (may we can learn from). # but we don't use it here (may we can learn from).
import typing as t
from urllib.parse import urlencode from urllib.parse import urlencode
from datetime import datetime from datetime import datetime
from html import unescape from html import unescape
import time import time
import json import json
from searx.exceptions import SearxEngineAPIException, SearxEngineCaptchaException, SearxEngineAccessDeniedException from searx.exceptions import SearxEngineAPIException, SearxEngineCaptchaException
from searx.enginelib import EngineCache
from searx.network import get as http_get
from searx.utils import html_to_text from searx.utils import html_to_text
about = { about = {
@@ -39,31 +35,6 @@ baidu_category = 'general'
time_range_support = True time_range_support = True
time_range_dict = {"day": 86400, "week": 604800, "month": 2592000, "year": 31536000} time_range_dict = {"day": 86400, "week": 604800, "month": 2592000, "year": 31536000}
image_base_url = "https://image.baidu.com/"
COOKIE_CACHE_KEY = "cookie"
COOKIE_CACHE_EXPIRATION_SECONDS = 3600
CACHE: EngineCache
"""Stores cookies from Baidu image search warmup."""
def setup(engine_settings: dict[str, t.Any]) -> bool:
global CACHE # pylint: disable=global-statement
CACHE = EngineCache(engine_settings["name"])
return True
def get_image_cookies(headers: dict[str, str]) -> dict[str, str]:
cookies: dict[str, str] | None = CACHE.get(COOKIE_CACHE_KEY)
if cookies:
return cookies
warmup = http_get(image_base_url, headers=headers, timeout=10)
cookies = dict(warmup.cookies.items())
CACHE.set(key=COOKIE_CACHE_KEY, value=cookies, expire=COOKIE_CACHE_EXPIRATION_SECONDS)
return cookies
def init(_): def init(_):
if baidu_category not in ('general', 'images', 'it'): if baidu_category not in ('general', 'images', 'it'):
@@ -117,9 +88,6 @@ def request(query, params):
if baidu_category == 'it': if baidu_category == 'it':
query_params["paramList"] += f",timestamp_range={past}-{now}" query_params["paramList"] += f",timestamp_range={past}-{now}"
if baidu_category == 'images':
params["cookies"] = get_image_cookies(params["headers"])
params["url"] = f"{query_url}?{urlencode(query_params)}" params["url"] = f"{query_url}?{urlencode(query_params)}"
params["allow_redirects"] = False params["allow_redirects"] = False
return params return params
@@ -135,8 +103,6 @@ def response(resp):
# baidu's JSON encoder wrongly quotes / and ' characters by \\ and \' # baidu's JSON encoder wrongly quotes / and ' characters by \\ and \'
text = text.replace(r"\/", "/").replace(r"\'", "'") text = text.replace(r"\/", "/").replace(r"\'", "'")
data = json.loads(text, strict=False) data = json.loads(text, strict=False)
if data.get("antiFlag") == 1:
raise SearxEngineAccessDeniedException(data.get("message", "Forbid spider access"))
parsers = {'general': parse_general, 'images': parse_images, 'it': parse_it} parsers = {'general': parse_general, 'images': parse_images, 'it': parse_it}
return parsers[baidu_category](data) return parsers[baidu_category](data)

View File

@@ -8,7 +8,6 @@ import random
import string import string
from urllib.parse import urlencode from urllib.parse import urlencode
from datetime import datetime, timedelta from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from searx import utils from searx import utils
@@ -40,32 +39,6 @@ cookie = {
"home_feed_column": "4", "home_feed_column": "4",
} }
_CN_TZ = ZoneInfo("Asia/Shanghai")
# Calendar-day time filter (Asia/Shanghai); dict values are days to subtract from today.
time_range_support = True
time_range_dict = {"day": 0, "week": 6, "month": 29, "year": 364}
def _pubtime_range(time_range: str) -> tuple[int, int]:
"""Return ``(pubtime_begin_s, pubtime_end_s)`` for Bilibili's search API.
Time ranges follow Bilibili's website semantics: they are counted in
**calendar days** in China Standard Time (``Asia/Shanghai``), not as
sliding 24-hour windows. For example, ``day`` means from 00:00:00 to
23:59:59 of the current local day; ``week`` spans from 00:00:00 on the
calendar day six days ago through the end of today, and so on.
The returned Unix timestamps (seconds) map to Bilibili's
``pubtime_begin_s`` and ``pubtime_end_s`` query parameters.
"""
now = datetime.now(_CN_TZ)
pubtime_end_s = int(now.replace(hour=23, minute=59, second=59, microsecond=0).timestamp())
begin_day = now - timedelta(days=time_range_dict[time_range])
pubtime_begin_s = int(begin_day.replace(hour=0, minute=0, second=0, microsecond=0).timestamp())
return pubtime_begin_s, pubtime_end_s
def request(query, params): def request(query, params):
query_params = { query_params = {
@@ -77,11 +50,6 @@ def request(query, params):
"search_type": "video", "search_type": "video",
} }
if params.get("time_range") in time_range_dict:
pubtime_begin_s, pubtime_end_s = _pubtime_range(params["time_range"])
query_params["pubtime_begin_s"] = pubtime_begin_s
query_params["pubtime_end_s"] = pubtime_end_s
params["url"] = f"{base_url}?{urlencode(query_params)}" params["url"] = f"{base_url}?{urlencode(query_params)}"
params["headers"]["Referer"] = "https://www.bilibili.com/" params["headers"]["Referer"] = "https://www.bilibili.com/"
params["headers"]["Accept"] = "application/json, text/javascript, */*; q=0.01" params["headers"]["Accept"] = "application/json, text/javascript, */*; q=0.01"

View File

@@ -1,62 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Magnific_ is a database for images.
.. _Magnific: https://www.magnific.com
"""
from urllib.parse import urlencode
import typing as t
from searx.result_types import EngineResults
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
from searx.search.processors import OnlineParams
about = {
"website": "https://www.magnific.com",
"wikidata_id": "Q104211654",
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": "JSON",
}
base_url = "https://www.magnific.com"
categories = ["images"]
paging = True
free_images_only = True
"""
Whether to only load images that may be used for free, without a Magnific account.
"""
def request(query: str, params: "OnlineParams") -> None:
args = {"term": query, "filters[ai-generated][excluded]": 1, "page": params["pageno"], "locale": "en"}
if free_images_only:
args["filters[license]"] = "free"
params["headers"]["Referer"] = f"{base_url}/search"
params["url"] = f"{base_url}/api/regular/search?{urlencode(args)}"
def response(resp: "SXNG_Response"):
res = EngineResults()
result: dict[str, t.Any] # TBH: dict[str, t.Any]
for result in resp.json()["items"]:
res.add(
res.types.Image(
title=result["name"],
url=result["url"],
thumbnail_src=result["preview"]["url"],
img_src=result["preview"]["url"],
resolution=f"{result['preview']['width']}x{result['preview']['height']}",
)
)
return res

View File

@@ -99,35 +99,23 @@ def parse_general(data):
dom = html.fromstring(data) dom = html.fromstring(data)
for item in eval_xpath_list(dom, "//div[contains(@class, 'fds-web-normal-doc-root')]"): for item in eval_xpath_list(dom, "//ul[contains(@class, 'lst_total')]/li[contains(@class, 'bx')]"):
thumbnail = extract_text( thumbnail = None
eval_xpath(
item,
".//div[contains(@class, 'sds-comps-image') and not(contains(@class, 'sds-comps-image-circle'))]/img/@src",
)
)
title = extract_text(eval_xpath(item, ".//span[contains(@class, 'sds-comps-text-type-headline1')]"))
url = None
try: try:
url = eval_xpath_getindex( thumbnail = eval_xpath_getindex(item, ".//div[contains(@class, 'thumb_single')]//img/@data-lazysrc", 0)
item, ".//a[starts-with(@href, 'http') and not(contains(@href, 'keep.naver.com'))]/@href", 0
)
except (ValueError, TypeError, SearxEngineXPathException): except (ValueError, TypeError, SearxEngineXPathException):
pass pass
content = extract_text(eval_xpath(item, ".//span[contains(@class, 'sds-comps-text-type-body1')]")) results.add(
MainResult(
if title and url: title=extract_text(eval_xpath(item, ".//a[contains(@class, 'link_tit')]")),
results.add( url=eval_xpath_getindex(item, ".//a[contains(@class, 'link_tit')]/@href", 0),
MainResult( content=extract_text(
title=title, eval_xpath(item, ".//div[contains(@class, 'total_dsc_wrap')]//a[contains(@class, 'api_txt_lines')]")
url=url, ),
content=content or "", thumbnail=thumbnail,
thumbnail=thumbnail or "",
)
) )
)
return results return results
@@ -185,7 +173,7 @@ def parse_news(data):
title=title, title=title,
url=url, url=url,
content=content, content=content,
thumbnail=thumbnail or "", thumbnail=thumbnail,
) )
) )
@@ -208,7 +196,7 @@ def parse_videos(data):
length = None length = None
try: try:
length = parse_duration_string(extract_text(eval_xpath(item, ".//span[contains(@class, 'time')]")) or "") length = parse_duration_string(extract_text(eval_xpath(item, ".//span[contains(@class, 'time')]")))
except (ValueError, TypeError): except (ValueError, TypeError):
pass pass

View File

@@ -1,92 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Neosearch_ aims to be a privacy-first alternative to Google.
.. _Neosearch: https://neosearch.org/About
"""
from json import loads
import typing as t
from urllib.parse import urlencode
from searx.extended_types import SXNG_Response
from searx.result_types import EngineResults
if t.TYPE_CHECKING:
from searx.enginelib.traits import EngineTraits
from searx.search.processors import OnlineParams
traits: EngineTraits
about = {
"website": "https://neosearch.org",
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": "JSON",
}
base_url = "https://neosearch.org"
categories = ["general"]
paging = False
def request(query: str, params: "OnlineParams"):
args = {"q": query, "generate": "auto"}
countrycode = params["searxng_locale"].split("-")[-1].upper()
if countrycode in traits.custom["countrycodes"]:
args["loc"] = countrycode
params["url"] = f"{base_url}/search?{urlencode(args)}"
def response(resp: "SXNG_Response") -> EngineResults:
res = EngineResults()
# first line contains something like `{"location": "de"}`
# second line contains the actual results
json_resp = loads(resp.text.splitlines()[-1])
for lens in json_resp["lenses"]:
for category in lens["categories"]:
for result in category["links"]:
if not result["url"]:
continue
res.add(
res.types.MainResult(
url=result["url"],
title=result["title"],
content=result["snippet"] or result["description"],
)
)
for suggestion in json_resp.get("suggestions", []):
res.add(res.types.LegacyResult(suggestion=suggestion))
return res
def fetch_traits(engine_traits: "EngineTraits") -> None:
# pylint: disable=import-outside-toplevel
from searx.network import get
from searx.utils import extr, js_obj_str_to_python
from babel.core import get_global
resp = get(base_url)
locations_js_raw = extr(resp.text, "const LOCATIONS = ", ";")
if not locations_js_raw:
raise RuntimeError("failed to find locations in neosearch HTML response")
locations: list[dict[str, str]] = js_obj_str_to_python(locations_js_raw)
babel_reg_list = get_global("territory_languages").keys()
countrycodes: list[str] = []
for loc in locations:
_reg = loc["code"].upper()
if _reg not in babel_reg_list:
print(f"ERROR: region tag {_reg} is unknown by babel")
continue
countrycodes.append(_reg)
countrycodes.sort()
engine_traits.custom["countrycodes"] = countrycodes

View File

@@ -1,63 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Picjumbo_ provides free stock photos.
.. _Picjumbo: https://picjumbo.com
"""
from urllib.parse import urlparse, urlunparse
import typing as t
from lxml import html
from searx.result_types import EngineResults
from searx.utils import eval_xpath, eval_xpath_list, extract_text
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
from searx.search.processors import OnlineParams
about = {
"website": "https://picjumbo.com",
"wikidata_id": None,
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": "HTML",
}
base_url = "https://picjumbo.com"
categories = ["images"]
paging = True
def request(query: str, params: "OnlineParams") -> None:
params["url"] = f"{base_url}/search/{query}/page/{params['pageno']}"
def _get_max_res_url(url: str) -> str:
"""Get the maximum resolution of the image based on the thumbnail URL."""
parsed_url = urlparse(url)
max_res_url = parsed_url._replace(query="w=10000&quality=100")
return urlunparse(max_res_url)
def response(resp: "SXNG_Response"):
res = EngineResults()
doc = html.fromstring(resp.text)
for result in eval_xpath_list(doc, "//div[contains(@class, 'photo_query')]/div[contains(@class, 'photo_item')]"):
thumbnail = extract_text(eval_xpath(result, ".//img[contains(@class, 'image')]/@src")) or ""
res.add(
res.types.Image(
url=extract_text(eval_xpath(result, ".//a[contains(@class, 'image')]/@href")) or "",
title=extract_text(eval_xpath(result, ".//h3")) or "",
content=extract_text(eval_xpath(result, ".//meta[@itemprop='keywords']/@content")) or "",
thumbnail_src=thumbnail,
img_src=_get_max_res_url(thumbnail),
)
)
return res

View File

@@ -1,62 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Shopify stock photos provides royalty-free images, intended for use with
Shopify.
"""
import typing as t
from urllib.parse import urlencode
from lxml import html
from searx.result_types import EngineResults
from searx.utils import eval_xpath, eval_xpath_list, extract_text
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
from searx.search.processors import OnlineParams
about = {
"website": "https://www.shopify.com/stock-photos",
"wikidata_id": None,
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": "HTML",
}
base_url = "https://www.shopify.com"
categories = ["images"]
paging = True
def request(query: str, params: "OnlineParams") -> None:
args = {"q": query, "page": params["pageno"]}
params["url"] = f"{base_url}/stock-photos/photos/search?{urlencode(args)}"
def _get_download_url(url: str) -> str:
"""Get the link to the full quality image."""
query_start = url.find("?")
return url[:query_start] + "/download?quality=premium"
def response(resp: "SXNG_Response"):
res = EngineResults()
doc = html.fromstring(resp.text)
for result in eval_xpath_list(doc, "//div[contains(@class, 'js-masonry-grid')]/div"):
url = base_url + (extract_text(eval_xpath(result, ".//a[contains(@class, 'photo-tile')]/@href")) or "")
res.add(
res.types.Image(
url=url,
title=extract_text(eval_xpath(result, ".//p[contains(@class, 'photo-tile__title')]")) or "",
thumbnail_src=extract_text(eval_xpath(result, ".//img[contains(@class, 'photo-card__image')]/@src"))
or "",
img_src=_get_download_url(url),
)
)
return res

View File

@@ -1,55 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Stocksnap_ is a search engine for CC0-licensed images.
.. _Stocksnap: https://stocksnap.io
"""
import typing as t
from searx.result_types import EngineResults
if t.TYPE_CHECKING:
from searx.extended_types import SXNG_Response
from searx.search.processors import OnlineParams
about = {
"website": "https://stocksnap.io",
"wikidata_id": None,
"official_api_documentation": None,
"use_official_api": False,
"require_api_key": False,
"results": "JSON",
}
# otherwise all requests get blocked, probably HTTP2 fingerprinting
enable_http2 = False
base_url = "https://stocksnap.io"
cdn_url = "https://cdn.stocksnap.io"
categories = ["images"]
paging = True
def request(query: str, params: "OnlineParams") -> None:
params["url"] = f"{base_url}/api/search-photos/{query}/relevance/desc/{params['pageno']}"
def response(resp: "SXNG_Response"):
res = EngineResults()
result: dict[str, str] # TBH: dict[str, t.Any]
for result in resp.json()["results"]:
slug = "-".join(result['keywords'][:1]) + "-" + result["img_id"]
res.add(
res.types.Image(
title=result["tags"],
url=f"{base_url}/photo/{slug}",
thumbnail_src=f"{cdn_url}/img-thumbs/280h/{result['img_id']}.jpg",
img_src=f"{cdn_url}/img-thumbs/960w/{result['img_id']}.jpg",
img_format="JPEG",
resolution=f"{result['img_width']}x{result['img_height']}",
)
)
return res

View File

@@ -1585,11 +1585,6 @@ engines:
disabled: true disabled: true
inactive: true inactive: true
- name: magnific
engine: magnific
shortcut: mag
disabled: true
- name: marginalia - name: marginalia
engine: marginalia engine: marginalia
shortcut: mar shortcut: mar
@@ -1862,11 +1857,6 @@ engines:
engine: photon engine: photon
shortcut: ph shortcut: ph
- name: picjumbo
engine: picjumbo
shortcut: pj
disabled: true
- name: pinterest - name: pinterest
engine: pinterest engine: pinterest
shortcut: pin shortcut: pin
@@ -2175,11 +2165,6 @@ engines:
engine: sepiasearch engine: sepiasearch
shortcut: sep shortcut: sep
- name: shopify stock
engine: shopify_stock
shortcut: shs
disabled: true
- name: sogou - name: sogou
engine: sogou engine: sogou
shortcut: sogou shortcut: sogou
@@ -2210,11 +2195,6 @@ engines:
api_site: 'stackoverflow' api_site: 'stackoverflow'
categories: [it, q&a] categories: [it, q&a]
- name: stocksnap
engine: stocksnap
shortcut: sto
disabled: true
- name: askubuntu - name: askubuntu
engine: stackexchange engine: stackexchange
shortcut: ubuntu shortcut: ubuntu
@@ -2854,12 +2834,6 @@ engines:
shortcut: nvrv shortcut: nvrv
disabled: true disabled: true
- name: neosearch
engine: neosearch
shortcut: neo
disabled: true
inactive: true
- name: rubygems - name: rubygems
shortcut: rbg shortcut: rbg
engine: xpath engine: xpath

View File

@@ -9,7 +9,6 @@
''' '''
sxng_locales = ( sxng_locales = (
('af', 'Afrikaans', '', 'Afrikaans', '\U0001f310'),
('ar', 'العربية', '', 'Arabic', '\U0001f310'), ('ar', 'العربية', '', 'Arabic', '\U0001f310'),
('ar-SA', 'العربية', 'المملكة العربية السعودية', 'Arabic', '\U0001f1f8\U0001f1e6'), ('ar-SA', 'العربية', 'المملكة العربية السعودية', 'Arabic', '\U0001f1f8\U0001f1e6'),
('bg', 'Български', '', 'Bulgarian', '\U0001f310'), ('bg', 'Български', '', 'Bulgarian', '\U0001f310'),
@@ -46,7 +45,6 @@ sxng_locales = (
('es-ES', 'Español', 'España', 'Spanish', '\U0001f1ea\U0001f1f8'), ('es-ES', 'Español', 'España', 'Spanish', '\U0001f1ea\U0001f1f8'),
('es-MX', 'Español', 'México', 'Spanish', '\U0001f1f2\U0001f1fd'), ('es-MX', 'Español', 'México', 'Spanish', '\U0001f1f2\U0001f1fd'),
('es-PE', 'Español', 'Perú', 'Spanish', '\U0001f1f5\U0001f1ea'), ('es-PE', 'Español', 'Perú', 'Spanish', '\U0001f1f5\U0001f1ea'),
('es-VE', 'Español', 'Venezuela', 'Spanish', '\U0001f1fb\U0001f1ea'),
('et', 'Eesti', '', 'Estonian', '\U0001f310'), ('et', 'Eesti', '', 'Estonian', '\U0001f310'),
('et-EE', 'Eesti', 'Eesti', 'Estonian', '\U0001f1ea\U0001f1ea'), ('et-EE', 'Eesti', 'Eesti', 'Estonian', '\U0001f1ea\U0001f1ea'),
('fi', 'Suomi', '', 'Finnish', '\U0001f310'), ('fi', 'Suomi', '', 'Finnish', '\U0001f310'),
@@ -58,7 +56,6 @@ sxng_locales = (
('fr-CA', 'Français', 'Canada', 'French', '\U0001f1e8\U0001f1e6'), ('fr-CA', 'Français', 'Canada', 'French', '\U0001f1e8\U0001f1e6'),
('fr-CH', 'Français', 'Suisse', 'French', '\U0001f1e8\U0001f1ed'), ('fr-CH', 'Français', 'Suisse', 'French', '\U0001f1e8\U0001f1ed'),
('fr-FR', 'Français', 'France', 'French', '\U0001f1eb\U0001f1f7'), ('fr-FR', 'Français', 'France', 'French', '\U0001f1eb\U0001f1f7'),
('gl', 'Galego', '', 'Galician', '\U0001f310'),
('hi', 'हिन्दी', '', 'Hindi', '\U0001f310'), ('hi', 'हिन्दी', '', 'Hindi', '\U0001f310'),
('hi-IN', 'हिन्दी', 'भारत', 'Hindi', '\U0001f1ee\U0001f1f3'), ('hi-IN', 'हिन्दी', 'भारत', 'Hindi', '\U0001f1ee\U0001f1f3'),
('hr', 'Hrvatski', '', 'Croatian', '\U0001f310'), ('hr', 'Hrvatski', '', 'Croatian', '\U0001f310'),
@@ -92,8 +89,6 @@ sxng_locales = (
('ro-RO', 'Română', 'România', 'Romanian', '\U0001f1f7\U0001f1f4'), ('ro-RO', 'Română', 'România', 'Romanian', '\U0001f1f7\U0001f1f4'),
('ru', 'Русский', '', 'Russian', '\U0001f310'), ('ru', 'Русский', '', 'Russian', '\U0001f310'),
('ru-RU', 'Русский', 'Россия', 'Russian', '\U0001f1f7\U0001f1fa'), ('ru-RU', 'Русский', 'Россия', 'Russian', '\U0001f1f7\U0001f1fa'),
('sk', 'Slovenčina', '', 'Slovak', '\U0001f310'),
('sq', 'Shqip', '', 'Albanian', '\U0001f310'),
('sv', 'Svenska', '', 'Swedish', '\U0001f310'), ('sv', 'Svenska', '', 'Swedish', '\U0001f310'),
('sv-FI', 'Svenska', 'Finland', 'Swedish', '\U0001f1eb\U0001f1ee'), ('sv-FI', 'Svenska', 'Finland', 'Swedish', '\U0001f1eb\U0001f1ee'),
('sv-SE', 'Svenska', 'Sverige', 'Swedish', '\U0001f1f8\U0001f1ea'), ('sv-SE', 'Svenska', 'Sverige', 'Swedish', '\U0001f1f8\U0001f1ea'),
@@ -101,7 +96,6 @@ sxng_locales = (
('th-TH', 'ไทย', 'ไทย', 'Thai', '\U0001f1f9\U0001f1ed'), ('th-TH', 'ไทย', 'ไทย', 'Thai', '\U0001f1f9\U0001f1ed'),
('tr', 'Türkçe', '', 'Turkish', '\U0001f310'), ('tr', 'Türkçe', '', 'Turkish', '\U0001f310'),
('tr-TR', 'Türkçe', 'Türkiye', 'Turkish', '\U0001f1f9\U0001f1f7'), ('tr-TR', 'Türkçe', 'Türkiye', 'Turkish', '\U0001f1f9\U0001f1f7'),
('uk', 'Українська', '', 'Ukrainian', '\U0001f310'),
('vi', 'Tiếng Việt', '', 'Vietnamese', '\U0001f310'), ('vi', 'Tiếng Việt', '', 'Vietnamese', '\U0001f310'),
('vi-VN', 'Tiếng Việt', 'Việt Nam', 'Vietnamese', '\U0001f1fb\U0001f1f3'), ('vi-VN', 'Tiếng Việt', 'Việt Nam', 'Vietnamese', '\U0001f1fb\U0001f1f3'),
('zh', '中文', '', 'Chinese', '\U0001f310'), ('zh', '中文', '', 'Chinese', '\U0001f310'),