@strapi/i18n 0.0.0-experimental.8ba06b448e7b82ad8505f461edf528901aea9e1e → 0.0.0-experimental.8bf99b7c43ed372264c198d347a2ada9dfed174d
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/admin/components/BulkLocaleActionModal.js +262 -0
- package/dist/admin/components/BulkLocaleActionModal.js.map +1 -0
- package/dist/admin/components/BulkLocaleActionModal.mjs +260 -0
- package/dist/admin/components/BulkLocaleActionModal.mjs.map +1 -0
- package/dist/admin/components/CMHeaderActions.js +721 -0
- package/dist/admin/components/CMHeaderActions.js.map +1 -0
- package/dist/admin/components/CMHeaderActions.mjs +696 -0
- package/dist/admin/components/CMHeaderActions.mjs.map +1 -0
- package/dist/admin/components/CMListViewModalsAdditionalInformation.js +69 -0
- package/dist/admin/components/CMListViewModalsAdditionalInformation.js.map +1 -0
- package/dist/admin/components/CMListViewModalsAdditionalInformation.mjs +65 -0
- package/dist/admin/components/CMListViewModalsAdditionalInformation.mjs.map +1 -0
- package/dist/admin/components/CheckboxConfirmation.js +155 -0
- package/dist/admin/components/CheckboxConfirmation.js.map +1 -0
- package/dist/admin/components/CheckboxConfirmation.mjs +134 -0
- package/dist/admin/components/CheckboxConfirmation.mjs.map +1 -0
- package/dist/admin/components/CreateLocale.js +395 -0
- package/dist/admin/components/CreateLocale.js.map +1 -0
- package/dist/admin/components/CreateLocale.mjs +369 -0
- package/dist/admin/components/CreateLocale.mjs.map +1 -0
- package/dist/admin/components/DeleteLocale.js +90 -0
- package/dist/admin/components/DeleteLocale.js.map +1 -0
- package/dist/admin/components/DeleteLocale.mjs +69 -0
- package/dist/admin/components/DeleteLocale.mjs.map +1 -0
- package/dist/admin/components/EditLocale.js +212 -0
- package/dist/admin/components/EditLocale.js.map +1 -0
- package/dist/admin/components/EditLocale.mjs +190 -0
- package/dist/admin/components/EditLocale.mjs.map +1 -0
- package/dist/admin/components/LocaleListCell.js +82 -0
- package/dist/admin/components/LocaleListCell.js.map +1 -0
- package/dist/admin/components/LocaleListCell.mjs +80 -0
- package/dist/admin/components/LocaleListCell.mjs.map +1 -0
- package/dist/admin/components/LocalePicker.js +98 -0
- package/dist/admin/components/LocalePicker.js.map +1 -0
- package/dist/admin/components/LocalePicker.mjs +77 -0
- package/dist/admin/components/LocalePicker.mjs.map +1 -0
- package/dist/admin/components/LocaleTable.js +143 -0
- package/dist/admin/components/LocaleTable.js.map +1 -0
- package/dist/admin/components/LocaleTable.mjs +122 -0
- package/dist/admin/components/LocaleTable.mjs.map +1 -0
- package/dist/admin/constants.js +37 -0
- package/dist/admin/constants.js.map +1 -0
- package/dist/admin/constants.mjs +35 -0
- package/dist/admin/constants.mjs.map +1 -0
- package/dist/admin/contentManagerHooks/editView.js +106 -0
- package/dist/admin/contentManagerHooks/editView.js.map +1 -0
- package/dist/admin/contentManagerHooks/editView.mjs +85 -0
- package/dist/admin/contentManagerHooks/editView.mjs.map +1 -0
- package/dist/admin/contentManagerHooks/listView.js +43 -0
- package/dist/admin/contentManagerHooks/listView.js.map +1 -0
- package/dist/admin/contentManagerHooks/listView.mjs +41 -0
- package/dist/admin/contentManagerHooks/listView.mjs.map +1 -0
- package/dist/admin/contentReleasesHooks/releaseDetailsView.js +20 -0
- package/dist/admin/contentReleasesHooks/releaseDetailsView.js.map +1 -0
- package/dist/admin/contentReleasesHooks/releaseDetailsView.mjs +18 -0
- package/dist/admin/contentReleasesHooks/releaseDetailsView.mjs.map +1 -0
- package/dist/admin/hooks/useI18n.js +78 -0
- package/dist/admin/hooks/useI18n.js.map +1 -0
- package/dist/admin/hooks/useI18n.mjs +57 -0
- package/dist/admin/hooks/useI18n.mjs.map +1 -0
- package/dist/admin/index.js +220 -16
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +202 -15
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/middlewares/extendCTBAttributeInitialData.js +71 -0
- package/dist/admin/middlewares/extendCTBAttributeInitialData.js.map +1 -0
- package/dist/admin/middlewares/extendCTBAttributeInitialData.mjs +69 -0
- package/dist/admin/middlewares/extendCTBAttributeInitialData.mjs.map +1 -0
- package/dist/admin/middlewares/extendCTBInitialData.js +40 -0
- package/dist/admin/middlewares/extendCTBInitialData.js.map +1 -0
- package/dist/admin/middlewares/extendCTBInitialData.mjs +38 -0
- package/dist/admin/middlewares/extendCTBInitialData.mjs.map +1 -0
- package/dist/admin/middlewares/rbac-middleware.js +49 -0
- package/dist/admin/middlewares/rbac-middleware.js.map +1 -0
- package/dist/admin/middlewares/rbac-middleware.mjs +28 -0
- package/dist/admin/middlewares/rbac-middleware.mjs.map +1 -0
- package/dist/admin/pages/SettingsPage.js +107 -0
- package/dist/admin/pages/SettingsPage.js.map +1 -0
- package/dist/admin/pages/SettingsPage.mjs +85 -0
- package/dist/admin/pages/SettingsPage.mjs.map +1 -0
- package/dist/admin/pluginId.js +6 -0
- package/dist/admin/pluginId.js.map +1 -0
- package/dist/admin/pluginId.mjs +4 -0
- package/dist/admin/pluginId.mjs.map +1 -0
- package/dist/admin/services/api.js +12 -0
- package/dist/admin/services/api.js.map +1 -0
- package/dist/admin/services/api.mjs +10 -0
- package/dist/admin/services/api.mjs.map +1 -0
- package/dist/admin/services/locales.js +70 -0
- package/dist/admin/services/locales.js.map +1 -0
- package/dist/admin/services/locales.mjs +64 -0
- package/dist/admin/services/locales.mjs.map +1 -0
- package/dist/admin/services/relations.js +23 -0
- package/dist/admin/services/relations.js.map +1 -0
- package/dist/admin/services/relations.mjs +21 -0
- package/dist/admin/services/relations.mjs.map +1 -0
- package/dist/admin/src/utils/schemas.d.ts +424 -16
- package/dist/admin/{chunks/de-nEMWvIiY.js → translations/de.json.js} +2 -2
- package/dist/admin/translations/de.json.js.map +1 -0
- package/dist/admin/{chunks/de-Cm8mYdaO.mjs → translations/de.json.mjs} +1 -1
- package/dist/admin/translations/de.json.mjs.map +1 -0
- package/dist/admin/{chunks/dk-CYATLPVe.js → translations/dk.json.js} +2 -2
- package/dist/admin/translations/dk.json.js.map +1 -0
- package/dist/admin/{chunks/dk-BeUFOegB.mjs → translations/dk.json.mjs} +1 -1
- package/dist/admin/translations/dk.json.mjs.map +1 -0
- package/dist/admin/{chunks/en-CG5cUCbD.js → translations/en.json.js} +2 -2
- package/dist/admin/translations/en.json.js.map +1 -0
- package/dist/admin/{chunks/en-eWSaCeOb.mjs → translations/en.json.mjs} +1 -1
- package/dist/admin/translations/en.json.mjs.map +1 -0
- package/dist/admin/{chunks/es-CWsogTGm.js → translations/es.json.js} +2 -2
- package/dist/admin/translations/es.json.js.map +1 -0
- package/dist/admin/{chunks/es-DqF_IdAc.mjs → translations/es.json.mjs} +1 -1
- package/dist/admin/translations/es.json.mjs.map +1 -0
- package/dist/admin/{chunks/fr-CC7UFcYd.js → translations/fr.json.js} +2 -2
- package/dist/admin/translations/fr.json.js.map +1 -0
- package/dist/admin/{chunks/fr-CyARbZ3c.mjs → translations/fr.json.mjs} +1 -1
- package/dist/admin/translations/fr.json.mjs.map +1 -0
- package/dist/admin/{chunks/ko-XwGmfhoq.js → translations/ko.json.js} +2 -2
- package/dist/admin/translations/ko.json.js.map +1 -0
- package/dist/admin/{chunks/ko-Ax4NSedM.mjs → translations/ko.json.mjs} +1 -1
- package/dist/admin/translations/ko.json.mjs.map +1 -0
- package/dist/admin/{chunks/pl-B_vzY_ZB.js → translations/pl.json.js} +2 -2
- package/dist/admin/translations/pl.json.js.map +1 -0
- package/dist/admin/{chunks/pl-B-aqvMqL.mjs → translations/pl.json.mjs} +1 -1
- package/dist/admin/translations/pl.json.mjs.map +1 -0
- package/dist/admin/{chunks/ru-WzHcJV1f.js → translations/ru.json.js} +2 -2
- package/dist/admin/translations/ru.json.js.map +1 -0
- package/dist/admin/{chunks/ru-VkPjQ-Sk.mjs → translations/ru.json.mjs} +1 -1
- package/dist/admin/translations/ru.json.mjs.map +1 -0
- package/dist/admin/{chunks/tr-CcWp6u3w.js → translations/tr.json.js} +2 -2
- package/dist/admin/translations/tr.json.js.map +1 -0
- package/dist/admin/{chunks/tr-DcTR88c9.mjs → translations/tr.json.mjs} +1 -1
- package/dist/admin/translations/tr.json.mjs.map +1 -0
- package/dist/admin/{chunks/uk-CO6JHYRC.js → translations/uk.json.js} +2 -2
- package/dist/admin/translations/uk.json.js.map +1 -0
- package/dist/admin/{chunks/uk-CMz6iPag.mjs → translations/uk.json.mjs} +1 -1
- package/dist/admin/translations/uk.json.mjs.map +1 -0
- package/dist/admin/{chunks/zh-Hans-DnU2bhri.js → translations/zh-Hans.json.js} +2 -2
- package/dist/admin/translations/zh-Hans.json.js.map +1 -0
- package/dist/admin/{chunks/zh-Hans-L3wsRegj.mjs → translations/zh-Hans.json.mjs} +1 -1
- package/dist/admin/translations/zh-Hans.json.mjs.map +1 -0
- package/dist/admin/{chunks/zh-C9So4SGq.js → translations/zh.json.js} +2 -2
- package/dist/admin/translations/zh.json.js.map +1 -0
- package/dist/admin/{chunks/zh-RZyMiPIs.mjs → translations/zh.json.mjs} +1 -1
- package/dist/admin/translations/zh.json.mjs.map +1 -0
- package/dist/admin/utils/baseQuery.js +8 -0
- package/dist/admin/utils/baseQuery.js.map +1 -0
- package/dist/admin/utils/baseQuery.mjs +6 -0
- package/dist/admin/utils/baseQuery.mjs.map +1 -0
- package/dist/admin/utils/clean.js +70 -0
- package/dist/admin/utils/clean.js.map +1 -0
- package/dist/admin/utils/clean.mjs +68 -0
- package/dist/admin/utils/clean.mjs.map +1 -0
- package/dist/admin/utils/fields.js +34 -0
- package/dist/admin/utils/fields.js.map +1 -0
- package/dist/admin/utils/fields.mjs +31 -0
- package/dist/admin/utils/fields.mjs.map +1 -0
- package/dist/admin/utils/getTranslation.js +8 -0
- package/dist/admin/utils/getTranslation.js.map +1 -0
- package/dist/admin/utils/getTranslation.mjs +6 -0
- package/dist/admin/utils/getTranslation.mjs.map +1 -0
- package/dist/admin/utils/prefixPluginTranslations.js +11 -0
- package/dist/admin/utils/prefixPluginTranslations.js.map +1 -0
- package/dist/admin/utils/prefixPluginTranslations.mjs +9 -0
- package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -0
- package/dist/admin/utils/schemas.js +74 -0
- package/dist/admin/utils/schemas.js.map +1 -0
- package/dist/admin/utils/schemas.mjs +72 -0
- package/dist/admin/utils/schemas.mjs.map +1 -0
- package/dist/admin/utils/strings.js +6 -0
- package/dist/admin/utils/strings.js.map +1 -0
- package/dist/admin/utils/strings.mjs +4 -0
- package/dist/admin/utils/strings.mjs.map +1 -0
- package/dist/server/bootstrap.js +79 -0
- package/dist/server/bootstrap.js.map +1 -0
- package/dist/server/bootstrap.mjs +77 -0
- package/dist/server/bootstrap.mjs.map +1 -0
- package/dist/server/constants/index.js +29 -0
- package/dist/server/constants/index.js.map +1 -0
- package/dist/server/constants/index.mjs +25 -0
- package/dist/server/constants/index.mjs.map +1 -0
- package/dist/server/constants/iso-locales.json.js +2423 -0
- package/dist/server/constants/iso-locales.json.js.map +1 -0
- package/dist/server/constants/iso-locales.json.mjs +2421 -0
- package/dist/server/constants/iso-locales.json.mjs.map +1 -0
- package/dist/server/content-types/index.js +10 -0
- package/dist/server/content-types/index.js.map +1 -0
- package/dist/server/content-types/index.mjs +8 -0
- package/dist/server/content-types/index.mjs.map +1 -0
- package/dist/server/content-types/locale/index.js +10 -0
- package/dist/server/content-types/locale/index.js.map +1 -0
- package/dist/server/content-types/locale/index.mjs +8 -0
- package/dist/server/content-types/locale/index.mjs.map +1 -0
- package/dist/server/content-types/locale/schema.json.js +46 -0
- package/dist/server/content-types/locale/schema.json.js.map +1 -0
- package/dist/server/content-types/locale/schema.json.mjs +38 -0
- package/dist/server/content-types/locale/schema.json.mjs.map +1 -0
- package/dist/server/controllers/content-types.js +76 -0
- package/dist/server/controllers/content-types.js.map +1 -0
- package/dist/server/controllers/content-types.mjs +74 -0
- package/dist/server/controllers/content-types.mjs.map +1 -0
- package/dist/server/controllers/index.js +14 -0
- package/dist/server/controllers/index.js.map +1 -0
- package/dist/server/controllers/index.mjs +12 -0
- package/dist/server/controllers/index.mjs.map +1 -0
- package/dist/server/controllers/iso-locales.js +13 -0
- package/dist/server/controllers/iso-locales.js.map +1 -0
- package/dist/server/controllers/iso-locales.mjs +11 -0
- package/dist/server/controllers/iso-locales.mjs.map +1 -0
- package/dist/server/controllers/locales.js +108 -0
- package/dist/server/controllers/locales.js.map +1 -0
- package/dist/server/controllers/locales.mjs +87 -0
- package/dist/server/controllers/locales.mjs.map +1 -0
- package/dist/server/controllers/validate-locale-creation.js +47 -0
- package/dist/server/controllers/validate-locale-creation.js.map +1 -0
- package/dist/server/controllers/validate-locale-creation.mjs +45 -0
- package/dist/server/controllers/validate-locale-creation.mjs.map +1 -0
- package/dist/server/domain/locale.js +11 -0
- package/dist/server/domain/locale.js.map +1 -0
- package/dist/server/domain/locale.mjs +9 -0
- package/dist/server/domain/locale.mjs.map +1 -0
- package/dist/server/graphql.js +115 -0
- package/dist/server/graphql.js.map +1 -0
- package/dist/server/graphql.mjs +113 -0
- package/dist/server/graphql.mjs.map +1 -0
- package/dist/server/index.js +10 -3712
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +7 -3691
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/register.js +79 -0
- package/dist/server/register.js.map +1 -0
- package/dist/server/register.mjs +77 -0
- package/dist/server/register.mjs.map +1 -0
- package/dist/server/routes/admin.js +102 -0
- package/dist/server/routes/admin.js.map +1 -0
- package/dist/server/routes/admin.mjs +100 -0
- package/dist/server/routes/admin.mjs.map +1 -0
- package/dist/server/routes/content-api.js +15 -0
- package/dist/server/routes/content-api.js.map +1 -0
- package/dist/server/routes/content-api.mjs +13 -0
- package/dist/server/routes/content-api.mjs.map +1 -0
- package/dist/server/routes/index.js +12 -0
- package/dist/server/routes/index.js.map +1 -0
- package/dist/server/routes/index.mjs +10 -0
- package/dist/server/routes/index.mjs.map +1 -0
- package/dist/server/services/content-types.js +157 -0
- package/dist/server/services/content-types.js.map +1 -0
- package/dist/server/services/content-types.mjs +155 -0
- package/dist/server/services/content-types.mjs.map +1 -0
- package/dist/server/services/index.js +22 -0
- package/dist/server/services/index.js.map +1 -0
- package/dist/server/services/index.mjs +20 -0
- package/dist/server/services/index.mjs.map +1 -0
- package/dist/server/services/iso-locales.js +12 -0
- package/dist/server/services/iso-locales.js.map +1 -0
- package/dist/server/services/iso-locales.mjs +10 -0
- package/dist/server/services/iso-locales.mjs.map +1 -0
- package/dist/server/services/locales.js +114 -0
- package/dist/server/services/locales.js.map +1 -0
- package/dist/server/services/locales.mjs +112 -0
- package/dist/server/services/locales.mjs.map +1 -0
- package/dist/server/services/localizations.js +68 -0
- package/dist/server/services/localizations.js.map +1 -0
- package/dist/server/services/localizations.mjs +66 -0
- package/dist/server/services/localizations.mjs.map +1 -0
- package/dist/server/services/metrics.js +30 -0
- package/dist/server/services/metrics.js.map +1 -0
- package/dist/server/services/metrics.mjs +28 -0
- package/dist/server/services/metrics.mjs.map +1 -0
- package/dist/server/services/permissions/actions.js +136 -0
- package/dist/server/services/permissions/actions.js.map +1 -0
- package/dist/server/services/permissions/actions.mjs +134 -0
- package/dist/server/services/permissions/actions.mjs.map +1 -0
- package/dist/server/services/permissions/engine.js +52 -0
- package/dist/server/services/permissions/engine.js.map +1 -0
- package/dist/server/services/permissions/engine.mjs +50 -0
- package/dist/server/services/permissions/engine.mjs.map +1 -0
- package/dist/server/services/permissions/sections-builder.js +45 -0
- package/dist/server/services/permissions/sections-builder.js.map +1 -0
- package/dist/server/services/permissions/sections-builder.mjs +43 -0
- package/dist/server/services/permissions/sections-builder.mjs.map +1 -0
- package/dist/server/services/permissions.js +14 -0
- package/dist/server/services/permissions.js.map +1 -0
- package/dist/server/services/permissions.mjs +12 -0
- package/dist/server/services/permissions.mjs.map +1 -0
- package/dist/server/services/sanitize/index.js +34 -0
- package/dist/server/services/sanitize/index.js.map +1 -0
- package/dist/server/services/sanitize/index.mjs +32 -0
- package/dist/server/services/sanitize/index.mjs.map +1 -0
- package/dist/server/utils/index.js +16 -0
- package/dist/server/utils/index.js.map +1 -0
- package/dist/server/utils/index.mjs +13 -0
- package/dist/server/utils/index.mjs.map +1 -0
- package/dist/server/validation/content-types.js +18 -0
- package/dist/server/validation/content-types.js.map +1 -0
- package/dist/server/validation/content-types.mjs +16 -0
- package/dist/server/validation/content-types.mjs.map +1 -0
- package/dist/server/validation/locales.js +23 -0
- package/dist/server/validation/locales.js.map +1 -0
- package/dist/server/validation/locales.mjs +20 -0
- package/dist/server/validation/locales.mjs.map +1 -0
- package/package.json +8 -8
- package/dist/admin/chunks/SettingsPage-BOEeBbiM.mjs +0 -797
- package/dist/admin/chunks/SettingsPage-BOEeBbiM.mjs.map +0 -1
- package/dist/admin/chunks/SettingsPage-Mg2Ygywx.js +0 -820
- package/dist/admin/chunks/SettingsPage-Mg2Ygywx.js.map +0 -1
- package/dist/admin/chunks/de-Cm8mYdaO.mjs.map +0 -1
- package/dist/admin/chunks/de-nEMWvIiY.js.map +0 -1
- package/dist/admin/chunks/dk-BeUFOegB.mjs.map +0 -1
- package/dist/admin/chunks/dk-CYATLPVe.js.map +0 -1
- package/dist/admin/chunks/en-CG5cUCbD.js.map +0 -1
- package/dist/admin/chunks/en-eWSaCeOb.mjs.map +0 -1
- package/dist/admin/chunks/es-CWsogTGm.js.map +0 -1
- package/dist/admin/chunks/es-DqF_IdAc.mjs.map +0 -1
- package/dist/admin/chunks/fr-CC7UFcYd.js.map +0 -1
- package/dist/admin/chunks/fr-CyARbZ3c.mjs.map +0 -1
- package/dist/admin/chunks/index--VTS8j_L.mjs +0 -2008
- package/dist/admin/chunks/index--VTS8j_L.mjs.map +0 -1
- package/dist/admin/chunks/index-hJ67XV0K.js +0 -2037
- package/dist/admin/chunks/index-hJ67XV0K.js.map +0 -1
- package/dist/admin/chunks/ko-Ax4NSedM.mjs.map +0 -1
- package/dist/admin/chunks/ko-XwGmfhoq.js.map +0 -1
- package/dist/admin/chunks/pl-B-aqvMqL.mjs.map +0 -1
- package/dist/admin/chunks/pl-B_vzY_ZB.js.map +0 -1
- package/dist/admin/chunks/ru-VkPjQ-Sk.mjs.map +0 -1
- package/dist/admin/chunks/ru-WzHcJV1f.js.map +0 -1
- package/dist/admin/chunks/tr-CcWp6u3w.js.map +0 -1
- package/dist/admin/chunks/tr-DcTR88c9.mjs.map +0 -1
- package/dist/admin/chunks/uk-CMz6iPag.mjs.map +0 -1
- package/dist/admin/chunks/uk-CO6JHYRC.js.map +0 -1
- package/dist/admin/chunks/zh-C9So4SGq.js.map +0 -1
- package/dist/admin/chunks/zh-Hans-DnU2bhri.js.map +0 -1
- package/dist/admin/chunks/zh-Hans-L3wsRegj.mjs.map +0 -1
- package/dist/admin/chunks/zh-RZyMiPIs.mjs.map +0 -1
package/dist/server/index.mjs
CHANGED
@@ -1,3700 +1,16 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
|
6
|
-
|
7
|
-
return strapi.store({
|
8
|
-
type: 'plugin',
|
9
|
-
name: 'i18n'
|
10
|
-
});
|
11
|
-
};
|
12
|
-
// retrieve a local service
|
13
|
-
const getService = (name)=>{
|
14
|
-
return strapi.plugin('i18n').service(name);
|
15
|
-
};
|
16
|
-
|
17
|
-
const registerModelsHooks = ()=>{
|
18
|
-
strapi.db.lifecycles.subscribe({
|
19
|
-
models: [
|
20
|
-
'plugin::i18n.locale'
|
21
|
-
],
|
22
|
-
async afterCreate () {
|
23
|
-
await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();
|
24
|
-
},
|
25
|
-
async afterDelete () {
|
26
|
-
await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();
|
27
|
-
}
|
28
|
-
});
|
29
|
-
strapi.documents.use(async (context, next)=>{
|
30
|
-
const schema = context.contentType;
|
31
|
-
if (![
|
32
|
-
'create',
|
33
|
-
'update',
|
34
|
-
'discardDraft',
|
35
|
-
'publish'
|
36
|
-
].includes(context.action)) {
|
37
|
-
return next();
|
38
|
-
}
|
39
|
-
if (!getService('content-types').isLocalizedContentType(schema)) {
|
40
|
-
return next();
|
41
|
-
}
|
42
|
-
// Build a populate array for all non localized fields within the schema
|
43
|
-
const { getNestedPopulateOfNonLocalizedAttributes } = getService('content-types');
|
44
|
-
const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(schema.uid);
|
45
|
-
// Get the result of the document service action
|
46
|
-
const result = await next();
|
47
|
-
// We may not have received a result with everything populated that we need
|
48
|
-
// Use the id and populate built from non localized fields to get the full
|
49
|
-
// result
|
50
|
-
let resultID;
|
51
|
-
// TODO: fix bug where an empty array can be returned
|
52
|
-
if (Array.isArray(result?.entries) && result.entries[0]?.id) {
|
53
|
-
resultID = result.entries[0].id;
|
54
|
-
} else if (result?.id) {
|
55
|
-
resultID = result.id;
|
56
|
-
} else {
|
57
|
-
return result;
|
58
|
-
}
|
59
|
-
if (attributesToPopulate.length > 0) {
|
60
|
-
const populatedResult = await strapi.db.query(schema.uid).findOne({
|
61
|
-
where: {
|
62
|
-
id: resultID
|
63
|
-
},
|
64
|
-
populate: attributesToPopulate
|
65
|
-
});
|
66
|
-
await getService('localizations').syncNonLocalizedAttributes(populatedResult, schema);
|
67
|
-
}
|
68
|
-
return result;
|
69
|
-
});
|
70
|
-
};
|
71
|
-
var bootstrap = (async ()=>{
|
72
|
-
const { sendDidInitializeEvent } = getService('metrics');
|
73
|
-
const { initDefaultLocale } = getService('locales');
|
74
|
-
const { sectionsBuilder, actions, engine } = getService('permissions');
|
75
|
-
// Data
|
76
|
-
await initDefaultLocale();
|
77
|
-
// Sections Builder
|
78
|
-
sectionsBuilder.registerLocalesPropertyHandler();
|
79
|
-
// Actions
|
80
|
-
await actions.registerI18nActions();
|
81
|
-
actions.registerI18nActionsHooks();
|
82
|
-
actions.updateActionsProperties();
|
83
|
-
// Engine/Permissions
|
84
|
-
engine.registerI18nPermissionsHandlers();
|
85
|
-
// Hooks & Models
|
86
|
-
registerModelsHooks();
|
87
|
-
sendDidInitializeEvent();
|
88
|
-
});
|
89
|
-
|
90
|
-
const { ApplicationError: ApplicationError$3 } = errors;
|
91
|
-
// TODO: v5 if implemented in the CM => delete this middleware
|
92
|
-
const validateLocaleCreation = async (ctx, next)=>{
|
93
|
-
const { model } = ctx.params;
|
94
|
-
const { query } = ctx.request;
|
95
|
-
// Prevent empty body
|
96
|
-
if (!ctx.request.body) {
|
97
|
-
ctx.request.body = {};
|
98
|
-
}
|
99
|
-
const body = ctx.request.body;
|
100
|
-
const { getValidLocale, isLocalizedContentType } = getService('content-types');
|
101
|
-
const modelDef = strapi.getModel(model);
|
102
|
-
if (!isLocalizedContentType(modelDef)) {
|
103
|
-
return next();
|
104
|
-
}
|
105
|
-
// Prevent empty string locale
|
106
|
-
const locale = get('locale', query) || get('locale', body) || undefined;
|
107
|
-
// cleanup to avoid creating duplicates in single types
|
108
|
-
ctx.request.query = {};
|
109
|
-
let entityLocale;
|
110
|
-
try {
|
111
|
-
entityLocale = await getValidLocale(locale);
|
112
|
-
} catch (e) {
|
113
|
-
throw new ApplicationError$3("This locale doesn't exist");
|
114
|
-
}
|
115
|
-
body.locale = entityLocale;
|
116
|
-
if (modelDef.kind === 'singleType') {
|
117
|
-
const entity = await strapi.entityService.findMany(modelDef.uid, {
|
118
|
-
locale: entityLocale
|
119
|
-
}); // TODO: add this type to entityService
|
120
|
-
ctx.request.query.locale = body.locale;
|
121
|
-
// updating
|
122
|
-
if (entity) {
|
123
|
-
return next();
|
124
|
-
}
|
125
|
-
}
|
126
|
-
return next();
|
127
|
-
};
|
128
|
-
|
129
|
-
const { ValidationError } = errors;
|
130
|
-
const LOCALE_SCALAR_TYPENAME = 'I18NLocaleCode';
|
131
|
-
const LOCALE_ARG_PLUGIN_NAME = 'I18NLocaleArg';
|
132
|
-
var graphqlProvider = (({ strapi: strapi1 })=>({
|
133
|
-
register () {
|
134
|
-
const { service: getGraphQLService } = strapi1.plugin('graphql');
|
135
|
-
const { service: getI18NService } = strapi1.plugin('i18n');
|
136
|
-
const { isLocalizedContentType } = getI18NService('content-types');
|
137
|
-
const extensionService = getGraphQLService('extension');
|
138
|
-
extensionService.shadowCRUD('plugin::i18n.locale').disableMutations();
|
139
|
-
// Disable unwanted fields for localized content types
|
140
|
-
Object.entries(strapi1.contentTypes).forEach(([uid, ct])=>{
|
141
|
-
if (isLocalizedContentType(ct)) {
|
142
|
-
// Disable locale field in localized inputs
|
143
|
-
extensionService.shadowCRUD(uid).field('locale').disableInput();
|
144
|
-
// Disable localizations field in localized inputs
|
145
|
-
extensionService.shadowCRUD(uid).field('localizations').disableInput();
|
146
|
-
}
|
147
|
-
});
|
148
|
-
extensionService.use(({ nexus, typeRegistry })=>{
|
149
|
-
const i18nLocaleArgPlugin = getI18nLocaleArgPlugin({
|
150
|
-
nexus,
|
151
|
-
typeRegistry
|
152
|
-
});
|
153
|
-
const i18nLocaleScalar = getLocaleScalar({
|
154
|
-
nexus
|
155
|
-
});
|
156
|
-
return {
|
157
|
-
plugins: [
|
158
|
-
i18nLocaleArgPlugin
|
159
|
-
],
|
160
|
-
types: [
|
161
|
-
i18nLocaleScalar
|
162
|
-
],
|
163
|
-
resolversConfig: {
|
164
|
-
// Modify the default scope associated to find and findOne locale queries to match the actual action name
|
165
|
-
'Query.i18NLocale': {
|
166
|
-
auth: {
|
167
|
-
scope: 'plugin::i18n.locales.listLocales'
|
168
|
-
}
|
169
|
-
},
|
170
|
-
'Query.i18NLocales': {
|
171
|
-
auth: {
|
172
|
-
scope: 'plugin::i18n.locales.listLocales'
|
173
|
-
}
|
174
|
-
}
|
175
|
-
}
|
176
|
-
};
|
177
|
-
});
|
178
|
-
}
|
179
|
-
}));
|
180
|
-
const getLocaleScalar = ({ nexus })=>{
|
181
|
-
const { service: getI18NService } = strapi.plugin('i18n');
|
182
|
-
const locales = getI18NService('iso-locales').getIsoLocales();
|
183
|
-
return nexus.scalarType({
|
184
|
-
name: LOCALE_SCALAR_TYPENAME,
|
185
|
-
description: 'A string used to identify an i18n locale',
|
186
|
-
serialize: identity,
|
187
|
-
parseValue: identity,
|
188
|
-
parseLiteral (ast) {
|
189
|
-
if (ast.kind !== 'StringValue') {
|
190
|
-
throw new ValidationError('Locale cannot represent non string type');
|
191
|
-
}
|
192
|
-
const isValidLocale = ast.value === '*' || locales.find(propEq('code', ast.value));
|
193
|
-
if (!isValidLocale) {
|
194
|
-
throw new ValidationError('Unknown locale supplied');
|
195
|
-
}
|
196
|
-
return ast.value;
|
197
|
-
}
|
198
|
-
});
|
199
|
-
};
|
200
|
-
const getI18nLocaleArgPlugin = ({ nexus, typeRegistry })=>{
|
201
|
-
const { service: getI18NService } = strapi.plugin('i18n');
|
202
|
-
const { isLocalizedContentType } = getI18NService('content-types');
|
203
|
-
return nexus.plugin({
|
204
|
-
name: LOCALE_ARG_PLUGIN_NAME,
|
205
|
-
onAddOutputField (config) {
|
206
|
-
// Add the locale arg to the queries on localized CTs
|
207
|
-
const { parentType } = config;
|
208
|
-
// Only target queries or mutations
|
209
|
-
if (parentType !== 'Query' && parentType !== 'Mutation') {
|
210
|
-
return;
|
211
|
-
}
|
212
|
-
let contentType;
|
213
|
-
if (config?.extensions?.strapi?.contentType) {
|
214
|
-
contentType = config.extensions.strapi.contentType;
|
215
|
-
} else {
|
216
|
-
const registryType = typeRegistry.get(config.type);
|
217
|
-
if (!registryType) {
|
218
|
-
return;
|
219
|
-
}
|
220
|
-
contentType = registryType.config.contentType;
|
221
|
-
}
|
222
|
-
// Ignore non-localized content types
|
223
|
-
if (!isLocalizedContentType(contentType)) {
|
224
|
-
return;
|
225
|
-
}
|
226
|
-
if (!config.args) {
|
227
|
-
config.args = {};
|
228
|
-
}
|
229
|
-
config.args.locale = nexus.arg({
|
230
|
-
type: LOCALE_SCALAR_TYPENAME,
|
231
|
-
description: 'The locale to use for the query'
|
232
|
-
});
|
233
|
-
}
|
234
|
-
});
|
235
|
-
};
|
236
|
-
|
237
|
-
var register = (({ strapi })=>{
|
238
|
-
extendContentTypes(strapi);
|
239
|
-
addContentManagerLocaleMiddleware(strapi);
|
240
|
-
});
|
241
|
-
// TODO: v5 if implemented in the CM => delete this middleware
|
242
|
-
/**
|
243
|
-
* Adds middleware on CM creation routes to use i18n locale passed in a specific param
|
244
|
-
* @param {Strapi} strapi
|
245
|
-
*/ const addContentManagerLocaleMiddleware = (strapi)=>{
|
246
|
-
strapi.server.router.use('/content-manager/collection-types/:model', (ctx, next)=>{
|
247
|
-
if (ctx.method === 'POST' || ctx.method === 'PUT') {
|
248
|
-
return validateLocaleCreation(ctx, next);
|
249
|
-
}
|
250
|
-
return next();
|
251
|
-
});
|
252
|
-
strapi.server.router.use('/content-manager/single-types/:model', (ctx, next)=>{
|
253
|
-
if (ctx.method === 'POST' || ctx.method === 'PUT') {
|
254
|
-
return validateLocaleCreation(ctx, next);
|
255
|
-
}
|
256
|
-
return next();
|
257
|
-
});
|
258
|
-
};
|
259
|
-
/**
|
260
|
-
* Adds locale and localization fields to all content types
|
261
|
-
* Even if content type is not localized, it will have these fields
|
262
|
-
* @param {Strapi} strapi
|
263
|
-
*/ const extendContentTypes = (strapi)=>{
|
264
|
-
const { isLocalizedContentType } = getService('content-types');
|
265
|
-
Object.values(strapi.contentTypes).forEach((contentType)=>{
|
266
|
-
const { attributes } = contentType;
|
267
|
-
const isLocalized = isLocalizedContentType(contentType);
|
268
|
-
_.set(attributes, 'locale', {
|
269
|
-
writable: true,
|
270
|
-
private: !isLocalized,
|
271
|
-
configurable: false,
|
272
|
-
visible: false,
|
273
|
-
type: 'string'
|
274
|
-
});
|
275
|
-
_.set(attributes, 'localizations', {
|
276
|
-
type: 'relation',
|
277
|
-
relation: 'oneToMany',
|
278
|
-
target: contentType.uid,
|
279
|
-
writable: false,
|
280
|
-
private: !isLocalized,
|
281
|
-
configurable: false,
|
282
|
-
visible: false,
|
283
|
-
unstable_virtual: true,
|
284
|
-
joinColumn: {
|
285
|
-
name: 'document_id',
|
286
|
-
referencedColumn: 'document_id',
|
287
|
-
referencedTable: strapi.db.metadata.identifiers.getTableName(contentType.collectionName),
|
288
|
-
// ensure the population will not include the results we already loaded
|
289
|
-
on ({ results }) {
|
290
|
-
return {
|
291
|
-
id: {
|
292
|
-
$notIn: results.map((r)=>r.id)
|
293
|
-
}
|
294
|
-
};
|
295
|
-
}
|
296
|
-
}
|
297
|
-
});
|
298
|
-
});
|
299
|
-
if (strapi.plugin('graphql')) {
|
300
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
301
|
-
graphqlProvider({
|
302
|
-
strapi
|
303
|
-
}).register();
|
304
|
-
}
|
305
|
-
};
|
306
|
-
|
307
|
-
var info = {
|
308
|
-
singularName: "locale",
|
309
|
-
pluralName: "locales",
|
310
|
-
collectionName: "locales",
|
311
|
-
displayName: "Locale",
|
312
|
-
description: ""
|
313
|
-
};
|
314
|
-
var options = {};
|
315
|
-
var pluginOptions = {
|
316
|
-
"content-manager": {
|
317
|
-
visible: false
|
318
|
-
},
|
319
|
-
"content-type-builder": {
|
320
|
-
visible: false
|
321
|
-
}
|
322
|
-
};
|
323
|
-
var attributes = {
|
324
|
-
name: {
|
325
|
-
type: "string",
|
326
|
-
min: 1,
|
327
|
-
max: 50,
|
328
|
-
configurable: false
|
329
|
-
},
|
330
|
-
code: {
|
331
|
-
type: "string",
|
332
|
-
unique: true,
|
333
|
-
configurable: false
|
334
|
-
}
|
335
|
-
};
|
336
|
-
var schema = {
|
337
|
-
info: info,
|
338
|
-
options: options,
|
339
|
-
pluginOptions: pluginOptions,
|
340
|
-
attributes: attributes
|
341
|
-
};
|
342
|
-
|
343
|
-
var locale = {
|
344
|
-
schema
|
345
|
-
};
|
346
|
-
|
347
|
-
var contentTypes$1 = {
|
348
|
-
locale
|
349
|
-
};
|
350
|
-
|
351
|
-
const actions = [
|
352
|
-
{
|
353
|
-
section: 'settings',
|
354
|
-
category: 'Internationalization',
|
355
|
-
subCategory: 'Locales',
|
356
|
-
pluginName: 'i18n',
|
357
|
-
displayName: 'Create',
|
358
|
-
uid: 'locale.create'
|
359
|
-
},
|
360
|
-
{
|
361
|
-
section: 'settings',
|
362
|
-
category: 'Internationalization',
|
363
|
-
subCategory: 'Locales',
|
364
|
-
pluginName: 'i18n',
|
365
|
-
displayName: 'Read',
|
366
|
-
uid: 'locale.read',
|
367
|
-
aliases: [
|
368
|
-
{
|
369
|
-
actionId: 'plugin::content-manager.explorer.read',
|
370
|
-
subjects: [
|
371
|
-
'plugin::i18n.locale'
|
372
|
-
]
|
373
|
-
}
|
374
|
-
]
|
375
|
-
},
|
376
|
-
{
|
377
|
-
section: 'settings',
|
378
|
-
category: 'Internationalization',
|
379
|
-
subCategory: 'Locales',
|
380
|
-
pluginName: 'i18n',
|
381
|
-
displayName: 'Update',
|
382
|
-
uid: 'locale.update'
|
383
|
-
},
|
384
|
-
{
|
385
|
-
section: 'settings',
|
386
|
-
category: 'Internationalization',
|
387
|
-
subCategory: 'Locales',
|
388
|
-
pluginName: 'i18n',
|
389
|
-
displayName: 'Delete',
|
390
|
-
uid: 'locale.delete'
|
391
|
-
}
|
392
|
-
];
|
393
|
-
const addLocalesPropertyIfNeeded = ({ value: action })=>{
|
394
|
-
const { section, options: { applyToProperties } } = action;
|
395
|
-
// Only add the locales property to contentTypes' actions
|
396
|
-
if (section !== 'contentTypes') {
|
397
|
-
return;
|
398
|
-
}
|
399
|
-
// If the 'locales' property is already declared within the applyToProperties array, then ignore the next steps
|
400
|
-
if (isArray(applyToProperties) && applyToProperties.includes('locales')) {
|
401
|
-
return;
|
402
|
-
}
|
403
|
-
// Add the 'locales' property to the applyToProperties array (create it if necessary)
|
404
|
-
action.options.applyToProperties = isArray(applyToProperties) ? applyToProperties.concat('locales') : [
|
405
|
-
'locales'
|
406
|
-
];
|
407
|
-
};
|
408
|
-
const shouldApplyLocalesPropertyToSubject = ({ property, subject })=>{
|
409
|
-
if (property === 'locales') {
|
410
|
-
const model = strapi.getModel(subject);
|
411
|
-
return getService('content-types').isLocalizedContentType(model);
|
412
|
-
}
|
413
|
-
return true;
|
414
|
-
};
|
415
|
-
const addAllLocalesToPermissions = async (permissions)=>{
|
416
|
-
const { actionProvider } = strapi.service('admin::permission');
|
417
|
-
const { find: findAllLocales } = getService('locales');
|
418
|
-
const allLocales = await findAllLocales();
|
419
|
-
const allLocalesCode = allLocales.map(prop('code'));
|
420
|
-
return Promise.all(permissions.map(async (permission)=>{
|
421
|
-
const { action, subject } = permission;
|
422
|
-
const appliesToLocalesProperty = await actionProvider.appliesToProperty('locales', action, subject);
|
423
|
-
if (!appliesToLocalesProperty) {
|
424
|
-
return permission;
|
425
|
-
}
|
426
|
-
const oldPermissionProperties = getOr({}, 'properties', permission);
|
427
|
-
return {
|
428
|
-
...permission,
|
429
|
-
properties: {
|
430
|
-
...oldPermissionProperties,
|
431
|
-
locales: allLocalesCode
|
432
|
-
}
|
433
|
-
};
|
434
|
-
}));
|
435
|
-
};
|
436
|
-
const syncSuperAdminPermissionsWithLocales = async ()=>{
|
437
|
-
const roleService = strapi.service('admin::role');
|
438
|
-
const permissionService = strapi.service('admin::permission');
|
439
|
-
const superAdminRole = await roleService.getSuperAdmin();
|
440
|
-
if (!superAdminRole) {
|
441
|
-
return;
|
442
|
-
}
|
443
|
-
const superAdminPermissions = await permissionService.findMany({
|
444
|
-
where: {
|
445
|
-
role: {
|
446
|
-
id: superAdminRole.id
|
447
|
-
}
|
448
|
-
}
|
449
|
-
});
|
450
|
-
const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);
|
451
|
-
await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);
|
452
|
-
};
|
453
|
-
const registerI18nActions = async ()=>{
|
454
|
-
const { actionProvider } = strapi.service('admin::permission');
|
455
|
-
await actionProvider.registerMany(actions);
|
456
|
-
};
|
457
|
-
const registerI18nActionsHooks = ()=>{
|
458
|
-
const { actionProvider } = strapi.service('admin::permission');
|
459
|
-
const { hooks } = strapi.service('admin::role');
|
460
|
-
actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);
|
461
|
-
hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);
|
462
|
-
};
|
463
|
-
const updateActionsProperties = ()=>{
|
464
|
-
const { actionProvider } = strapi.service('admin::permission');
|
465
|
-
// Register the transformation for every new action
|
466
|
-
actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);
|
467
|
-
// Handle already registered actions
|
468
|
-
actionProvider.values().forEach((action)=>addLocalesPropertyIfNeeded({
|
469
|
-
value: action
|
470
|
-
}));
|
471
|
-
};
|
472
|
-
var i18nActionsService = {
|
473
|
-
actions,
|
474
|
-
registerI18nActions,
|
475
|
-
registerI18nActionsHooks,
|
476
|
-
updateActionsProperties,
|
477
|
-
syncSuperAdminPermissionsWithLocales
|
478
|
-
};
|
479
|
-
|
480
|
-
/**
|
481
|
-
* Handler for the permissions layout (sections builder)
|
482
|
-
* Adds the locales property to the subjects
|
483
|
-
* @param {Action} action
|
484
|
-
* @param {ContentTypesSection} section
|
485
|
-
* @return {Promise<void>}
|
486
|
-
*/ const localesPropertyHandler = async ({ action, section })=>{
|
487
|
-
const { actionProvider } = strapi.service('admin::permission');
|
488
|
-
const locales = await getService('locales').find();
|
489
|
-
// Do not add the locales property if there is none registered
|
490
|
-
if (isEmpty(locales)) {
|
491
|
-
return;
|
492
|
-
}
|
493
|
-
for (const subject of section.subjects){
|
494
|
-
const applies = await actionProvider.appliesToProperty('locales', action.actionId, subject.uid);
|
495
|
-
const hasLocalesProperty = subject.properties.find((property)=>property.value === 'locales');
|
496
|
-
if (applies && !hasLocalesProperty) {
|
497
|
-
subject.properties.push({
|
498
|
-
label: 'Locales',
|
499
|
-
value: 'locales',
|
500
|
-
children: locales.map(({ name, code })=>({
|
501
|
-
label: name || code,
|
502
|
-
value: code
|
503
|
-
}))
|
504
|
-
});
|
505
|
-
}
|
506
|
-
}
|
507
|
-
};
|
508
|
-
const registerLocalesPropertyHandler = ()=>{
|
509
|
-
const { sectionsBuilder } = strapi.service('admin::permission');
|
510
|
-
sectionsBuilder.addHandler('singleTypes', localesPropertyHandler);
|
511
|
-
sectionsBuilder.addHandler('collectionTypes', localesPropertyHandler);
|
512
|
-
};
|
513
|
-
var sectionsBuilderService = {
|
514
|
-
localesPropertyHandler,
|
515
|
-
registerLocalesPropertyHandler
|
516
|
-
};
|
517
|
-
|
518
|
-
/**
|
519
|
-
* @typedef {object} WillRegisterPermissionContext
|
520
|
-
* @property {Permission} permission
|
521
|
-
* @property {object} user
|
522
|
-
* @property {object} condition
|
523
|
-
*/ /**
|
524
|
-
* Locales property handler for the permission engine
|
525
|
-
* Add the has-locale-access condition if the locales property is defined
|
526
|
-
* @param {WillRegisterPermissionContext} context
|
527
|
-
*/ const willRegisterPermission = (context)=>{
|
528
|
-
const { permission, condition, user } = context;
|
529
|
-
const { subject, properties } = permission;
|
530
|
-
const isSuperAdmin = strapi.service('admin::role').hasSuperAdminRole(user);
|
531
|
-
if (isSuperAdmin) {
|
532
|
-
return;
|
533
|
-
}
|
534
|
-
const { locales } = properties || {};
|
535
|
-
const { isLocalizedContentType } = getService('content-types');
|
536
|
-
// If there is no subject defined, ignore the permission
|
537
|
-
if (!subject) {
|
538
|
-
return;
|
539
|
-
}
|
540
|
-
const ct = strapi.contentTypes[subject];
|
541
|
-
// If the subject exists but isn't localized, ignore the permission
|
542
|
-
if (!isLocalizedContentType(ct)) {
|
543
|
-
return;
|
544
|
-
}
|
545
|
-
// If the subject is localized but the locales property is null (access to all locales), ignore the permission
|
546
|
-
if (locales === null) {
|
547
|
-
return;
|
548
|
-
}
|
549
|
-
condition.and({
|
550
|
-
locale: {
|
551
|
-
$in: locales || []
|
552
|
-
}
|
553
|
-
});
|
554
|
-
};
|
555
|
-
const registerI18nPermissionsHandlers = ()=>{
|
556
|
-
const { engine } = strapi.service('admin::permission');
|
557
|
-
engine.hooks['before-register.permission'].register(willRegisterPermission);
|
558
|
-
};
|
559
|
-
var engineService = {
|
560
|
-
willRegisterPermission,
|
561
|
-
registerI18nPermissionsHandlers
|
562
|
-
};
|
563
|
-
|
564
|
-
const permissions = ()=>({
|
565
|
-
actions: i18nActionsService,
|
566
|
-
sectionsBuilder: sectionsBuilderService,
|
567
|
-
engine: engineService
|
568
|
-
});
|
569
|
-
|
570
|
-
const sendDidInitializeEvent = async ()=>{
|
571
|
-
const { isLocalizedContentType } = getService('content-types');
|
572
|
-
// TODO: V5: This event should be renamed numberOfContentTypes in V5 as the name is already taken to describe the number of content types using i18n.
|
573
|
-
const numberOfContentTypes = reduce((sum, contentType)=>isLocalizedContentType(contentType) ? sum + 1 : sum, 0)(strapi.contentTypes);
|
574
|
-
await strapi.telemetry.send('didInitializeI18n', {
|
575
|
-
groupProperties: {
|
576
|
-
numberOfContentTypes
|
577
|
-
}
|
578
|
-
});
|
579
|
-
};
|
580
|
-
const sendDidUpdateI18nLocalesEvent = async ()=>{
|
581
|
-
const numberOfLocales = await getService('locales').count();
|
582
|
-
await strapi.telemetry.send('didUpdateI18nLocales', {
|
583
|
-
groupProperties: {
|
584
|
-
numberOfLocales
|
585
|
-
}
|
586
|
-
});
|
587
|
-
};
|
588
|
-
const metrics = ()=>({
|
589
|
-
sendDidInitializeEvent,
|
590
|
-
sendDidUpdateI18nLocalesEvent
|
591
|
-
});
|
592
|
-
|
593
|
-
/**
|
594
|
-
* Update non localized fields of all the related localizations of an entry with the entry values
|
595
|
-
*/ const syncNonLocalizedAttributes = async (sourceEntry, model)=>{
|
596
|
-
const { copyNonLocalizedAttributes } = getService('content-types');
|
597
|
-
const nonLocalizedAttributes = copyNonLocalizedAttributes(model, sourceEntry);
|
598
|
-
if (isEmpty(nonLocalizedAttributes)) {
|
599
|
-
return;
|
600
|
-
}
|
601
|
-
const uid = model.uid;
|
602
|
-
const documentId = sourceEntry.documentId;
|
603
|
-
const locale = sourceEntry.locale;
|
604
|
-
const status = sourceEntry?.publishedAt ? 'published' : 'draft';
|
605
|
-
// Find all the entries that need to be updated
|
606
|
-
// this is every other entry of the document in the same status but a different locale
|
607
|
-
const localeEntriesToUpdate = await strapi.db.query(uid).findMany({
|
608
|
-
where: {
|
609
|
-
documentId,
|
610
|
-
publishedAt: status === 'published' ? {
|
611
|
-
$ne: null
|
612
|
-
} : null,
|
613
|
-
locale: {
|
614
|
-
$ne: locale
|
615
|
-
}
|
616
|
-
},
|
617
|
-
select: [
|
618
|
-
'locale',
|
619
|
-
'id'
|
620
|
-
]
|
621
|
-
});
|
622
|
-
const entryData = await strapi.documents(uid).omitComponentData(nonLocalizedAttributes);
|
623
|
-
await async.map(localeEntriesToUpdate, async (entry)=>{
|
624
|
-
const transformedData = await strapi.documents.utils.transformData(cloneDeep(nonLocalizedAttributes), {
|
625
|
-
uid,
|
626
|
-
status,
|
627
|
-
locale: entry.locale,
|
628
|
-
allowMissingId: true
|
629
|
-
});
|
630
|
-
// Update or create non localized components for the entry
|
631
|
-
const componentData = await strapi.documents(uid).updateComponents(entry, transformedData);
|
632
|
-
// Update every other locale entry of this documentId in the same status
|
633
|
-
await strapi.db.query(uid).update({
|
634
|
-
where: {
|
635
|
-
documentId,
|
636
|
-
publishedAt: status === 'published' ? {
|
637
|
-
$ne: null
|
638
|
-
} : null,
|
639
|
-
locale: {
|
640
|
-
$eq: entry.locale
|
641
|
-
}
|
642
|
-
},
|
643
|
-
// The data we send to the update function is the entry data merged with
|
644
|
-
// the updated component data
|
645
|
-
data: Object.assign(cloneDeep(entryData), componentData)
|
646
|
-
});
|
647
|
-
});
|
648
|
-
};
|
649
|
-
const localizations = ()=>({
|
650
|
-
syncNonLocalizedAttributes
|
651
|
-
});
|
652
|
-
|
653
|
-
var isoLocales = [
|
654
|
-
{
|
655
|
-
code: "af",
|
656
|
-
name: "Afrikaans (af)"
|
657
|
-
},
|
658
|
-
{
|
659
|
-
code: "af-NA",
|
660
|
-
name: "Afrikaans (Namibia) (af-NA)"
|
661
|
-
},
|
662
|
-
{
|
663
|
-
code: "af-ZA",
|
664
|
-
name: "Afrikaans (South Africa) (af-ZA)"
|
665
|
-
},
|
666
|
-
{
|
667
|
-
code: "agq",
|
668
|
-
name: "Aghem (agq)"
|
669
|
-
},
|
670
|
-
{
|
671
|
-
code: "agq-CM",
|
672
|
-
name: "Aghem (Cameroon) (agq-CM)"
|
673
|
-
},
|
674
|
-
{
|
675
|
-
code: "ak",
|
676
|
-
name: "Akan (ak)"
|
677
|
-
},
|
678
|
-
{
|
679
|
-
code: "ak-GH",
|
680
|
-
name: "Akan (Ghana) (ak-GH)"
|
681
|
-
},
|
682
|
-
{
|
683
|
-
code: "sq",
|
684
|
-
name: "Albanian (sq)"
|
685
|
-
},
|
686
|
-
{
|
687
|
-
code: "sq-AL",
|
688
|
-
name: "Albanian (Albania) (sq-AL)"
|
689
|
-
},
|
690
|
-
{
|
691
|
-
code: "am",
|
692
|
-
name: "Amharic (am)"
|
693
|
-
},
|
694
|
-
{
|
695
|
-
code: "am-ET",
|
696
|
-
name: "Amharic (Ethiopia) (am-ET)"
|
697
|
-
},
|
698
|
-
{
|
699
|
-
code: "aig",
|
700
|
-
name: "Antigua and Barbuda Creole English"
|
701
|
-
},
|
702
|
-
{
|
703
|
-
code: "ar",
|
704
|
-
name: "Arabic (ar)"
|
705
|
-
},
|
706
|
-
{
|
707
|
-
code: "ar-DZ",
|
708
|
-
name: "Arabic (Algeria) (ar-DZ)"
|
709
|
-
},
|
710
|
-
{
|
711
|
-
code: "ar-BH",
|
712
|
-
name: "Arabic (Bahrain) (ar-BH)"
|
713
|
-
},
|
714
|
-
{
|
715
|
-
code: "ar-EG",
|
716
|
-
name: "Arabic (Egypt) (ar-EG)"
|
717
|
-
},
|
718
|
-
{
|
719
|
-
code: "ar-IQ",
|
720
|
-
name: "Arabic (Iraq) (ar-IQ)"
|
721
|
-
},
|
722
|
-
{
|
723
|
-
code: "ar-JO",
|
724
|
-
name: "Arabic (Jordan) (ar-JO)"
|
725
|
-
},
|
726
|
-
{
|
727
|
-
code: "ar-KW",
|
728
|
-
name: "Arabic (Kuwait) (ar-KW)"
|
729
|
-
},
|
730
|
-
{
|
731
|
-
code: "ar-LB",
|
732
|
-
name: "Arabic (Lebanon) (ar-LB)"
|
733
|
-
},
|
734
|
-
{
|
735
|
-
code: "ar-LY",
|
736
|
-
name: "Arabic (Libya) (ar-LY)"
|
737
|
-
},
|
738
|
-
{
|
739
|
-
code: "ar-MA",
|
740
|
-
name: "Arabic (Morocco) (ar-MA)"
|
741
|
-
},
|
742
|
-
{
|
743
|
-
code: "ar-OM",
|
744
|
-
name: "Arabic (Oman) (ar-OM)"
|
745
|
-
},
|
746
|
-
{
|
747
|
-
code: "ar-QA",
|
748
|
-
name: "Arabic (Qatar) (ar-QA)"
|
749
|
-
},
|
750
|
-
{
|
751
|
-
code: "ar-SA",
|
752
|
-
name: "Arabic (Saudi Arabia) (ar-SA)"
|
753
|
-
},
|
754
|
-
{
|
755
|
-
code: "ar-SD",
|
756
|
-
name: "Arabic (Sudan) (ar-SD)"
|
757
|
-
},
|
758
|
-
{
|
759
|
-
code: "ar-SY",
|
760
|
-
name: "Arabic (Syria) (ar-SY)"
|
761
|
-
},
|
762
|
-
{
|
763
|
-
code: "ar-TN",
|
764
|
-
name: "Arabic (Tunisia) (ar-TN)"
|
765
|
-
},
|
766
|
-
{
|
767
|
-
code: "ar-AE",
|
768
|
-
name: "Arabic (United Arab Emirates) (ar-AE)"
|
769
|
-
},
|
770
|
-
{
|
771
|
-
code: "ar-001",
|
772
|
-
name: "Arabic (World) (ar-001)"
|
773
|
-
},
|
774
|
-
{
|
775
|
-
code: "ar-YE",
|
776
|
-
name: "Arabic (Yemen) (ar-YE)"
|
777
|
-
},
|
778
|
-
{
|
779
|
-
code: "hy",
|
780
|
-
name: "Armenian (hy)"
|
781
|
-
},
|
782
|
-
{
|
783
|
-
code: "hy-AM",
|
784
|
-
name: "Armenian (Armenia) (hy-AM)"
|
785
|
-
},
|
786
|
-
{
|
787
|
-
code: "as",
|
788
|
-
name: "Assamese (as)"
|
789
|
-
},
|
790
|
-
{
|
791
|
-
code: "as-IN",
|
792
|
-
name: "Assamese (India) (as-IN)"
|
793
|
-
},
|
794
|
-
{
|
795
|
-
code: "ast",
|
796
|
-
name: "Asturian (ast)"
|
797
|
-
},
|
798
|
-
{
|
799
|
-
code: "ast-ES",
|
800
|
-
name: "Asturian (Spain) (ast-ES)"
|
801
|
-
},
|
802
|
-
{
|
803
|
-
code: "asa",
|
804
|
-
name: "Asu (asa)"
|
805
|
-
},
|
806
|
-
{
|
807
|
-
code: "asa-TZ",
|
808
|
-
name: "Asu (Tanzania) (asa-TZ)"
|
809
|
-
},
|
810
|
-
{
|
811
|
-
code: "az",
|
812
|
-
name: "Azerbaijani (az)"
|
813
|
-
},
|
814
|
-
{
|
815
|
-
code: "az-Cyrl",
|
816
|
-
name: "Azerbaijani (Cyrillic) (az-Cyrl)"
|
817
|
-
},
|
818
|
-
{
|
819
|
-
code: "az-Cyrl-AZ",
|
820
|
-
name: "Azerbaijani (Cyrillic, Azerbaijan) (az-Cyrl-AZ)"
|
821
|
-
},
|
822
|
-
{
|
823
|
-
code: "az-Latn",
|
824
|
-
name: "Azerbaijani (Latin) (az-Latn)"
|
825
|
-
},
|
826
|
-
{
|
827
|
-
code: "az-Latn-AZ",
|
828
|
-
name: "Azerbaijani (Latin, Azerbaijan) (az-Latn-AZ)"
|
829
|
-
},
|
830
|
-
{
|
831
|
-
code: "ksf",
|
832
|
-
name: "Bafia (ksf)"
|
833
|
-
},
|
834
|
-
{
|
835
|
-
code: "ksf-CM",
|
836
|
-
name: "Bafia (Cameroon) (ksf-CM)"
|
837
|
-
},
|
838
|
-
{
|
839
|
-
code: "bah",
|
840
|
-
name: "Bahamas Creole English"
|
841
|
-
},
|
842
|
-
{
|
843
|
-
code: "bm",
|
844
|
-
name: "Bambara (bm)"
|
845
|
-
},
|
846
|
-
{
|
847
|
-
code: "bm-ML",
|
848
|
-
name: "Bambara (Mali) (bm-ML)"
|
849
|
-
},
|
850
|
-
{
|
851
|
-
code: "bas",
|
852
|
-
name: "Basaa (bas)"
|
853
|
-
},
|
854
|
-
{
|
855
|
-
code: "bas-CM",
|
856
|
-
name: "Basaa (Cameroon) (bas-CM)"
|
857
|
-
},
|
858
|
-
{
|
859
|
-
code: "eu",
|
860
|
-
name: "Basque (eu)"
|
861
|
-
},
|
862
|
-
{
|
863
|
-
code: "eu-ES",
|
864
|
-
name: "Basque (Spain) (eu-ES)"
|
865
|
-
},
|
866
|
-
{
|
867
|
-
code: "be",
|
868
|
-
name: "Belarusian (be)"
|
869
|
-
},
|
870
|
-
{
|
871
|
-
code: "be-BY",
|
872
|
-
name: "Belarusian (Belarus) (be-BY)"
|
873
|
-
},
|
874
|
-
{
|
875
|
-
code: "bem",
|
876
|
-
name: "Bemba (bem)"
|
877
|
-
},
|
878
|
-
{
|
879
|
-
code: "bem-ZM",
|
880
|
-
name: "Bemba (Zambia) (bem-ZM)"
|
881
|
-
},
|
882
|
-
{
|
883
|
-
code: "bez",
|
884
|
-
name: "Bena (bez)"
|
885
|
-
},
|
886
|
-
{
|
887
|
-
code: "bez-TZ",
|
888
|
-
name: "Bena (Tanzania) (bez-TZ)"
|
889
|
-
},
|
890
|
-
{
|
891
|
-
code: "bn",
|
892
|
-
name: "Bengali (bn)"
|
893
|
-
},
|
894
|
-
{
|
895
|
-
code: "bn-BD",
|
896
|
-
name: "Bengali (Bangladesh) (bn-BD)"
|
897
|
-
},
|
898
|
-
{
|
899
|
-
code: "bn-IN",
|
900
|
-
name: "Bengali (India) (bn-IN)"
|
901
|
-
},
|
902
|
-
{
|
903
|
-
code: "brx",
|
904
|
-
name: "Bodo (brx)"
|
905
|
-
},
|
906
|
-
{
|
907
|
-
code: "brx-IN",
|
908
|
-
name: "Bodo (India) (brx-IN)"
|
909
|
-
},
|
910
|
-
{
|
911
|
-
code: "bs",
|
912
|
-
name: "Bosnian (bs)"
|
913
|
-
},
|
914
|
-
{
|
915
|
-
code: "bs-BA",
|
916
|
-
name: "Bosnian (Bosnia and Herzegovina) (bs-BA)"
|
917
|
-
},
|
918
|
-
{
|
919
|
-
code: "br",
|
920
|
-
name: "Breton (br)"
|
921
|
-
},
|
922
|
-
{
|
923
|
-
code: "br-FR",
|
924
|
-
name: "Breton (France) (br-FR)"
|
925
|
-
},
|
926
|
-
{
|
927
|
-
code: "bg",
|
928
|
-
name: "Bulgarian (bg)"
|
929
|
-
},
|
930
|
-
{
|
931
|
-
code: "bg-BG",
|
932
|
-
name: "Bulgarian (Bulgaria) (bg-BG)"
|
933
|
-
},
|
934
|
-
{
|
935
|
-
code: "my",
|
936
|
-
name: "Burmese (my)"
|
937
|
-
},
|
938
|
-
{
|
939
|
-
code: "my-MM",
|
940
|
-
name: "Burmese (Myanmar [Burma]) (my-MM)"
|
941
|
-
},
|
942
|
-
{
|
943
|
-
code: "ca",
|
944
|
-
name: "Catalan (ca)"
|
945
|
-
},
|
946
|
-
{
|
947
|
-
code: "ca-ES",
|
948
|
-
name: "Catalan (Spain) (ca-ES)"
|
949
|
-
},
|
950
|
-
{
|
951
|
-
code: "ckb",
|
952
|
-
name: "Central Kurdish (ckb)"
|
953
|
-
},
|
954
|
-
{
|
955
|
-
code: "kmr",
|
956
|
-
name: "Northern Kurdish (kmr)"
|
957
|
-
},
|
958
|
-
{
|
959
|
-
code: "sdh",
|
960
|
-
name: "Southern Kurdish (sdh)"
|
961
|
-
},
|
962
|
-
{
|
963
|
-
code: "tzm",
|
964
|
-
name: "Central Morocco Tamazight (tzm)"
|
965
|
-
},
|
966
|
-
{
|
967
|
-
code: "tzm-Latn",
|
968
|
-
name: "Central Morocco Tamazight (Latin) (tzm-Latn)"
|
969
|
-
},
|
970
|
-
{
|
971
|
-
code: "tzm-Latn-MA",
|
972
|
-
name: "Central Morocco Tamazight (Latin, Morocco) (tzm-Latn-MA) "
|
973
|
-
},
|
974
|
-
{
|
975
|
-
code: "chr",
|
976
|
-
name: "Cherokee (chr)"
|
977
|
-
},
|
978
|
-
{
|
979
|
-
code: "chr-US",
|
980
|
-
name: "Cherokee (United States) (chr-US)"
|
981
|
-
},
|
982
|
-
{
|
983
|
-
code: "cgg",
|
984
|
-
name: "Chiga (cgg)"
|
985
|
-
},
|
986
|
-
{
|
987
|
-
code: "cgg-UG",
|
988
|
-
name: "Chiga (Uganda) (cgg-UG)"
|
989
|
-
},
|
990
|
-
{
|
991
|
-
code: "zh",
|
992
|
-
name: "Chinese (zh)"
|
993
|
-
},
|
994
|
-
{
|
995
|
-
code: "zh-Hans",
|
996
|
-
name: "Chinese (Simplified) (zh-Hans)"
|
997
|
-
},
|
998
|
-
{
|
999
|
-
code: "zh-CN",
|
1000
|
-
name: "Chinese (Simplified, China) (zh-CN)"
|
1001
|
-
},
|
1002
|
-
{
|
1003
|
-
code: "zh-Hans-CN",
|
1004
|
-
name: "Chinese (Simplified, China) (zh-Hans-CN)"
|
1005
|
-
},
|
1006
|
-
{
|
1007
|
-
code: "zh-Hans-HK",
|
1008
|
-
name: "Chinese (Simplified, Hong Kong SAR China) (zh-Hans-HK)"
|
1009
|
-
},
|
1010
|
-
{
|
1011
|
-
code: "zh-Hans-MO",
|
1012
|
-
name: "Chinese (Simplified, Macau SAR China) (zh-Hans-MO) "
|
1013
|
-
},
|
1014
|
-
{
|
1015
|
-
code: "zh-Hans-SG",
|
1016
|
-
name: "Chinese (Simplified, Singapore) (zh-Hans-SG)"
|
1017
|
-
},
|
1018
|
-
{
|
1019
|
-
code: "zh-Hant",
|
1020
|
-
name: "Chinese (Traditional) (zh-Hant)"
|
1021
|
-
},
|
1022
|
-
{
|
1023
|
-
code: "zh-Hant-HK",
|
1024
|
-
name: "Chinese (Traditional, Hong Kong SAR China) (zh-Hant-HK) "
|
1025
|
-
},
|
1026
|
-
{
|
1027
|
-
code: "zh-Hant-MO",
|
1028
|
-
name: "Chinese (Traditional, Macau SAR China) (zh-Hant-MO) "
|
1029
|
-
},
|
1030
|
-
{
|
1031
|
-
code: "zh-Hant-TW",
|
1032
|
-
name: "Chinese (Traditional, Taiwan) (zh-Hant-TW)"
|
1033
|
-
},
|
1034
|
-
{
|
1035
|
-
code: "swc",
|
1036
|
-
name: "Congo Swahili (swc)"
|
1037
|
-
},
|
1038
|
-
{
|
1039
|
-
code: "swc-CD",
|
1040
|
-
name: "Congo Swahili (Congo - Kinshasa) (swc-CD)"
|
1041
|
-
},
|
1042
|
-
{
|
1043
|
-
code: "kw",
|
1044
|
-
name: "Cornish (kw)"
|
1045
|
-
},
|
1046
|
-
{
|
1047
|
-
code: "kw-GB",
|
1048
|
-
name: "Cornish (United Kingdom) (kw-GB)"
|
1049
|
-
},
|
1050
|
-
{
|
1051
|
-
code: "hr",
|
1052
|
-
name: "Croatian (hr)"
|
1053
|
-
},
|
1054
|
-
{
|
1055
|
-
code: "hr-HR",
|
1056
|
-
name: "Croatian (Croatia) (hr-HR)"
|
1057
|
-
},
|
1058
|
-
{
|
1059
|
-
code: "cs",
|
1060
|
-
name: "Czech (cs)"
|
1061
|
-
},
|
1062
|
-
{
|
1063
|
-
code: "cs-CZ",
|
1064
|
-
name: "Czech (Czech Republic) (cs-CZ)"
|
1065
|
-
},
|
1066
|
-
{
|
1067
|
-
code: "da",
|
1068
|
-
name: "Danish (da)"
|
1069
|
-
},
|
1070
|
-
{
|
1071
|
-
code: "da-DK",
|
1072
|
-
name: "Danish (Denmark) (da-DK)"
|
1073
|
-
},
|
1074
|
-
{
|
1075
|
-
code: "dua",
|
1076
|
-
name: "Duala (dua)"
|
1077
|
-
},
|
1078
|
-
{
|
1079
|
-
code: "dua-CM",
|
1080
|
-
name: "Duala (Cameroon) (dua-CM)"
|
1081
|
-
},
|
1082
|
-
{
|
1083
|
-
code: "dv",
|
1084
|
-
name: "Dhivehi (Maldives)"
|
1085
|
-
},
|
1086
|
-
{
|
1087
|
-
code: "nl",
|
1088
|
-
name: "Dutch (nl)"
|
1089
|
-
},
|
1090
|
-
{
|
1091
|
-
code: "nl-AW",
|
1092
|
-
name: "Dutch (Aruba) (nl-AW)"
|
1093
|
-
},
|
1094
|
-
{
|
1095
|
-
code: "nl-BE",
|
1096
|
-
name: "Dutch (Belgium) (nl-BE)"
|
1097
|
-
},
|
1098
|
-
{
|
1099
|
-
code: "nl-CW",
|
1100
|
-
name: "Dutch (Curaçao) (nl-CW)"
|
1101
|
-
},
|
1102
|
-
{
|
1103
|
-
code: "nl-NL",
|
1104
|
-
name: "Dutch (Netherlands) (nl-NL)"
|
1105
|
-
},
|
1106
|
-
{
|
1107
|
-
code: "nl-SX",
|
1108
|
-
name: "Dutch (Sint Maarten) (nl-SX)"
|
1109
|
-
},
|
1110
|
-
{
|
1111
|
-
code: "ebu",
|
1112
|
-
name: "Embu (ebu)"
|
1113
|
-
},
|
1114
|
-
{
|
1115
|
-
code: "ebu-KE",
|
1116
|
-
name: "Embu (Kenya) (ebu-KE)"
|
1117
|
-
},
|
1118
|
-
{
|
1119
|
-
code: "en",
|
1120
|
-
name: "English (en)"
|
1121
|
-
},
|
1122
|
-
{
|
1123
|
-
code: "en-AI",
|
1124
|
-
name: "English (Anguilla) (en-AI)"
|
1125
|
-
},
|
1126
|
-
{
|
1127
|
-
code: "en-AS",
|
1128
|
-
name: "English (American Samoa) (en-AS)"
|
1129
|
-
},
|
1130
|
-
{
|
1131
|
-
code: "en-AU",
|
1132
|
-
name: "English (Australia) (en-AU)"
|
1133
|
-
},
|
1134
|
-
{
|
1135
|
-
code: "en-AT",
|
1136
|
-
name: "English (Austria) (en-AT)"
|
1137
|
-
},
|
1138
|
-
{
|
1139
|
-
code: "en-BB",
|
1140
|
-
name: "English (Barbados) (en-BB)"
|
1141
|
-
},
|
1142
|
-
{
|
1143
|
-
code: "en-BE",
|
1144
|
-
name: "English (Belgium) (en-BE)"
|
1145
|
-
},
|
1146
|
-
{
|
1147
|
-
code: "en-BZ",
|
1148
|
-
name: "English (Belize) (en-BZ)"
|
1149
|
-
},
|
1150
|
-
{
|
1151
|
-
code: "en-BM",
|
1152
|
-
name: "English (Bermuda) (en-BM)"
|
1153
|
-
},
|
1154
|
-
{
|
1155
|
-
code: "en-BW",
|
1156
|
-
name: "English (Botswana) (en-BW)"
|
1157
|
-
},
|
1158
|
-
{
|
1159
|
-
code: "en-IO",
|
1160
|
-
name: "English (British Indian Ocean Territory) (en-IO)"
|
1161
|
-
},
|
1162
|
-
{
|
1163
|
-
code: "en-BI",
|
1164
|
-
name: "English (Burundi) (en-BI)"
|
1165
|
-
},
|
1166
|
-
{
|
1167
|
-
code: "en-CM",
|
1168
|
-
name: "English (Cameroon) (en-CM)"
|
1169
|
-
},
|
1170
|
-
{
|
1171
|
-
code: "en-CA",
|
1172
|
-
name: "English (Canada) (en-CA)"
|
1173
|
-
},
|
1174
|
-
{
|
1175
|
-
code: "en-KY",
|
1176
|
-
name: "English (Cayman Islands) (en-KY)"
|
1177
|
-
},
|
1178
|
-
{
|
1179
|
-
code: "en-CX",
|
1180
|
-
name: "English (Christmas Island) (en-CX)"
|
1181
|
-
},
|
1182
|
-
{
|
1183
|
-
code: "en-CC",
|
1184
|
-
name: "English (Cocos [Keeling] Islands) (en-CC)"
|
1185
|
-
},
|
1186
|
-
{
|
1187
|
-
code: "en-CK",
|
1188
|
-
name: "English (Cook Islands) (en-CK)"
|
1189
|
-
},
|
1190
|
-
{
|
1191
|
-
code: "en-CY",
|
1192
|
-
name: "English (Cyprus) (en-CY)"
|
1193
|
-
},
|
1194
|
-
{
|
1195
|
-
code: "en-DK",
|
1196
|
-
name: "English (Denmark) (en-DK)"
|
1197
|
-
},
|
1198
|
-
{
|
1199
|
-
code: "en-DG",
|
1200
|
-
name: "English (Diego Garcia) (en-DG)"
|
1201
|
-
},
|
1202
|
-
{
|
1203
|
-
code: "en-DM",
|
1204
|
-
name: "English (Dominica) (en-DM)"
|
1205
|
-
},
|
1206
|
-
{
|
1207
|
-
code: "en-EG",
|
1208
|
-
name: "English (Egypt) (en-EG)"
|
1209
|
-
},
|
1210
|
-
{
|
1211
|
-
code: "en-ER",
|
1212
|
-
name: "English (Eritrea) (en-ER)"
|
1213
|
-
},
|
1214
|
-
{
|
1215
|
-
code: "en-EU",
|
1216
|
-
name: "English (Europe) (en-EU)"
|
1217
|
-
},
|
1218
|
-
{
|
1219
|
-
code: "en-FK",
|
1220
|
-
name: "English (Falkland Islands) (en-FK)"
|
1221
|
-
},
|
1222
|
-
{
|
1223
|
-
code: "en-FJ",
|
1224
|
-
name: "English (Fiji) (en-FJ)"
|
1225
|
-
},
|
1226
|
-
{
|
1227
|
-
code: "en-FI",
|
1228
|
-
name: "English (Finland) (en-FI)"
|
1229
|
-
},
|
1230
|
-
{
|
1231
|
-
code: "en-GM",
|
1232
|
-
name: "English (Gambia) (en-GM)"
|
1233
|
-
},
|
1234
|
-
{
|
1235
|
-
code: "en-DE",
|
1236
|
-
name: "English (Germany) (en-DE)"
|
1237
|
-
},
|
1238
|
-
{
|
1239
|
-
code: "en-GH",
|
1240
|
-
name: "English (Ghana) (en-GH)"
|
1241
|
-
},
|
1242
|
-
{
|
1243
|
-
code: "en-GI",
|
1244
|
-
name: "English (Gibraltar) (en-GI)"
|
1245
|
-
},
|
1246
|
-
{
|
1247
|
-
code: "en-GD",
|
1248
|
-
name: "English (Grenada) (en-GD)"
|
1249
|
-
},
|
1250
|
-
{
|
1251
|
-
code: "en-GU",
|
1252
|
-
name: "English (Guam) (en-GU)"
|
1253
|
-
},
|
1254
|
-
{
|
1255
|
-
code: "en-GG",
|
1256
|
-
name: "English (Guernsey) (en-GG)"
|
1257
|
-
},
|
1258
|
-
{
|
1259
|
-
code: "en-GY",
|
1260
|
-
name: "English (Guyana) (en-GY)"
|
1261
|
-
},
|
1262
|
-
{
|
1263
|
-
code: "en-HK",
|
1264
|
-
name: "English (Hong Kong SAR China) (en-HK)"
|
1265
|
-
},
|
1266
|
-
{
|
1267
|
-
code: "en-IN",
|
1268
|
-
name: "English (India) (en-IN)"
|
1269
|
-
},
|
1270
|
-
{
|
1271
|
-
code: "en-IE",
|
1272
|
-
name: "English (Ireland) (en-IE)"
|
1273
|
-
},
|
1274
|
-
{
|
1275
|
-
code: "en-IM",
|
1276
|
-
name: "English (Isle of Man) (en-IM)"
|
1277
|
-
},
|
1278
|
-
{
|
1279
|
-
code: "en-IL",
|
1280
|
-
name: "English (Israel) (en-IL)"
|
1281
|
-
},
|
1282
|
-
{
|
1283
|
-
code: "en-JM",
|
1284
|
-
name: "English (Jamaica) (en-JM)"
|
1285
|
-
},
|
1286
|
-
{
|
1287
|
-
code: "en-JE",
|
1288
|
-
name: "English (Jersey) (en-JE)"
|
1289
|
-
},
|
1290
|
-
{
|
1291
|
-
code: "en-KE",
|
1292
|
-
name: "English (Kenya) (en-KE)"
|
1293
|
-
},
|
1294
|
-
{
|
1295
|
-
code: "en-KI",
|
1296
|
-
name: "English (Kiribati) (en-KI)"
|
1297
|
-
},
|
1298
|
-
{
|
1299
|
-
code: "en-KW",
|
1300
|
-
name: "English (Kuwait) (en-KW)"
|
1301
|
-
},
|
1302
|
-
{
|
1303
|
-
code: "en-LS",
|
1304
|
-
name: "English (Lesotho) (en-LS)"
|
1305
|
-
},
|
1306
|
-
{
|
1307
|
-
code: "en-MO",
|
1308
|
-
name: "English (Macao SAR China) (en-MO)"
|
1309
|
-
},
|
1310
|
-
{
|
1311
|
-
code: "en-MG",
|
1312
|
-
name: "English (Madagascar) (en-MG)"
|
1313
|
-
},
|
1314
|
-
{
|
1315
|
-
code: "en-MW",
|
1316
|
-
name: "English (Malawi) (en-MW)"
|
1317
|
-
},
|
1318
|
-
{
|
1319
|
-
code: "en-MY",
|
1320
|
-
name: "English (Malaysia) (en-MY)"
|
1321
|
-
},
|
1322
|
-
{
|
1323
|
-
code: "en-MT",
|
1324
|
-
name: "English (Malta) (en-MT)"
|
1325
|
-
},
|
1326
|
-
{
|
1327
|
-
code: "en-MH",
|
1328
|
-
name: "English (Marshall Islands) (en-MH)"
|
1329
|
-
},
|
1330
|
-
{
|
1331
|
-
code: "en-MU",
|
1332
|
-
name: "English (Mauritius) (en-MU)"
|
1333
|
-
},
|
1334
|
-
{
|
1335
|
-
code: "en-FM",
|
1336
|
-
name: "English (Micronesia) (en-FM)"
|
1337
|
-
},
|
1338
|
-
{
|
1339
|
-
code: "en-MS",
|
1340
|
-
name: "English (Montserrat) (en-MS)"
|
1341
|
-
},
|
1342
|
-
{
|
1343
|
-
code: "en-NA",
|
1344
|
-
name: "English (Namibia) (en-NA)"
|
1345
|
-
},
|
1346
|
-
{
|
1347
|
-
code: "en-NR",
|
1348
|
-
name: "English (Nauru) (en-NR)"
|
1349
|
-
},
|
1350
|
-
{
|
1351
|
-
code: "en-NL",
|
1352
|
-
name: "English (Netherlands) (en-NL)"
|
1353
|
-
},
|
1354
|
-
{
|
1355
|
-
code: "en-NZ",
|
1356
|
-
name: "English (New Zealand) (en-NZ)"
|
1357
|
-
},
|
1358
|
-
{
|
1359
|
-
code: "en-NG",
|
1360
|
-
name: "English (Nigeria) (en-NG)"
|
1361
|
-
},
|
1362
|
-
{
|
1363
|
-
code: "en-NU",
|
1364
|
-
name: "English (Niue) (en-NU)"
|
1365
|
-
},
|
1366
|
-
{
|
1367
|
-
code: "en-NF",
|
1368
|
-
name: "English (Norfolk Island) (en-NF)"
|
1369
|
-
},
|
1370
|
-
{
|
1371
|
-
code: "en-MP",
|
1372
|
-
name: "English (Northern Mariana Islands) (en-MP)"
|
1373
|
-
},
|
1374
|
-
{
|
1375
|
-
code: "en-NO",
|
1376
|
-
name: "English (Norway) (en-NO)"
|
1377
|
-
},
|
1378
|
-
{
|
1379
|
-
code: "en-PA",
|
1380
|
-
name: "English (Panama) (en-PA)"
|
1381
|
-
},
|
1382
|
-
{
|
1383
|
-
code: "en-PK",
|
1384
|
-
name: "English (Pakistan) (en-PK)"
|
1385
|
-
},
|
1386
|
-
{
|
1387
|
-
code: "en-PW",
|
1388
|
-
name: "English (Palau) (en-PW)"
|
1389
|
-
},
|
1390
|
-
{
|
1391
|
-
code: "en-PG",
|
1392
|
-
name: "English (Papua New Guinea) (en-PG)"
|
1393
|
-
},
|
1394
|
-
{
|
1395
|
-
code: "en-PH",
|
1396
|
-
name: "English (Philippines) (en-PH)"
|
1397
|
-
},
|
1398
|
-
{
|
1399
|
-
code: "en-PN",
|
1400
|
-
name: "English (Pitcairn Islands) (en-PN)"
|
1401
|
-
},
|
1402
|
-
{
|
1403
|
-
code: "en-PR",
|
1404
|
-
name: "English (Puerto Rico) (en-PR)"
|
1405
|
-
},
|
1406
|
-
{
|
1407
|
-
code: "en-RW",
|
1408
|
-
name: "English (Rwanda) (en-RW)"
|
1409
|
-
},
|
1410
|
-
{
|
1411
|
-
code: "en-WS",
|
1412
|
-
name: "English (Samoa) (en-WS)"
|
1413
|
-
},
|
1414
|
-
{
|
1415
|
-
code: "en-SA",
|
1416
|
-
name: "English (Saudi Arabia) (en-SA)"
|
1417
|
-
},
|
1418
|
-
{
|
1419
|
-
code: "en-SC",
|
1420
|
-
name: "English (Seychelles) (en-SC)"
|
1421
|
-
},
|
1422
|
-
{
|
1423
|
-
code: "en-SL",
|
1424
|
-
name: "English (Sierra Leone) (en-SL)"
|
1425
|
-
},
|
1426
|
-
{
|
1427
|
-
code: "en-SG",
|
1428
|
-
name: "English (Singapore) (en-SG)"
|
1429
|
-
},
|
1430
|
-
{
|
1431
|
-
code: "en-SX",
|
1432
|
-
name: "English (Sint Maarten) (en-SX)"
|
1433
|
-
},
|
1434
|
-
{
|
1435
|
-
code: "en-SI",
|
1436
|
-
name: "English (Slovenia) (en-SI)"
|
1437
|
-
},
|
1438
|
-
{
|
1439
|
-
code: "en-SB",
|
1440
|
-
name: "English (Solomon Islands) (en-SB)"
|
1441
|
-
},
|
1442
|
-
{
|
1443
|
-
code: "en-SS",
|
1444
|
-
name: "English (South Sudan) (en-SS)"
|
1445
|
-
},
|
1446
|
-
{
|
1447
|
-
code: "en-SH",
|
1448
|
-
name: "English (St Helena) (en-SH)"
|
1449
|
-
},
|
1450
|
-
{
|
1451
|
-
code: "en-KN",
|
1452
|
-
name: "English (St Kitts & Nevis) (en-KN)"
|
1453
|
-
},
|
1454
|
-
{
|
1455
|
-
code: "en-LC",
|
1456
|
-
name: "English (St Lucia) (en-LC)"
|
1457
|
-
},
|
1458
|
-
{
|
1459
|
-
code: "svc",
|
1460
|
-
name: "Vincentian Creole English"
|
1461
|
-
},
|
1462
|
-
{
|
1463
|
-
code: "vic",
|
1464
|
-
name: "Virgin Islands Creole English"
|
1465
|
-
},
|
1466
|
-
{
|
1467
|
-
code: "en-SD",
|
1468
|
-
name: "English (Sudan) (en-SD)"
|
1469
|
-
},
|
1470
|
-
{
|
1471
|
-
code: "en-SZ",
|
1472
|
-
name: "English (Swaziland) (en-SZ)"
|
1473
|
-
},
|
1474
|
-
{
|
1475
|
-
code: "en-SE",
|
1476
|
-
name: "English (Sweden) (en-SE)"
|
1477
|
-
},
|
1478
|
-
{
|
1479
|
-
code: "en-CH",
|
1480
|
-
name: "English (Switzerland) (en-CH)"
|
1481
|
-
},
|
1482
|
-
{
|
1483
|
-
code: "en-TZ",
|
1484
|
-
name: "English (Tanzania) (en-TZ)"
|
1485
|
-
},
|
1486
|
-
{
|
1487
|
-
code: "en-TK",
|
1488
|
-
name: "English (Tokelau) (en-TK)"
|
1489
|
-
},
|
1490
|
-
{
|
1491
|
-
code: "en-TO",
|
1492
|
-
name: "English (Tonga) (en-TO)"
|
1493
|
-
},
|
1494
|
-
{
|
1495
|
-
code: "en-TT",
|
1496
|
-
name: "English (Trinidad and Tobago) (en-TT)"
|
1497
|
-
},
|
1498
|
-
{
|
1499
|
-
code: "en-TV",
|
1500
|
-
name: "English (Tuvalu) (en-TV)"
|
1501
|
-
},
|
1502
|
-
{
|
1503
|
-
code: "en-ZA",
|
1504
|
-
name: "English (South Africa) (en-ZA)"
|
1505
|
-
},
|
1506
|
-
{
|
1507
|
-
code: "en-AE",
|
1508
|
-
name: "English (U.A.E.) (en-AE)"
|
1509
|
-
},
|
1510
|
-
{
|
1511
|
-
code: "en-UM",
|
1512
|
-
name: "English (U.S. Minor Outlying Islands) (en-UM)"
|
1513
|
-
},
|
1514
|
-
{
|
1515
|
-
code: "en-VI",
|
1516
|
-
name: "English (U.S. Virgin Islands) (en-VI)"
|
1517
|
-
},
|
1518
|
-
{
|
1519
|
-
code: "en-US-POSIX",
|
1520
|
-
name: "English (U.S., Computer) (en-US-POSIX)"
|
1521
|
-
},
|
1522
|
-
{
|
1523
|
-
code: "en-UG",
|
1524
|
-
name: "English (Uganda) (en-UG)"
|
1525
|
-
},
|
1526
|
-
{
|
1527
|
-
code: "en-GB",
|
1528
|
-
name: "English (United Kingdom) (en-GB)"
|
1529
|
-
},
|
1530
|
-
{
|
1531
|
-
code: "en-US",
|
1532
|
-
name: "English (United States) (en-US)"
|
1533
|
-
},
|
1534
|
-
{
|
1535
|
-
code: "en-VU",
|
1536
|
-
name: "English (Vanuatu) (en-VU)"
|
1537
|
-
},
|
1538
|
-
{
|
1539
|
-
code: "en-ZM",
|
1540
|
-
name: "English (Zambia) (en-ZM)"
|
1541
|
-
},
|
1542
|
-
{
|
1543
|
-
code: "en-ZW",
|
1544
|
-
name: "English (Zimbabwe) (en-ZW)"
|
1545
|
-
},
|
1546
|
-
{
|
1547
|
-
code: "eo",
|
1548
|
-
name: "Esperanto (eo)"
|
1549
|
-
},
|
1550
|
-
{
|
1551
|
-
code: "et",
|
1552
|
-
name: "Estonian (et)"
|
1553
|
-
},
|
1554
|
-
{
|
1555
|
-
code: "et-EE",
|
1556
|
-
name: "Estonian (Estonia) (et-EE)"
|
1557
|
-
},
|
1558
|
-
{
|
1559
|
-
code: "ee",
|
1560
|
-
name: "Ewe (ee)"
|
1561
|
-
},
|
1562
|
-
{
|
1563
|
-
code: "ee-GH",
|
1564
|
-
name: "Ewe (Ghana) (ee-GH)"
|
1565
|
-
},
|
1566
|
-
{
|
1567
|
-
code: "ee-TG",
|
1568
|
-
name: "Ewe (Togo) (ee-TG)"
|
1569
|
-
},
|
1570
|
-
{
|
1571
|
-
code: "ewo",
|
1572
|
-
name: "Ewondo (ewo)"
|
1573
|
-
},
|
1574
|
-
{
|
1575
|
-
code: "ewo-CM",
|
1576
|
-
name: "Ewondo (Cameroon) (ewo-CM)"
|
1577
|
-
},
|
1578
|
-
{
|
1579
|
-
code: "fo",
|
1580
|
-
name: "Faroese (fo)"
|
1581
|
-
},
|
1582
|
-
{
|
1583
|
-
code: "fo-FO",
|
1584
|
-
name: "Faroese (Faroe Islands) (fo-FO)"
|
1585
|
-
},
|
1586
|
-
{
|
1587
|
-
code: "fil",
|
1588
|
-
name: "Filipino (fil)"
|
1589
|
-
},
|
1590
|
-
{
|
1591
|
-
code: "fil-PH",
|
1592
|
-
name: "Filipino (Philippines) (fil-PH)"
|
1593
|
-
},
|
1594
|
-
{
|
1595
|
-
code: "fi",
|
1596
|
-
name: "Finnish (fi)"
|
1597
|
-
},
|
1598
|
-
{
|
1599
|
-
code: "fi-FI",
|
1600
|
-
name: "Finnish (Finland) (fi-FI)"
|
1601
|
-
},
|
1602
|
-
{
|
1603
|
-
code: "fr",
|
1604
|
-
name: "French (fr)"
|
1605
|
-
},
|
1606
|
-
{
|
1607
|
-
code: "fr-BE",
|
1608
|
-
name: "French (Belgium) (fr-BE)"
|
1609
|
-
},
|
1610
|
-
{
|
1611
|
-
code: "fr-BJ",
|
1612
|
-
name: "French (Benin) (fr-BJ)"
|
1613
|
-
},
|
1614
|
-
{
|
1615
|
-
code: "fr-BF",
|
1616
|
-
name: "French (Burkina Faso) (fr-BF)"
|
1617
|
-
},
|
1618
|
-
{
|
1619
|
-
code: "fr-BI",
|
1620
|
-
name: "French (Burundi) (fr-BI)"
|
1621
|
-
},
|
1622
|
-
{
|
1623
|
-
code: "fr-CM",
|
1624
|
-
name: "French (Cameroon) (fr-CM)"
|
1625
|
-
},
|
1626
|
-
{
|
1627
|
-
code: "fr-CA",
|
1628
|
-
name: "French (Canada) (fr-CA)"
|
1629
|
-
},
|
1630
|
-
{
|
1631
|
-
code: "fr-CF",
|
1632
|
-
name: "French (Central African Republic) (fr-CF)"
|
1633
|
-
},
|
1634
|
-
{
|
1635
|
-
code: "fr-TD",
|
1636
|
-
name: "French (Chad) (fr-TD)"
|
1637
|
-
},
|
1638
|
-
{
|
1639
|
-
code: "fr-KM",
|
1640
|
-
name: "French (Comoros) (fr-KM)"
|
1641
|
-
},
|
1642
|
-
{
|
1643
|
-
code: "fr-CG",
|
1644
|
-
name: "French (Congo - Brazzaville) (fr-CG)"
|
1645
|
-
},
|
1646
|
-
{
|
1647
|
-
code: "fr-CD",
|
1648
|
-
name: "French (Congo - Kinshasa) (fr-CD)"
|
1649
|
-
},
|
1650
|
-
{
|
1651
|
-
code: "fr-CI",
|
1652
|
-
name: "French (Côte d’Ivoire) (fr-CI)"
|
1653
|
-
},
|
1654
|
-
{
|
1655
|
-
code: "fr-DJ",
|
1656
|
-
name: "French (Djibouti) (fr-DJ)"
|
1657
|
-
},
|
1658
|
-
{
|
1659
|
-
code: "fr-GQ",
|
1660
|
-
name: "French (Equatorial Guinea) (fr-GQ)"
|
1661
|
-
},
|
1662
|
-
{
|
1663
|
-
code: "fr-FR",
|
1664
|
-
name: "French (France) (fr-FR)"
|
1665
|
-
},
|
1666
|
-
{
|
1667
|
-
code: "fr-GF",
|
1668
|
-
name: "French (French Guiana) (fr-GF)"
|
1669
|
-
},
|
1670
|
-
{
|
1671
|
-
code: "fr-GA",
|
1672
|
-
name: "French (Gabon) (fr-GA)"
|
1673
|
-
},
|
1674
|
-
{
|
1675
|
-
code: "fr-GP",
|
1676
|
-
name: "French (Guadeloupe) (fr-GP)"
|
1677
|
-
},
|
1678
|
-
{
|
1679
|
-
code: "fr-GN",
|
1680
|
-
name: "French (Guinea) (fr-GN)"
|
1681
|
-
},
|
1682
|
-
{
|
1683
|
-
code: "fr-LU",
|
1684
|
-
name: "French (Luxembourg) (fr-LU)"
|
1685
|
-
},
|
1686
|
-
{
|
1687
|
-
code: "fr-MG",
|
1688
|
-
name: "French (Madagascar) (fr-MG)"
|
1689
|
-
},
|
1690
|
-
{
|
1691
|
-
code: "fr-ML",
|
1692
|
-
name: "French (Mali) (fr-ML)"
|
1693
|
-
},
|
1694
|
-
{
|
1695
|
-
code: "fr-MQ",
|
1696
|
-
name: "French (Martinique) (fr-MQ)"
|
1697
|
-
},
|
1698
|
-
{
|
1699
|
-
code: "fr-YT",
|
1700
|
-
name: "French (Mayotte) (fr-YT)"
|
1701
|
-
},
|
1702
|
-
{
|
1703
|
-
code: "fr-MC",
|
1704
|
-
name: "French (Monaco) (fr-MC)"
|
1705
|
-
},
|
1706
|
-
{
|
1707
|
-
code: "fr-NE",
|
1708
|
-
name: "French (Niger) (fr-NE)"
|
1709
|
-
},
|
1710
|
-
{
|
1711
|
-
code: "fr-RW",
|
1712
|
-
name: "French (Rwanda) (fr-RW)"
|
1713
|
-
},
|
1714
|
-
{
|
1715
|
-
code: "fr-RE",
|
1716
|
-
name: "French (Réunion) (fr-RE)"
|
1717
|
-
},
|
1718
|
-
{
|
1719
|
-
code: "fr-BL",
|
1720
|
-
name: "French (Saint Barthélemy) (fr-BL)"
|
1721
|
-
},
|
1722
|
-
{
|
1723
|
-
code: "fr-MF",
|
1724
|
-
name: "French (Saint Martin) (fr-MF)"
|
1725
|
-
},
|
1726
|
-
{
|
1727
|
-
code: "fr-MU",
|
1728
|
-
name: "French (Mauritius) (fr-MU)"
|
1729
|
-
},
|
1730
|
-
{
|
1731
|
-
code: "fr-SN",
|
1732
|
-
name: "French (Senegal) (fr-SN)"
|
1733
|
-
},
|
1734
|
-
{
|
1735
|
-
code: "fr-CH",
|
1736
|
-
name: "French (Switzerland) (fr-CH)"
|
1737
|
-
},
|
1738
|
-
{
|
1739
|
-
code: "fr-TG",
|
1740
|
-
name: "French (Togo) (fr-TG)"
|
1741
|
-
},
|
1742
|
-
{
|
1743
|
-
code: "ff",
|
1744
|
-
name: "Fulah (ff)"
|
1745
|
-
},
|
1746
|
-
{
|
1747
|
-
code: "ff-SN",
|
1748
|
-
name: "Fulah (Senegal) (ff-SN)"
|
1749
|
-
},
|
1750
|
-
{
|
1751
|
-
code: "gl",
|
1752
|
-
name: "Galician (gl)"
|
1753
|
-
},
|
1754
|
-
{
|
1755
|
-
code: "gl-ES",
|
1756
|
-
name: "Galician (Spain) (gl-ES)"
|
1757
|
-
},
|
1758
|
-
{
|
1759
|
-
code: "lao",
|
1760
|
-
name: "Laotian (Laos) (lao)"
|
1761
|
-
},
|
1762
|
-
{
|
1763
|
-
code: "lg",
|
1764
|
-
name: "Ganda (lg)"
|
1765
|
-
},
|
1766
|
-
{
|
1767
|
-
code: "lg-UG",
|
1768
|
-
name: "Ganda (Uganda) (lg-UG)"
|
1769
|
-
},
|
1770
|
-
{
|
1771
|
-
code: "ka",
|
1772
|
-
name: "Georgian (ka)"
|
1773
|
-
},
|
1774
|
-
{
|
1775
|
-
code: "ka-GE",
|
1776
|
-
name: "Georgian (Georgia) (ka-GE)"
|
1777
|
-
},
|
1778
|
-
{
|
1779
|
-
code: "de",
|
1780
|
-
name: "German (de)"
|
1781
|
-
},
|
1782
|
-
{
|
1783
|
-
code: "de-AT",
|
1784
|
-
name: "German (Austria) (de-AT)"
|
1785
|
-
},
|
1786
|
-
{
|
1787
|
-
code: "de-BE",
|
1788
|
-
name: "German (Belgium) (de-BE)"
|
1789
|
-
},
|
1790
|
-
{
|
1791
|
-
code: "de-DE",
|
1792
|
-
name: "German (Germany) (de-DE)"
|
1793
|
-
},
|
1794
|
-
{
|
1795
|
-
code: "de-LI",
|
1796
|
-
name: "German (Liechtenstein) (de-LI)"
|
1797
|
-
},
|
1798
|
-
{
|
1799
|
-
code: "de-LU",
|
1800
|
-
name: "German (Luxembourg) (de-LU)"
|
1801
|
-
},
|
1802
|
-
{
|
1803
|
-
code: "de-CH",
|
1804
|
-
name: "German (Switzerland) (de-CH)"
|
1805
|
-
},
|
1806
|
-
{
|
1807
|
-
code: "el",
|
1808
|
-
name: "Greek (el)"
|
1809
|
-
},
|
1810
|
-
{
|
1811
|
-
code: "el-CY",
|
1812
|
-
name: "Greek (Cyprus) (el-CY)"
|
1813
|
-
},
|
1814
|
-
{
|
1815
|
-
code: "el-GR",
|
1816
|
-
name: "Greek (Greece) (el-GR)"
|
1817
|
-
},
|
1818
|
-
{
|
1819
|
-
code: "gu",
|
1820
|
-
name: "Gujarati (gu)"
|
1821
|
-
},
|
1822
|
-
{
|
1823
|
-
code: "gu-IN",
|
1824
|
-
name: "Gujarati (India) (gu-IN)"
|
1825
|
-
},
|
1826
|
-
{
|
1827
|
-
code: "guz",
|
1828
|
-
name: "Gusii (guz)"
|
1829
|
-
},
|
1830
|
-
{
|
1831
|
-
code: "guz-KE",
|
1832
|
-
name: "Gusii (Kenya) (guz-KE)"
|
1833
|
-
},
|
1834
|
-
{
|
1835
|
-
code: "ha",
|
1836
|
-
name: "Hausa (ha)"
|
1837
|
-
},
|
1838
|
-
{
|
1839
|
-
code: "ha-Latn",
|
1840
|
-
name: "Hausa (Latin) (ha-Latn)"
|
1841
|
-
},
|
1842
|
-
{
|
1843
|
-
code: "ha-Latn-GH",
|
1844
|
-
name: "Hausa (Latin, Ghana) (ha-Latn-GH)"
|
1845
|
-
},
|
1846
|
-
{
|
1847
|
-
code: "ha-Latn-NE",
|
1848
|
-
name: "Hausa (Latin, Niger) (ha-Latn-NE)"
|
1849
|
-
},
|
1850
|
-
{
|
1851
|
-
code: "ha-Latn-NG",
|
1852
|
-
name: "Hausa (Latin, Nigeria) (ha-Latn-NG)"
|
1853
|
-
},
|
1854
|
-
{
|
1855
|
-
code: "haw",
|
1856
|
-
name: "Hawaiian (haw)"
|
1857
|
-
},
|
1858
|
-
{
|
1859
|
-
code: "haw-US",
|
1860
|
-
name: "Hawaiian (United States) (haw-US)"
|
1861
|
-
},
|
1862
|
-
{
|
1863
|
-
code: "he",
|
1864
|
-
name: "Hebrew (he)"
|
1865
|
-
},
|
1866
|
-
{
|
1867
|
-
code: "he-IL",
|
1868
|
-
name: "Hebrew (Israel) (he-IL)"
|
1869
|
-
},
|
1870
|
-
{
|
1871
|
-
code: "hi",
|
1872
|
-
name: "Hindi (hi)"
|
1873
|
-
},
|
1874
|
-
{
|
1875
|
-
code: "hi-IN",
|
1876
|
-
name: "Hindi (India) (hi-IN)"
|
1877
|
-
},
|
1878
|
-
{
|
1879
|
-
code: "hu",
|
1880
|
-
name: "Hungarian (hu)"
|
1881
|
-
},
|
1882
|
-
{
|
1883
|
-
code: "hu-HU",
|
1884
|
-
name: "Hungarian (Hungary) (hu-HU)"
|
1885
|
-
},
|
1886
|
-
{
|
1887
|
-
code: "is",
|
1888
|
-
name: "Icelandic (is)"
|
1889
|
-
},
|
1890
|
-
{
|
1891
|
-
code: "is-IS",
|
1892
|
-
name: "Icelandic (Iceland) (is-IS)"
|
1893
|
-
},
|
1894
|
-
{
|
1895
|
-
code: "ig",
|
1896
|
-
name: "Igbo (ig)"
|
1897
|
-
},
|
1898
|
-
{
|
1899
|
-
code: "ig-NG",
|
1900
|
-
name: "Igbo (Nigeria) (ig-NG)"
|
1901
|
-
},
|
1902
|
-
{
|
1903
|
-
code: "smn",
|
1904
|
-
name: "Inari Sami"
|
1905
|
-
},
|
1906
|
-
{
|
1907
|
-
code: "smn-FI",
|
1908
|
-
name: "Inari Sami (Finland)"
|
1909
|
-
},
|
1910
|
-
{
|
1911
|
-
code: "id",
|
1912
|
-
name: "Indonesian (id)"
|
1913
|
-
},
|
1914
|
-
{
|
1915
|
-
code: "id-ID",
|
1916
|
-
name: "Indonesian (Indonesia) (id-ID)"
|
1917
|
-
},
|
1918
|
-
{
|
1919
|
-
code: "ga",
|
1920
|
-
name: "Irish (ga)"
|
1921
|
-
},
|
1922
|
-
{
|
1923
|
-
code: "ga-IE",
|
1924
|
-
name: "Irish (Ireland) (ga-IE)"
|
1925
|
-
},
|
1926
|
-
{
|
1927
|
-
code: "it",
|
1928
|
-
name: "Italian (it)"
|
1929
|
-
},
|
1930
|
-
{
|
1931
|
-
code: "it-IT",
|
1932
|
-
name: "Italian (Italy) (it-IT)"
|
1933
|
-
},
|
1934
|
-
{
|
1935
|
-
code: "it-CH",
|
1936
|
-
name: "Italian (Switzerland) (it-CH)"
|
1937
|
-
},
|
1938
|
-
{
|
1939
|
-
code: "ja",
|
1940
|
-
name: "Japanese (ja)"
|
1941
|
-
},
|
1942
|
-
{
|
1943
|
-
code: "ja-JP",
|
1944
|
-
name: "Japanese (Japan) (ja-JP)"
|
1945
|
-
},
|
1946
|
-
{
|
1947
|
-
code: "dyo",
|
1948
|
-
name: "Jola-Fonyi (dyo)"
|
1949
|
-
},
|
1950
|
-
{
|
1951
|
-
code: "dyo-SN",
|
1952
|
-
name: "Jola-Fonyi (Senegal) (dyo-SN)"
|
1953
|
-
},
|
1954
|
-
{
|
1955
|
-
code: "kea",
|
1956
|
-
name: "Kabuverdianu (kea)"
|
1957
|
-
},
|
1958
|
-
{
|
1959
|
-
code: "kea-CV",
|
1960
|
-
name: "Kabuverdianu (Cape Verde) (kea-CV)"
|
1961
|
-
},
|
1962
|
-
{
|
1963
|
-
code: "kab",
|
1964
|
-
name: "Kabyle (kab)"
|
1965
|
-
},
|
1966
|
-
{
|
1967
|
-
code: "kab-DZ",
|
1968
|
-
name: "Kabyle (Algeria) (kab-DZ)"
|
1969
|
-
},
|
1970
|
-
{
|
1971
|
-
code: "kl",
|
1972
|
-
name: "Kalaallisut (kl)"
|
1973
|
-
},
|
1974
|
-
{
|
1975
|
-
code: "kl-GL",
|
1976
|
-
name: "Kalaallisut (Greenland) (kl-GL)"
|
1977
|
-
},
|
1978
|
-
{
|
1979
|
-
code: "kln",
|
1980
|
-
name: "Kalenjin (kln)"
|
1981
|
-
},
|
1982
|
-
{
|
1983
|
-
code: "kln-KE",
|
1984
|
-
name: "Kalenjin (Kenya) (kln-KE)"
|
1985
|
-
},
|
1986
|
-
{
|
1987
|
-
code: "kam",
|
1988
|
-
name: "Kamba (kam)"
|
1989
|
-
},
|
1990
|
-
{
|
1991
|
-
code: "kam-KE",
|
1992
|
-
name: "Kamba (Kenya) (kam-KE)"
|
1993
|
-
},
|
1994
|
-
{
|
1995
|
-
code: "kn",
|
1996
|
-
name: "Kannada (kn)"
|
1997
|
-
},
|
1998
|
-
{
|
1999
|
-
code: "kn-IN",
|
2000
|
-
name: "Kannada (India) (kn-IN)"
|
2001
|
-
},
|
2002
|
-
{
|
2003
|
-
code: "kaa",
|
2004
|
-
name: "Kara-Kalpak (kaa)"
|
2005
|
-
},
|
2006
|
-
{
|
2007
|
-
code: "kk",
|
2008
|
-
name: "Kazakh (kk)"
|
2009
|
-
},
|
2010
|
-
{
|
2011
|
-
code: "kk-Cyrl",
|
2012
|
-
name: "Kazakh (Cyrillic) (kk-Cyrl)"
|
2013
|
-
},
|
2014
|
-
{
|
2015
|
-
code: "kk-Cyrl-KZ",
|
2016
|
-
name: "Kazakh (Cyrillic, Kazakhstan) (kk-Cyrl-KZ)"
|
2017
|
-
},
|
2018
|
-
{
|
2019
|
-
code: "km",
|
2020
|
-
name: "Khmer (km)"
|
2021
|
-
},
|
2022
|
-
{
|
2023
|
-
code: "km-KH",
|
2024
|
-
name: "Khmer (Cambodia) (km-KH)"
|
2025
|
-
},
|
2026
|
-
{
|
2027
|
-
code: "ki",
|
2028
|
-
name: "Kikuyu (ki)"
|
2029
|
-
},
|
2030
|
-
{
|
2031
|
-
code: "ki-KE",
|
2032
|
-
name: "Kikuyu (Kenya) (ki-KE)"
|
2033
|
-
},
|
2034
|
-
{
|
2035
|
-
code: "rw",
|
2036
|
-
name: "Kinyarwanda (rw)"
|
2037
|
-
},
|
2038
|
-
{
|
2039
|
-
code: "rw-RW",
|
2040
|
-
name: "Kinyarwanda (Rwanda) (rw-RW)"
|
2041
|
-
},
|
2042
|
-
{
|
2043
|
-
code: "kok",
|
2044
|
-
name: "Konkani (kok)"
|
2045
|
-
},
|
2046
|
-
{
|
2047
|
-
code: "kok-IN",
|
2048
|
-
name: "Konkani (India) (kok-IN)"
|
2049
|
-
},
|
2050
|
-
{
|
2051
|
-
code: "ko",
|
2052
|
-
name: "Korean (ko)"
|
2053
|
-
},
|
2054
|
-
{
|
2055
|
-
code: "ko-KR",
|
2056
|
-
name: "Korean (South Korea) (ko-KR)"
|
2057
|
-
},
|
2058
|
-
{
|
2059
|
-
code: "khq",
|
2060
|
-
name: "Koyra Chiini (khq)"
|
2061
|
-
},
|
2062
|
-
{
|
2063
|
-
code: "khq-ML",
|
2064
|
-
name: "Koyra Chiini (Mali) (khq-ML)"
|
2065
|
-
},
|
2066
|
-
{
|
2067
|
-
code: "ses",
|
2068
|
-
name: "Koyraboro Senni (ses)"
|
2069
|
-
},
|
2070
|
-
{
|
2071
|
-
code: "ses-ML",
|
2072
|
-
name: "Koyraboro Senni (Mali) (ses-ML)"
|
2073
|
-
},
|
2074
|
-
{
|
2075
|
-
code: "nmg",
|
2076
|
-
name: "Kwasio (nmg)"
|
2077
|
-
},
|
2078
|
-
{
|
2079
|
-
code: "nmg-CM",
|
2080
|
-
name: "Kwasio (Cameroon) (nmg-CM)"
|
2081
|
-
},
|
2082
|
-
{
|
2083
|
-
code: "ky",
|
2084
|
-
name: "Kyrgyz (ky)"
|
2085
|
-
},
|
2086
|
-
{
|
2087
|
-
code: "lag",
|
2088
|
-
name: "Langi (lag)"
|
2089
|
-
},
|
2090
|
-
{
|
2091
|
-
code: "lag-TZ",
|
2092
|
-
name: "Langi (Tanzania) (lag-TZ)"
|
2093
|
-
},
|
2094
|
-
{
|
2095
|
-
code: "lv",
|
2096
|
-
name: "Latvian (lv)"
|
2097
|
-
},
|
2098
|
-
{
|
2099
|
-
code: "lv-LV",
|
2100
|
-
name: "Latvian (Latvia) (lv-LV)"
|
2101
|
-
},
|
2102
|
-
{
|
2103
|
-
code: "lir",
|
2104
|
-
name: "Liberian English"
|
2105
|
-
},
|
2106
|
-
{
|
2107
|
-
code: "ln",
|
2108
|
-
name: "Lingala (ln)"
|
2109
|
-
},
|
2110
|
-
{
|
2111
|
-
code: "ln-CG",
|
2112
|
-
name: "Lingala (Congo - Brazzaville) (ln-CG)"
|
2113
|
-
},
|
2114
|
-
{
|
2115
|
-
code: "ln-CD",
|
2116
|
-
name: "Lingala (Congo - Kinshasa) (ln-CD)"
|
2117
|
-
},
|
2118
|
-
{
|
2119
|
-
code: "lt",
|
2120
|
-
name: "Lithuanian (lt)"
|
2121
|
-
},
|
2122
|
-
{
|
2123
|
-
code: "lt-LT",
|
2124
|
-
name: "Lithuanian (Lithuania) (lt-LT)"
|
2125
|
-
},
|
2126
|
-
{
|
2127
|
-
code: "lu",
|
2128
|
-
name: "Luba-Katanga (lu)"
|
2129
|
-
},
|
2130
|
-
{
|
2131
|
-
code: "lu-CD",
|
2132
|
-
name: "Luba-Katanga (Congo - Kinshasa) (lu-CD)"
|
2133
|
-
},
|
2134
|
-
{
|
2135
|
-
code: "luo",
|
2136
|
-
name: "Luo (luo)"
|
2137
|
-
},
|
2138
|
-
{
|
2139
|
-
code: "luo-KE",
|
2140
|
-
name: "Luo (Kenya) (luo-KE)"
|
2141
|
-
},
|
2142
|
-
{
|
2143
|
-
code: "luy",
|
2144
|
-
name: "Luyia (luy)"
|
2145
|
-
},
|
2146
|
-
{
|
2147
|
-
code: "luy-KE",
|
2148
|
-
name: "Luyia (Kenya) (luy-KE)"
|
2149
|
-
},
|
2150
|
-
{
|
2151
|
-
code: "mk",
|
2152
|
-
name: "Macedonian (mk)"
|
2153
|
-
},
|
2154
|
-
{
|
2155
|
-
code: "mk-MK",
|
2156
|
-
name: "Macedonian (Macedonia) (mk-MK)"
|
2157
|
-
},
|
2158
|
-
{
|
2159
|
-
code: "jmc",
|
2160
|
-
name: "Machame (jmc)"
|
2161
|
-
},
|
2162
|
-
{
|
2163
|
-
code: "jmc-TZ",
|
2164
|
-
name: "Machame (Tanzania) (jmc-TZ)"
|
2165
|
-
},
|
2166
|
-
{
|
2167
|
-
code: "mgh",
|
2168
|
-
name: "Makhuwa-Meetto (mgh)"
|
2169
|
-
},
|
2170
|
-
{
|
2171
|
-
code: "mgh-MZ",
|
2172
|
-
name: "Makhuwa-Meetto (Mozambique) (mgh-MZ)"
|
2173
|
-
},
|
2174
|
-
{
|
2175
|
-
code: "kde",
|
2176
|
-
name: "Makonde (kde)"
|
2177
|
-
},
|
2178
|
-
{
|
2179
|
-
code: "kde-TZ",
|
2180
|
-
name: "Makonde (Tanzania) (kde-TZ)"
|
2181
|
-
},
|
2182
|
-
{
|
2183
|
-
code: "mg",
|
2184
|
-
name: "Malagasy (mg)"
|
2185
|
-
},
|
2186
|
-
{
|
2187
|
-
code: "mg-MG",
|
2188
|
-
name: "Malagasy (Madagascar) (mg-MG)"
|
2189
|
-
},
|
2190
|
-
{
|
2191
|
-
code: "ms",
|
2192
|
-
name: "Malay (ms)"
|
2193
|
-
},
|
2194
|
-
{
|
2195
|
-
code: "ms-BN",
|
2196
|
-
name: "Malay (Brunei) (ms-BN)"
|
2197
|
-
},
|
2198
|
-
{
|
2199
|
-
code: "ms-MY",
|
2200
|
-
name: "Malay (Malaysia) (ms-MY)"
|
2201
|
-
},
|
2202
|
-
{
|
2203
|
-
code: "ml",
|
2204
|
-
name: "Malayalam (ml)"
|
2205
|
-
},
|
2206
|
-
{
|
2207
|
-
code: "ml-IN",
|
2208
|
-
name: "Malayalam (India) (ml-IN)"
|
2209
|
-
},
|
2210
|
-
{
|
2211
|
-
code: "mt",
|
2212
|
-
name: "Maltese (mt)"
|
2213
|
-
},
|
2214
|
-
{
|
2215
|
-
code: "mt-MT",
|
2216
|
-
name: "Maltese (Malta) (mt-MT)"
|
2217
|
-
},
|
2218
|
-
{
|
2219
|
-
code: "gv",
|
2220
|
-
name: "Manx (gv)"
|
2221
|
-
},
|
2222
|
-
{
|
2223
|
-
code: "gv-GB",
|
2224
|
-
name: "Manx (United Kingdom) (gv-GB)"
|
2225
|
-
},
|
2226
|
-
{
|
2227
|
-
code: "mr",
|
2228
|
-
name: "Marathi (mr)"
|
2229
|
-
},
|
2230
|
-
{
|
2231
|
-
code: "mr-IN",
|
2232
|
-
name: "Marathi (India) (mr-IN)"
|
2233
|
-
},
|
2234
|
-
{
|
2235
|
-
code: "mas",
|
2236
|
-
name: "Masai (mas)"
|
2237
|
-
},
|
2238
|
-
{
|
2239
|
-
code: "mas-KE",
|
2240
|
-
name: "Masai (Kenya) (mas-KE)"
|
2241
|
-
},
|
2242
|
-
{
|
2243
|
-
code: "mas-TZ",
|
2244
|
-
name: "Masai (Tanzania) (mas-TZ)"
|
2245
|
-
},
|
2246
|
-
{
|
2247
|
-
code: "mer",
|
2248
|
-
name: "Meru (mer)"
|
2249
|
-
},
|
2250
|
-
{
|
2251
|
-
code: "mer-KE",
|
2252
|
-
name: "Meru (Kenya) (mer-KE)"
|
2253
|
-
},
|
2254
|
-
{
|
2255
|
-
code: "mn",
|
2256
|
-
name: "Mongolian (mn)"
|
2257
|
-
},
|
2258
|
-
{
|
2259
|
-
code: "mfe",
|
2260
|
-
name: "Morisyen (mfe)"
|
2261
|
-
},
|
2262
|
-
{
|
2263
|
-
code: "mfe-MU",
|
2264
|
-
name: "Morisyen (Mauritius) (mfe-MU)"
|
2265
|
-
},
|
2266
|
-
{
|
2267
|
-
code: "mua",
|
2268
|
-
name: "Mundang (mua)"
|
2269
|
-
},
|
2270
|
-
{
|
2271
|
-
code: "mua-CM",
|
2272
|
-
name: "Mundang (Cameroon) (mua-CM)"
|
2273
|
-
},
|
2274
|
-
{
|
2275
|
-
code: "naq",
|
2276
|
-
name: "Nama (naq)"
|
2277
|
-
},
|
2278
|
-
{
|
2279
|
-
code: "naq-NA",
|
2280
|
-
name: "Nama (Namibia) (naq-NA)"
|
2281
|
-
},
|
2282
|
-
{
|
2283
|
-
code: "ne",
|
2284
|
-
name: "Nepali (ne)"
|
2285
|
-
},
|
2286
|
-
{
|
2287
|
-
code: "ne-IN",
|
2288
|
-
name: "Nepali (India) (ne-IN)"
|
2289
|
-
},
|
2290
|
-
{
|
2291
|
-
code: "ne-NP",
|
2292
|
-
name: "Nepali (Nepal) (ne-NP)"
|
2293
|
-
},
|
2294
|
-
{
|
2295
|
-
code: "se",
|
2296
|
-
name: "Northern Sami"
|
2297
|
-
},
|
2298
|
-
{
|
2299
|
-
code: "se-FI",
|
2300
|
-
name: "Northern Sami (Finland)"
|
2301
|
-
},
|
2302
|
-
{
|
2303
|
-
code: "se-NO",
|
2304
|
-
name: "Northern Sami (Norway)"
|
2305
|
-
},
|
2306
|
-
{
|
2307
|
-
code: "se-SE",
|
2308
|
-
name: "Northern Sami (Sweden)"
|
2309
|
-
},
|
2310
|
-
{
|
2311
|
-
code: "nd",
|
2312
|
-
name: "North Ndebele (nd)"
|
2313
|
-
},
|
2314
|
-
{
|
2315
|
-
code: "nd-ZW",
|
2316
|
-
name: "North Ndebele (Zimbabwe) (nd-ZW)"
|
2317
|
-
},
|
2318
|
-
{
|
2319
|
-
code: "nb",
|
2320
|
-
name: "Norwegian Bokmål (nb)"
|
2321
|
-
},
|
2322
|
-
{
|
2323
|
-
code: "nb-NO",
|
2324
|
-
name: "Norwegian Bokmål (Norway) (nb-NO)"
|
2325
|
-
},
|
2326
|
-
{
|
2327
|
-
code: "nn",
|
2328
|
-
name: "Norwegian Nynorsk (nn)"
|
2329
|
-
},
|
2330
|
-
{
|
2331
|
-
code: "nn-NO",
|
2332
|
-
name: "Norwegian Nynorsk (Norway) (nn-NO)"
|
2333
|
-
},
|
2334
|
-
{
|
2335
|
-
code: "nus",
|
2336
|
-
name: "Nuer (nus)"
|
2337
|
-
},
|
2338
|
-
{
|
2339
|
-
code: "nus-SD",
|
2340
|
-
name: "Nuer (Sudan) (nus-SD)"
|
2341
|
-
},
|
2342
|
-
{
|
2343
|
-
code: "nyn",
|
2344
|
-
name: "Nyankole (nyn)"
|
2345
|
-
},
|
2346
|
-
{
|
2347
|
-
code: "nyn-UG",
|
2348
|
-
name: "Nyankole (Uganda) (nyn-UG)"
|
2349
|
-
},
|
2350
|
-
{
|
2351
|
-
code: "or",
|
2352
|
-
name: "Oriya (or)"
|
2353
|
-
},
|
2354
|
-
{
|
2355
|
-
code: "or-IN",
|
2356
|
-
name: "Oriya (India) (or-IN)"
|
2357
|
-
},
|
2358
|
-
{
|
2359
|
-
code: "om",
|
2360
|
-
name: "Oromo (om)"
|
2361
|
-
},
|
2362
|
-
{
|
2363
|
-
code: "om-ET",
|
2364
|
-
name: "Oromo (Ethiopia) (om-ET)"
|
2365
|
-
},
|
2366
|
-
{
|
2367
|
-
code: "om-KE",
|
2368
|
-
name: "Oromo (Kenya) (om-KE)"
|
2369
|
-
},
|
2370
|
-
{
|
2371
|
-
code: "ps",
|
2372
|
-
name: "Pashto (ps)"
|
2373
|
-
},
|
2374
|
-
{
|
2375
|
-
code: "ps-AF",
|
2376
|
-
name: "Pashto (Afghanistan) (ps-AF)"
|
2377
|
-
},
|
2378
|
-
{
|
2379
|
-
code: "fa",
|
2380
|
-
name: "Persian (fa)"
|
2381
|
-
},
|
2382
|
-
{
|
2383
|
-
code: "fa-AF",
|
2384
|
-
name: "Persian (Afghanistan) (fa-AF)"
|
2385
|
-
},
|
2386
|
-
{
|
2387
|
-
code: "fa-IR",
|
2388
|
-
name: "Persian (Iran) (fa-IR)"
|
2389
|
-
},
|
2390
|
-
{
|
2391
|
-
code: "pl",
|
2392
|
-
name: "Polish (pl)"
|
2393
|
-
},
|
2394
|
-
{
|
2395
|
-
code: "pl-PL",
|
2396
|
-
name: "Polish (Poland) (pl-PL)"
|
2397
|
-
},
|
2398
|
-
{
|
2399
|
-
code: "pt",
|
2400
|
-
name: "Portuguese (pt)"
|
2401
|
-
},
|
2402
|
-
{
|
2403
|
-
code: "pt-AO",
|
2404
|
-
name: "Portuguese (Angola) (pt-AO)"
|
2405
|
-
},
|
2406
|
-
{
|
2407
|
-
code: "pt-BR",
|
2408
|
-
name: "Portuguese (Brazil) (pt-BR)"
|
2409
|
-
},
|
2410
|
-
{
|
2411
|
-
code: "pt-GW",
|
2412
|
-
name: "Portuguese (Guinea-Bissau) (pt-GW)"
|
2413
|
-
},
|
2414
|
-
{
|
2415
|
-
code: "pt-MZ",
|
2416
|
-
name: "Portuguese (Mozambique) (pt-MZ)"
|
2417
|
-
},
|
2418
|
-
{
|
2419
|
-
code: "pt-PT",
|
2420
|
-
name: "Portuguese (Portugal) (pt-PT)"
|
2421
|
-
},
|
2422
|
-
{
|
2423
|
-
code: "pt-ST",
|
2424
|
-
name: "Portuguese (São Tomé and Príncipe) (pt-ST)"
|
2425
|
-
},
|
2426
|
-
{
|
2427
|
-
code: "pa",
|
2428
|
-
name: "Punjabi (pa)"
|
2429
|
-
},
|
2430
|
-
{
|
2431
|
-
code: "pa-Arab",
|
2432
|
-
name: "Punjabi (Arabic) (pa-Arab)"
|
2433
|
-
},
|
2434
|
-
{
|
2435
|
-
code: "pa-Arab-PK",
|
2436
|
-
name: "Punjabi (Arabic, Pakistan) (pa-Arab-PK)"
|
2437
|
-
},
|
2438
|
-
{
|
2439
|
-
code: "pa-Guru",
|
2440
|
-
name: "Punjabi (Gurmukhi) (pa-Guru)"
|
2441
|
-
},
|
2442
|
-
{
|
2443
|
-
code: "pa-Guru-IN",
|
2444
|
-
name: "Punjabi (Gurmukhi, India) (pa-Guru-IN)"
|
2445
|
-
},
|
2446
|
-
{
|
2447
|
-
code: "ro",
|
2448
|
-
name: "Romanian (ro)"
|
2449
|
-
},
|
2450
|
-
{
|
2451
|
-
code: "ro-MD",
|
2452
|
-
name: "Romanian (Moldova) (ro-MD)"
|
2453
|
-
},
|
2454
|
-
{
|
2455
|
-
code: "ro-RO",
|
2456
|
-
name: "Romanian (Romania) (ro-RO)"
|
2457
|
-
},
|
2458
|
-
{
|
2459
|
-
code: "rm",
|
2460
|
-
name: "Romansh (rm)"
|
2461
|
-
},
|
2462
|
-
{
|
2463
|
-
code: "rm-CH",
|
2464
|
-
name: "Romansh (Switzerland) (rm-CH)"
|
2465
|
-
},
|
2466
|
-
{
|
2467
|
-
code: "rof",
|
2468
|
-
name: "Rombo (rof)"
|
2469
|
-
},
|
2470
|
-
{
|
2471
|
-
code: "rof-TZ",
|
2472
|
-
name: "Rombo (Tanzania) (rof-TZ)"
|
2473
|
-
},
|
2474
|
-
{
|
2475
|
-
code: "rn",
|
2476
|
-
name: "Rundi (rn)"
|
2477
|
-
},
|
2478
|
-
{
|
2479
|
-
code: "rn-BI",
|
2480
|
-
name: "Rundi (Burundi) (rn-BI)"
|
2481
|
-
},
|
2482
|
-
{
|
2483
|
-
code: "ru",
|
2484
|
-
name: "Russian (ru)"
|
2485
|
-
},
|
2486
|
-
{
|
2487
|
-
code: "ru-MD",
|
2488
|
-
name: "Russian (Moldova) (ru-MD)"
|
2489
|
-
},
|
2490
|
-
{
|
2491
|
-
code: "ru-RU",
|
2492
|
-
name: "Russian (Russia) (ru-RU)"
|
2493
|
-
},
|
2494
|
-
{
|
2495
|
-
code: "ru-UA",
|
2496
|
-
name: "Russian (Ukraine) (ru-UA)"
|
2497
|
-
},
|
2498
|
-
{
|
2499
|
-
code: "rwk",
|
2500
|
-
name: "Rwa (rwk)"
|
2501
|
-
},
|
2502
|
-
{
|
2503
|
-
code: "rwk-TZ",
|
2504
|
-
name: "Rwa (Tanzania) (rwk-TZ)"
|
2505
|
-
},
|
2506
|
-
{
|
2507
|
-
code: "saq",
|
2508
|
-
name: "Samburu (saq)"
|
2509
|
-
},
|
2510
|
-
{
|
2511
|
-
code: "saq-KE",
|
2512
|
-
name: "Samburu (Kenya) (saq-KE)"
|
2513
|
-
},
|
2514
|
-
{
|
2515
|
-
code: "sg",
|
2516
|
-
name: "Sango (sg)"
|
2517
|
-
},
|
2518
|
-
{
|
2519
|
-
code: "sg-CF",
|
2520
|
-
name: "Sango (Central African Republic) (sg-CF)"
|
2521
|
-
},
|
2522
|
-
{
|
2523
|
-
code: "sbp",
|
2524
|
-
name: "Sangu (sbp)"
|
2525
|
-
},
|
2526
|
-
{
|
2527
|
-
code: "sbp-TZ",
|
2528
|
-
name: "Sangu (Tanzania) (sbp-TZ)"
|
2529
|
-
},
|
2530
|
-
{
|
2531
|
-
code: "sa",
|
2532
|
-
name: "Sanskrit (sa)"
|
2533
|
-
},
|
2534
|
-
{
|
2535
|
-
code: "gd",
|
2536
|
-
name: "Scottish Gaelic (gd)"
|
2537
|
-
},
|
2538
|
-
{
|
2539
|
-
code: "gd-GB",
|
2540
|
-
name: "Scottish Gaelic (United Kingdom)"
|
2541
|
-
},
|
2542
|
-
{
|
2543
|
-
code: "seh",
|
2544
|
-
name: "Sena (seh)"
|
2545
|
-
},
|
2546
|
-
{
|
2547
|
-
code: "seh-MZ",
|
2548
|
-
name: "Sena (Mozambique) (seh-MZ)"
|
2549
|
-
},
|
2550
|
-
{
|
2551
|
-
code: "sr",
|
2552
|
-
name: "Serbian (sr)"
|
2553
|
-
},
|
2554
|
-
{
|
2555
|
-
code: "sr-Cyrl",
|
2556
|
-
name: "Serbian (Cyrillic) (sr-Cyrl)"
|
2557
|
-
},
|
2558
|
-
{
|
2559
|
-
code: "sr-Cyrl-BA",
|
2560
|
-
name: "Serbian (Cyrillic, Bosnia and Herzegovina)(sr-Cyrl-BA) "
|
2561
|
-
},
|
2562
|
-
{
|
2563
|
-
code: "sr-Cyrl-ME",
|
2564
|
-
name: "Serbian (Cyrillic, Montenegro) (sr-Cyrl-ME)"
|
2565
|
-
},
|
2566
|
-
{
|
2567
|
-
code: "sr-Cyrl-RS",
|
2568
|
-
name: "Serbian (Cyrillic, Serbia) (sr-Cyrl-RS)"
|
2569
|
-
},
|
2570
|
-
{
|
2571
|
-
code: "sr-Latn",
|
2572
|
-
name: "Serbian (Latin) (sr-Latn)"
|
2573
|
-
},
|
2574
|
-
{
|
2575
|
-
code: "sr-Latn-BA",
|
2576
|
-
name: "Serbian (Latin, Bosnia and Herzegovina) (sr-Latn-BA) "
|
2577
|
-
},
|
2578
|
-
{
|
2579
|
-
code: "sr-Latn-ME",
|
2580
|
-
name: "Serbian (Latin, Montenegro) (sr-Latn-ME)"
|
2581
|
-
},
|
2582
|
-
{
|
2583
|
-
code: "sr-Latn-RS",
|
2584
|
-
name: "Serbian (Latin, Serbia) (sr-Latn-RS)"
|
2585
|
-
},
|
2586
|
-
{
|
2587
|
-
code: "ksb",
|
2588
|
-
name: "Shambala (ksb)"
|
2589
|
-
},
|
2590
|
-
{
|
2591
|
-
code: "ksb-TZ",
|
2592
|
-
name: "Shambala (Tanzania) (ksb-TZ)"
|
2593
|
-
},
|
2594
|
-
{
|
2595
|
-
code: "sn",
|
2596
|
-
name: "Shona (sn)"
|
2597
|
-
},
|
2598
|
-
{
|
2599
|
-
code: "sn-ZW",
|
2600
|
-
name: "Shona (Zimbabwe) (sn-ZW)"
|
2601
|
-
},
|
2602
|
-
{
|
2603
|
-
code: "ii",
|
2604
|
-
name: "Sichuan Yi (ii)"
|
2605
|
-
},
|
2606
|
-
{
|
2607
|
-
code: "ii-CN",
|
2608
|
-
name: "Sichuan Yi (China) (ii-CN)"
|
2609
|
-
},
|
2610
|
-
{
|
2611
|
-
code: "si",
|
2612
|
-
name: "Sinhala (si)"
|
2613
|
-
},
|
2614
|
-
{
|
2615
|
-
code: "si-LK",
|
2616
|
-
name: "Sinhala (Sri Lanka) (si-LK)"
|
2617
|
-
},
|
2618
|
-
{
|
2619
|
-
code: "sk",
|
2620
|
-
name: "Slovak (sk)"
|
2621
|
-
},
|
2622
|
-
{
|
2623
|
-
code: "sk-SK",
|
2624
|
-
name: "Slovak (Slovakia) (sk-SK)"
|
2625
|
-
},
|
2626
|
-
{
|
2627
|
-
code: "sl",
|
2628
|
-
name: "Slovenian (sl)"
|
2629
|
-
},
|
2630
|
-
{
|
2631
|
-
code: "sl-SI",
|
2632
|
-
name: "Slovenian (Slovenia) (sl-SI)"
|
2633
|
-
},
|
2634
|
-
{
|
2635
|
-
code: "xog",
|
2636
|
-
name: "Soga (xog)"
|
2637
|
-
},
|
2638
|
-
{
|
2639
|
-
code: "xog-UG",
|
2640
|
-
name: "Soga (Uganda) (xog-UG)"
|
2641
|
-
},
|
2642
|
-
{
|
2643
|
-
code: "so",
|
2644
|
-
name: "Somali (so)"
|
2645
|
-
},
|
2646
|
-
{
|
2647
|
-
code: "so-DJ",
|
2648
|
-
name: "Somali (Djibouti) (so-DJ)"
|
2649
|
-
},
|
2650
|
-
{
|
2651
|
-
code: "so-ET",
|
2652
|
-
name: "Somali (Ethiopia) (so-ET)"
|
2653
|
-
},
|
2654
|
-
{
|
2655
|
-
code: "so-KE",
|
2656
|
-
name: "Somali (Kenya) (so-KE)"
|
2657
|
-
},
|
2658
|
-
{
|
2659
|
-
code: "so-SO",
|
2660
|
-
name: "Somali (Somalia) (so-SO)"
|
2661
|
-
},
|
2662
|
-
{
|
2663
|
-
code: "es",
|
2664
|
-
name: "Spanish (es)"
|
2665
|
-
},
|
2666
|
-
{
|
2667
|
-
code: "es-AR",
|
2668
|
-
name: "Spanish (Argentina) (es-AR)"
|
2669
|
-
},
|
2670
|
-
{
|
2671
|
-
code: "es-BO",
|
2672
|
-
name: "Spanish (Bolivia) (es-BO)"
|
2673
|
-
},
|
2674
|
-
{
|
2675
|
-
code: "es-CL",
|
2676
|
-
name: "Spanish (Chile) (es-CL)"
|
2677
|
-
},
|
2678
|
-
{
|
2679
|
-
code: "es-CO",
|
2680
|
-
name: "Spanish (Colombia) (es-CO)"
|
2681
|
-
},
|
2682
|
-
{
|
2683
|
-
code: "es-CR",
|
2684
|
-
name: "Spanish (Costa Rica) (es-CR)"
|
2685
|
-
},
|
2686
|
-
{
|
2687
|
-
code: "es-DO",
|
2688
|
-
name: "Spanish (Dominican Republic) (es-DO)"
|
2689
|
-
},
|
2690
|
-
{
|
2691
|
-
code: "es-EC",
|
2692
|
-
name: "Spanish (Ecuador) (es-EC)"
|
2693
|
-
},
|
2694
|
-
{
|
2695
|
-
code: "es-SV",
|
2696
|
-
name: "Spanish (El Salvador) (es-SV)"
|
2697
|
-
},
|
2698
|
-
{
|
2699
|
-
code: "es-GQ",
|
2700
|
-
name: "Spanish (Equatorial Guinea) (es-GQ)"
|
2701
|
-
},
|
2702
|
-
{
|
2703
|
-
code: "es-GT",
|
2704
|
-
name: "Spanish (Guatemala) (es-GT)"
|
2705
|
-
},
|
2706
|
-
{
|
2707
|
-
code: "es-HN",
|
2708
|
-
name: "Spanish (Honduras) (es-HN)"
|
2709
|
-
},
|
2710
|
-
{
|
2711
|
-
code: "es-419",
|
2712
|
-
name: "Spanish (Latin America) (es-419)"
|
2713
|
-
},
|
2714
|
-
{
|
2715
|
-
code: "es-MX",
|
2716
|
-
name: "Spanish (Mexico) (es-MX)"
|
2717
|
-
},
|
2718
|
-
{
|
2719
|
-
code: "es-NI",
|
2720
|
-
name: "Spanish (Nicaragua) (es-NI)"
|
2721
|
-
},
|
2722
|
-
{
|
2723
|
-
code: "es-PA",
|
2724
|
-
name: "Spanish (Panama) (es-PA)"
|
2725
|
-
},
|
2726
|
-
{
|
2727
|
-
code: "es-PY",
|
2728
|
-
name: "Spanish (Paraguay) (es-PY)"
|
2729
|
-
},
|
2730
|
-
{
|
2731
|
-
code: "es-PE",
|
2732
|
-
name: "Spanish (Peru) (es-PE)"
|
2733
|
-
},
|
2734
|
-
{
|
2735
|
-
code: "es-PR",
|
2736
|
-
name: "Spanish (Puerto Rico) (es-PR)"
|
2737
|
-
},
|
2738
|
-
{
|
2739
|
-
code: "es-ES",
|
2740
|
-
name: "Spanish (Spain) (es-ES)"
|
2741
|
-
},
|
2742
|
-
{
|
2743
|
-
code: "es-US",
|
2744
|
-
name: "Spanish (United States) (es-US)"
|
2745
|
-
},
|
2746
|
-
{
|
2747
|
-
code: "es-UY",
|
2748
|
-
name: "Spanish (Uruguay) (es-UY)"
|
2749
|
-
},
|
2750
|
-
{
|
2751
|
-
code: "es-VE",
|
2752
|
-
name: "Spanish (Venezuela) (es-VE)"
|
2753
|
-
},
|
2754
|
-
{
|
2755
|
-
code: "sw",
|
2756
|
-
name: "Swahili (sw)"
|
2757
|
-
},
|
2758
|
-
{
|
2759
|
-
code: "sw-KE",
|
2760
|
-
name: "Swahili (Kenya) (sw-KE)"
|
2761
|
-
},
|
2762
|
-
{
|
2763
|
-
code: "sw-TZ",
|
2764
|
-
name: "Swahili (Tanzania) (sw-TZ)"
|
2765
|
-
},
|
2766
|
-
{
|
2767
|
-
code: "sv",
|
2768
|
-
name: "Swedish (sv)"
|
2769
|
-
},
|
2770
|
-
{
|
2771
|
-
code: "sv-FI",
|
2772
|
-
name: "Swedish (Finland) (sv-FI)"
|
2773
|
-
},
|
2774
|
-
{
|
2775
|
-
code: "sv-SE",
|
2776
|
-
name: "Swedish (Sweden) (sv-SE)"
|
2777
|
-
},
|
2778
|
-
{
|
2779
|
-
code: "gsw",
|
2780
|
-
name: "Swiss German (gsw)"
|
2781
|
-
},
|
2782
|
-
{
|
2783
|
-
code: "gsw-CH",
|
2784
|
-
name: "Swiss German (Switzerland) (gsw-CH)"
|
2785
|
-
},
|
2786
|
-
{
|
2787
|
-
code: "shi",
|
2788
|
-
name: "Tachelhit (shi)"
|
2789
|
-
},
|
2790
|
-
{
|
2791
|
-
code: "shi-Latn",
|
2792
|
-
name: "Tachelhit (Latin) (shi-Latn)"
|
2793
|
-
},
|
2794
|
-
{
|
2795
|
-
code: "shi-Latn-MA",
|
2796
|
-
name: "Tachelhit (Latin, Morocco) (shi-Latn-MA)"
|
2797
|
-
},
|
2798
|
-
{
|
2799
|
-
code: "shi-Tfng",
|
2800
|
-
name: "Tachelhit (Tifinagh) (shi-Tfng)"
|
2801
|
-
},
|
2802
|
-
{
|
2803
|
-
code: "shi-Tfng-MA",
|
2804
|
-
name: "Tachelhit (Tifinagh, Morocco) (shi-Tfng-MA)"
|
2805
|
-
},
|
2806
|
-
{
|
2807
|
-
code: "dav",
|
2808
|
-
name: "Taita (dav)"
|
2809
|
-
},
|
2810
|
-
{
|
2811
|
-
code: "dav-KE",
|
2812
|
-
name: "Taita (Kenya) (dav-KE)"
|
2813
|
-
},
|
2814
|
-
{
|
2815
|
-
code: "tg",
|
2816
|
-
name: "Tajik (tg)"
|
2817
|
-
},
|
2818
|
-
{
|
2819
|
-
code: "ta",
|
2820
|
-
name: "Tamil (ta)"
|
2821
|
-
},
|
2822
|
-
{
|
2823
|
-
code: "ta-IN",
|
2824
|
-
name: "Tamil (India) (ta-IN)"
|
2825
|
-
},
|
2826
|
-
{
|
2827
|
-
code: "ta-LK",
|
2828
|
-
name: "Tamil (Sri Lanka) (ta-LK)"
|
2829
|
-
},
|
2830
|
-
{
|
2831
|
-
code: "twq",
|
2832
|
-
name: "Tasawaq (twq)"
|
2833
|
-
},
|
2834
|
-
{
|
2835
|
-
code: "twq-NE",
|
2836
|
-
name: "Tasawaq (Niger) (twq-NE)"
|
2837
|
-
},
|
2838
|
-
{
|
2839
|
-
code: "mi",
|
2840
|
-
name: "Te Reo Māori (mi)"
|
2841
|
-
},
|
2842
|
-
{
|
2843
|
-
code: "te",
|
2844
|
-
name: "Telugu (te)"
|
2845
|
-
},
|
2846
|
-
{
|
2847
|
-
code: "te-IN",
|
2848
|
-
name: "Telugu (India) (te-IN)"
|
2849
|
-
},
|
2850
|
-
{
|
2851
|
-
code: "teo",
|
2852
|
-
name: "Teso (teo)"
|
2853
|
-
},
|
2854
|
-
{
|
2855
|
-
code: "teo-KE",
|
2856
|
-
name: "Teso (Kenya) (teo-KE)"
|
2857
|
-
},
|
2858
|
-
{
|
2859
|
-
code: "teo-UG",
|
2860
|
-
name: "Teso (Uganda) (teo-UG)"
|
2861
|
-
},
|
2862
|
-
{
|
2863
|
-
code: "th",
|
2864
|
-
name: "Thai (th)"
|
2865
|
-
},
|
2866
|
-
{
|
2867
|
-
code: "th-TH",
|
2868
|
-
name: "Thai (Thailand) (th-TH)"
|
2869
|
-
},
|
2870
|
-
{
|
2871
|
-
code: "bo",
|
2872
|
-
name: "Tibetan (bo)"
|
2873
|
-
},
|
2874
|
-
{
|
2875
|
-
code: "bo-CN",
|
2876
|
-
name: "Tibetan (China) (bo-CN)"
|
2877
|
-
},
|
2878
|
-
{
|
2879
|
-
code: "bo-IN",
|
2880
|
-
name: "Tibetan (India) (bo-IN)"
|
2881
|
-
},
|
2882
|
-
{
|
2883
|
-
code: "ti",
|
2884
|
-
name: "Tigrinya (ti)"
|
2885
|
-
},
|
2886
|
-
{
|
2887
|
-
code: "ti-ER",
|
2888
|
-
name: "Tigrinya (Eritrea) (ti-ER)"
|
2889
|
-
},
|
2890
|
-
{
|
2891
|
-
code: "ti-ET",
|
2892
|
-
name: "Tigrinya (Ethiopia) (ti-ET)"
|
2893
|
-
},
|
2894
|
-
{
|
2895
|
-
code: "to",
|
2896
|
-
name: "Tongan (to)"
|
2897
|
-
},
|
2898
|
-
{
|
2899
|
-
code: "to-TO",
|
2900
|
-
name: "Tongan (Tonga) (to-TO)"
|
2901
|
-
},
|
2902
|
-
{
|
2903
|
-
code: "tr",
|
2904
|
-
name: "Turkish (tr)"
|
2905
|
-
},
|
2906
|
-
{
|
2907
|
-
code: "tk",
|
2908
|
-
name: "Turkmen (tk)"
|
2909
|
-
},
|
2910
|
-
{
|
2911
|
-
code: "tr-TR",
|
2912
|
-
name: "Turkish (Turkey) (tr-TR)"
|
2913
|
-
},
|
2914
|
-
{
|
2915
|
-
code: "tch",
|
2916
|
-
name: "Turks And Caicos Creole English"
|
2917
|
-
},
|
2918
|
-
{
|
2919
|
-
code: "uk",
|
2920
|
-
name: "Ukrainian (uk)"
|
2921
|
-
},
|
2922
|
-
{
|
2923
|
-
code: "uk-UA",
|
2924
|
-
name: "Ukrainian (Ukraine) (uk-UA)"
|
2925
|
-
},
|
2926
|
-
{
|
2927
|
-
code: "ur",
|
2928
|
-
name: "Urdu (ur)"
|
2929
|
-
},
|
2930
|
-
{
|
2931
|
-
code: "ur-IN",
|
2932
|
-
name: "Urdu (India) (ur-IN)"
|
2933
|
-
},
|
2934
|
-
{
|
2935
|
-
code: "ur-PK",
|
2936
|
-
name: "Urdu (Pakistan) (ur-PK)"
|
2937
|
-
},
|
2938
|
-
{
|
2939
|
-
code: "ug",
|
2940
|
-
name: "Uyghur"
|
2941
|
-
},
|
2942
|
-
{
|
2943
|
-
code: "ug-CN",
|
2944
|
-
name: "Uyghur (China)"
|
2945
|
-
},
|
2946
|
-
{
|
2947
|
-
code: "uz",
|
2948
|
-
name: "Uzbek (uz)"
|
2949
|
-
},
|
2950
|
-
{
|
2951
|
-
code: "uz-Arab",
|
2952
|
-
name: "Uzbek (Arabic) (uz-Arab)"
|
2953
|
-
},
|
2954
|
-
{
|
2955
|
-
code: "uz-Arab-AF",
|
2956
|
-
name: "Uzbek (Arabic, Afghanistan) (uz-Arab-AF)"
|
2957
|
-
},
|
2958
|
-
{
|
2959
|
-
code: "uz-Cyrl",
|
2960
|
-
name: "Uzbek (Cyrillic) (uz-Cyrl)"
|
2961
|
-
},
|
2962
|
-
{
|
2963
|
-
code: "uz-Cyrl-UZ",
|
2964
|
-
name: "Uzbek (Cyrillic, Uzbekistan) (uz-Cyrl-UZ)"
|
2965
|
-
},
|
2966
|
-
{
|
2967
|
-
code: "uz-Latn",
|
2968
|
-
name: "Uzbek (Latin) (uz-Latn)"
|
2969
|
-
},
|
2970
|
-
{
|
2971
|
-
code: "uz-Latn-UZ",
|
2972
|
-
name: "Uzbek (Latin, Uzbekistan) (uz-Latn-UZ)"
|
2973
|
-
},
|
2974
|
-
{
|
2975
|
-
code: "vai",
|
2976
|
-
name: "Vai (vai)"
|
2977
|
-
},
|
2978
|
-
{
|
2979
|
-
code: "vai-Latn",
|
2980
|
-
name: "Vai (Latin) (vai-Latn)"
|
2981
|
-
},
|
2982
|
-
{
|
2983
|
-
code: "vai-Latn-LR",
|
2984
|
-
name: "Vai (Latin, Liberia) (vai-Latn-LR)"
|
2985
|
-
},
|
2986
|
-
{
|
2987
|
-
code: "vai-Vaii",
|
2988
|
-
name: "Vai (Vai) (vai-Vaii)"
|
2989
|
-
},
|
2990
|
-
{
|
2991
|
-
code: "vai-Vaii-LR",
|
2992
|
-
name: "Vai (Vai, Liberia) (vai-Vaii-LR)"
|
2993
|
-
},
|
2994
|
-
{
|
2995
|
-
code: "val",
|
2996
|
-
name: "Valencian (val)"
|
2997
|
-
},
|
2998
|
-
{
|
2999
|
-
code: "val-ES",
|
3000
|
-
name: "Valencian (Spain) (val-ES)"
|
3001
|
-
},
|
3002
|
-
{
|
3003
|
-
code: "ca-ES-valencia",
|
3004
|
-
name: "Valencian (Spain Catalan) (ca-ES-valencia)"
|
3005
|
-
},
|
3006
|
-
{
|
3007
|
-
code: "vi",
|
3008
|
-
name: "Vietnamese (vi)"
|
3009
|
-
},
|
3010
|
-
{
|
3011
|
-
code: "vi-VN",
|
3012
|
-
name: "Vietnamese (Vietnam) (vi-VN)"
|
3013
|
-
},
|
3014
|
-
{
|
3015
|
-
code: "vun",
|
3016
|
-
name: "Vunjo (vun)"
|
3017
|
-
},
|
3018
|
-
{
|
3019
|
-
code: "vun-TZ",
|
3020
|
-
name: "Vunjo (Tanzania) (vun-TZ)"
|
3021
|
-
},
|
3022
|
-
{
|
3023
|
-
code: "cy",
|
3024
|
-
name: "Welsh (cy)"
|
3025
|
-
},
|
3026
|
-
{
|
3027
|
-
code: "cy-GB",
|
3028
|
-
name: "Welsh (United Kingdom) (cy-GB)"
|
3029
|
-
},
|
3030
|
-
{
|
3031
|
-
code: "wo",
|
3032
|
-
name: "Wolof (wo)"
|
3033
|
-
},
|
3034
|
-
{
|
3035
|
-
code: "xh",
|
3036
|
-
name: "Xhosa (xh)"
|
3037
|
-
},
|
3038
|
-
{
|
3039
|
-
code: "yav",
|
3040
|
-
name: "Yangben (yav)"
|
3041
|
-
},
|
3042
|
-
{
|
3043
|
-
code: "yav-CM",
|
3044
|
-
name: "Yangben (Cameroon) (yav-CM)"
|
3045
|
-
},
|
3046
|
-
{
|
3047
|
-
code: "yo",
|
3048
|
-
name: "Yoruba (yo)"
|
3049
|
-
},
|
3050
|
-
{
|
3051
|
-
code: "yo-NG",
|
3052
|
-
name: "Yoruba (Nigeria) (yo-NG)"
|
3053
|
-
},
|
3054
|
-
{
|
3055
|
-
code: "dje",
|
3056
|
-
name: "Zarma (dje)"
|
3057
|
-
},
|
3058
|
-
{
|
3059
|
-
code: "dje-NE",
|
3060
|
-
name: "Zarma (Niger) (dje-NE)"
|
3061
|
-
},
|
3062
|
-
{
|
3063
|
-
code: "zu",
|
3064
|
-
name: "Zulu (zu)"
|
3065
|
-
},
|
3066
|
-
{
|
3067
|
-
code: "zu-ZA",
|
3068
|
-
name: "Zulu (South Africa) (zu-ZA)"
|
3069
|
-
}
|
3070
|
-
];
|
3071
|
-
|
3072
|
-
/**
|
3073
|
-
* Returns the default locale based either on env var or english
|
3074
|
-
* @returns {string}
|
3075
|
-
*/ const getInitLocale = ()=>{
|
3076
|
-
const envLocaleCode = process.env.STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE;
|
3077
|
-
if (envLocaleCode) {
|
3078
|
-
const matchingLocale = isoLocales.find(({ code })=>code === envLocaleCode);
|
3079
|
-
if (!matchingLocale) {
|
3080
|
-
throw new Error('Unknown locale code provided in the environment variable STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE');
|
3081
|
-
}
|
3082
|
-
return {
|
3083
|
-
...matchingLocale
|
3084
|
-
};
|
3085
|
-
}
|
3086
|
-
return {
|
3087
|
-
code: 'en',
|
3088
|
-
name: 'English (en)'
|
3089
|
-
};
|
3090
|
-
};
|
3091
|
-
const DEFAULT_LOCALE = getInitLocale();
|
3092
|
-
|
3093
|
-
const find = (params = {})=>strapi.db.query('plugin::i18n.locale').findMany({
|
3094
|
-
where: params
|
3095
|
-
});
|
3096
|
-
const findById = (id)=>strapi.db.query('plugin::i18n.locale').findOne({
|
3097
|
-
where: {
|
3098
|
-
id
|
3099
|
-
}
|
3100
|
-
});
|
3101
|
-
const findByCode = (code)=>strapi.db.query('plugin::i18n.locale').findOne({
|
3102
|
-
where: {
|
3103
|
-
code
|
3104
|
-
}
|
3105
|
-
});
|
3106
|
-
const count = (params = {})=>strapi.db.query('plugin::i18n.locale').count({
|
3107
|
-
where: params
|
3108
|
-
});
|
3109
|
-
const create = async (locale)=>{
|
3110
|
-
const result = await strapi.db.query('plugin::i18n.locale').create({
|
3111
|
-
data: locale
|
3112
|
-
});
|
3113
|
-
getService('metrics').sendDidUpdateI18nLocalesEvent();
|
3114
|
-
return result;
|
3115
|
-
};
|
3116
|
-
const update = async (params, updates)=>{
|
3117
|
-
const result = await strapi.db.query('plugin::i18n.locale').update({
|
3118
|
-
where: params,
|
3119
|
-
data: updates
|
3120
|
-
});
|
3121
|
-
getService('metrics').sendDidUpdateI18nLocalesEvent();
|
3122
|
-
return result;
|
3123
|
-
};
|
3124
|
-
const deleteFn = async ({ id })=>{
|
3125
|
-
const localeToDelete = await findById(id);
|
3126
|
-
if (localeToDelete) {
|
3127
|
-
await deleteAllLocalizedEntriesFor({
|
3128
|
-
locale: localeToDelete.code
|
3129
|
-
});
|
3130
|
-
const result = await strapi.db.query('plugin::i18n.locale').delete({
|
3131
|
-
where: {
|
3132
|
-
id
|
3133
|
-
}
|
3134
|
-
});
|
3135
|
-
getService('metrics').sendDidUpdateI18nLocalesEvent();
|
3136
|
-
return result;
|
3137
|
-
}
|
3138
|
-
return localeToDelete;
|
3139
|
-
};
|
3140
|
-
const setDefaultLocale = ({ code })=>getCoreStore().set({
|
3141
|
-
key: 'default_locale',
|
3142
|
-
value: code
|
3143
|
-
});
|
3144
|
-
const getDefaultLocale = ()=>getCoreStore().get({
|
3145
|
-
key: 'default_locale'
|
3146
|
-
});
|
3147
|
-
const setIsDefault = async (locales)=>{
|
3148
|
-
if (isNil(locales)) {
|
3149
|
-
return locales;
|
3150
|
-
}
|
3151
|
-
const actualDefault = await getDefaultLocale();
|
3152
|
-
if (Array.isArray(locales)) {
|
3153
|
-
return locales.map((locale)=>({
|
3154
|
-
...locale,
|
3155
|
-
isDefault: actualDefault === locale.code
|
3156
|
-
}));
|
3157
|
-
}
|
3158
|
-
// single locale
|
3159
|
-
return {
|
3160
|
-
...locales,
|
3161
|
-
isDefault: actualDefault === locales.code
|
3162
|
-
};
|
3163
|
-
};
|
3164
|
-
const initDefaultLocale = async ()=>{
|
3165
|
-
const existingLocalesNb = await strapi.db.query('plugin::i18n.locale').count();
|
3166
|
-
if (existingLocalesNb === 0) {
|
3167
|
-
await create(DEFAULT_LOCALE);
|
3168
|
-
await setDefaultLocale({
|
3169
|
-
code: DEFAULT_LOCALE.code
|
3170
|
-
});
|
3171
|
-
}
|
3172
|
-
};
|
3173
|
-
const deleteAllLocalizedEntriesFor = async ({ locale })=>{
|
3174
|
-
const { isLocalizedContentType } = getService('content-types');
|
3175
|
-
const localizedModels = Object.values(strapi.contentTypes).filter(isLocalizedContentType);
|
3176
|
-
for (const model of localizedModels){
|
3177
|
-
// FIXME: delete many content & their associations
|
3178
|
-
await strapi.db.query(model.uid).deleteMany({
|
3179
|
-
where: {
|
3180
|
-
locale
|
3181
|
-
}
|
3182
|
-
});
|
3183
|
-
}
|
3184
|
-
};
|
3185
|
-
const locales = ()=>({
|
3186
|
-
find,
|
3187
|
-
findById,
|
3188
|
-
findByCode,
|
3189
|
-
create,
|
3190
|
-
update,
|
3191
|
-
count,
|
3192
|
-
setDefaultLocale,
|
3193
|
-
getDefaultLocale,
|
3194
|
-
setIsDefault,
|
3195
|
-
delete: deleteFn,
|
3196
|
-
initDefaultLocale
|
3197
|
-
});
|
3198
|
-
|
3199
|
-
const getIsoLocales = ()=>isoLocales;
|
3200
|
-
const isoLocalesService = ()=>({
|
3201
|
-
getIsoLocales
|
3202
|
-
});
|
3203
|
-
|
3204
|
-
const { isRelationalAttribute, getVisibleAttributes, isTypedAttribute, getScalarAttributes, getRelationalAttributes } = contentTypes$2;
|
3205
|
-
const { ApplicationError: ApplicationError$2 } = errors;
|
3206
|
-
const hasLocalizedOption = (modelOrAttribute)=>{
|
3207
|
-
return prop('pluginOptions.i18n.localized', modelOrAttribute) === true;
|
3208
|
-
};
|
3209
|
-
const getValidLocale = async (locale)=>{
|
3210
|
-
const localesService = getService('locales');
|
3211
|
-
if (isNil(locale)) {
|
3212
|
-
return localesService.getDefaultLocale();
|
3213
|
-
}
|
3214
|
-
const foundLocale = await localesService.findByCode(locale);
|
3215
|
-
if (!foundLocale) {
|
3216
|
-
throw new ApplicationError$2('Locale not found');
|
3217
|
-
}
|
3218
|
-
return locale;
|
3219
|
-
};
|
3220
|
-
/**
|
3221
|
-
* Returns whether an attribute is localized or not
|
3222
|
-
* @param {*} attribute
|
3223
|
-
* @returns
|
3224
|
-
*/ const isLocalizedAttribute = (attribute)=>{
|
3225
|
-
return hasLocalizedOption(attribute) || isRelationalAttribute(attribute) || isTypedAttribute(attribute, 'uid');
|
3226
|
-
};
|
3227
|
-
/**
|
3228
|
-
* Returns whether a model is localized or not
|
3229
|
-
* @param {*} model
|
3230
|
-
* @returns
|
3231
|
-
*/ const isLocalizedContentType = (model)=>{
|
3232
|
-
return hasLocalizedOption(model);
|
3233
|
-
};
|
3234
|
-
/**
|
3235
|
-
* Returns the list of attribute names that are not localized
|
3236
|
-
* @param {object} model
|
3237
|
-
* @returns {string[]}
|
3238
|
-
*/ const getNonLocalizedAttributes = (model)=>{
|
3239
|
-
return getVisibleAttributes(model).filter((attrName)=>!isLocalizedAttribute(model.attributes[attrName]));
|
3240
|
-
};
|
3241
|
-
const removeId = (value)=>{
|
3242
|
-
if (typeof value === 'object' && has('id', value)) {
|
3243
|
-
delete value.id;
|
3244
|
-
}
|
3245
|
-
};
|
3246
|
-
const removeIds = (model)=>(entry)=>removeIdsMut(model, cloneDeep(entry));
|
3247
|
-
const removeIdsMut = (model, entry)=>{
|
3248
|
-
if (isNil(entry)) {
|
3249
|
-
return entry;
|
3250
|
-
}
|
3251
|
-
removeId(entry);
|
3252
|
-
_.forEach(model.attributes, (attr, attrName)=>{
|
3253
|
-
const value = entry[attrName];
|
3254
|
-
if (attr.type === 'dynamiczone' && isArray(value)) {
|
3255
|
-
value.forEach((compo)=>{
|
3256
|
-
if (has('__component', compo)) {
|
3257
|
-
const model = strapi.components[compo.__component];
|
3258
|
-
removeIdsMut(model, compo);
|
3259
|
-
}
|
3260
|
-
});
|
3261
|
-
} else if (attr.type === 'component') {
|
3262
|
-
const model = strapi.components[attr.component];
|
3263
|
-
if (isArray(value)) {
|
3264
|
-
value.forEach((compo)=>removeIdsMut(model, compo));
|
3265
|
-
} else {
|
3266
|
-
removeIdsMut(model, value);
|
3267
|
-
}
|
3268
|
-
}
|
3269
|
-
});
|
3270
|
-
return entry;
|
3271
|
-
};
|
3272
|
-
/**
|
3273
|
-
* Returns a copy of an entry picking only its non localized attributes
|
3274
|
-
* @param {object} model
|
3275
|
-
* @param {object} entry
|
3276
|
-
* @returns {object}
|
3277
|
-
*/ const copyNonLocalizedAttributes = (model, entry)=>{
|
3278
|
-
const nonLocalizedAttributes = getNonLocalizedAttributes(model);
|
3279
|
-
return pipe(pick(nonLocalizedAttributes), removeIds(model))(entry);
|
3280
|
-
};
|
3281
|
-
/**
|
3282
|
-
* Returns the list of attribute names that are localized
|
3283
|
-
* @param {object} model
|
3284
|
-
* @returns {string[]}
|
3285
|
-
*/ const getLocalizedAttributes = (model)=>{
|
3286
|
-
return getVisibleAttributes(model).filter((attrName)=>isLocalizedAttribute(model.attributes[attrName]));
|
3287
|
-
};
|
3288
|
-
/**
|
3289
|
-
* Fill non localized fields of an entry if there are nil
|
3290
|
-
* @param {Object} entry entry to fill
|
3291
|
-
* @param {Object} relatedEntry values used to fill
|
3292
|
-
* @param {Object} options
|
3293
|
-
* @param {Object} options.model corresponding model
|
3294
|
-
*/ const fillNonLocalizedAttributes = (entry, relatedEntry, { model })=>{
|
3295
|
-
if (isNil(relatedEntry)) {
|
3296
|
-
return;
|
3297
|
-
}
|
3298
|
-
const modelDef = strapi.getModel(model);
|
3299
|
-
const relatedEntryCopy = copyNonLocalizedAttributes(modelDef, relatedEntry);
|
3300
|
-
_.forEach(relatedEntryCopy, (value, field)=>{
|
3301
|
-
if (isNil(entry[field])) {
|
3302
|
-
entry[field] = value;
|
3303
|
-
}
|
3304
|
-
});
|
3305
|
-
};
|
3306
|
-
/**
|
3307
|
-
* build the populate param to
|
3308
|
-
* @param {String} modelUID uid of the model, could be of a content-type or a component
|
3309
|
-
*/ const getNestedPopulateOfNonLocalizedAttributes = (modelUID)=>{
|
3310
|
-
const schema = strapi.getModel(modelUID);
|
3311
|
-
const scalarAttributes = getScalarAttributes(schema);
|
3312
|
-
const nonLocalizedAttributes = getNonLocalizedAttributes(schema);
|
3313
|
-
const allAttributes = [
|
3314
|
-
...scalarAttributes,
|
3315
|
-
...nonLocalizedAttributes
|
3316
|
-
];
|
3317
|
-
if (schema.modelType === 'component') {
|
3318
|
-
// When called recursively on a non localized component we
|
3319
|
-
// need to explicitly populate that components relations
|
3320
|
-
allAttributes.push(...getRelationalAttributes(schema));
|
3321
|
-
}
|
3322
|
-
const currentAttributesToPopulate = allAttributes.filter((value, index, self)=>{
|
3323
|
-
return self.indexOf(value) === index && self.lastIndexOf(value) === index;
|
3324
|
-
});
|
3325
|
-
const attributesToPopulate = [
|
3326
|
-
...currentAttributesToPopulate
|
3327
|
-
];
|
3328
|
-
for (const attrName of currentAttributesToPopulate){
|
3329
|
-
const attr = schema.attributes[attrName];
|
3330
|
-
if (attr.type === 'component') {
|
3331
|
-
const nestedPopulate = getNestedPopulateOfNonLocalizedAttributes(attr.component).map((nestedAttr)=>`${attrName}.${nestedAttr}`);
|
3332
|
-
attributesToPopulate.push(...nestedPopulate);
|
3333
|
-
} else if (attr.type === 'dynamiczone') {
|
3334
|
-
attr.components.forEach((componentName)=>{
|
3335
|
-
const nestedPopulate = getNestedPopulateOfNonLocalizedAttributes(componentName).map((nestedAttr)=>`${attrName}.${nestedAttr}`);
|
3336
|
-
attributesToPopulate.push(...nestedPopulate);
|
3337
|
-
});
|
3338
|
-
}
|
3339
|
-
}
|
3340
|
-
return attributesToPopulate;
|
3341
|
-
};
|
3342
|
-
const contentTypes = ()=>({
|
3343
|
-
isLocalizedContentType,
|
3344
|
-
getValidLocale,
|
3345
|
-
getLocalizedAttributes,
|
3346
|
-
getNonLocalizedAttributes,
|
3347
|
-
copyNonLocalizedAttributes,
|
3348
|
-
fillNonLocalizedAttributes,
|
3349
|
-
getNestedPopulateOfNonLocalizedAttributes
|
3350
|
-
});
|
3351
|
-
|
3352
|
-
const LOCALIZATION_FIELDS = [
|
3353
|
-
'locale',
|
3354
|
-
'localizations'
|
3355
|
-
];
|
3356
|
-
const sanitize = ({ strapi })=>{
|
3357
|
-
const { isLocalizedContentType } = getService('content-types');
|
3358
|
-
/**
|
3359
|
-
* Sanitizes localization fields of a given entity based on its schema.
|
3360
|
-
*
|
3361
|
-
* Remove localization-related fields that are unnecessary, that is
|
3362
|
-
* for schemas that aren't localized.
|
3363
|
-
*/ const sanitizeLocalizationFields = curry((schema, entity)=>traverseEntity(({ key, schema }, { remove })=>{
|
3364
|
-
const isLocalized = isLocalizedContentType(schema);
|
3365
|
-
const isLocalizationField = LOCALIZATION_FIELDS.includes(key);
|
3366
|
-
if (!isLocalized && isLocalizationField) {
|
3367
|
-
remove(key);
|
3368
|
-
}
|
3369
|
-
}, {
|
3370
|
-
schema,
|
3371
|
-
getModel: strapi.getModel.bind(strapi)
|
3372
|
-
}, entity));
|
3373
|
-
return {
|
3374
|
-
sanitizeLocalizationFields
|
3375
|
-
};
|
3376
|
-
};
|
3377
|
-
|
3378
|
-
var services = {
|
3379
|
-
permissions,
|
3380
|
-
metrics,
|
3381
|
-
localizations,
|
3382
|
-
locales,
|
3383
|
-
sanitize,
|
3384
|
-
'iso-locales': isoLocalesService,
|
3385
|
-
'content-types': contentTypes
|
3386
|
-
};
|
3387
|
-
|
3388
|
-
var admin = {
|
3389
|
-
type: 'admin',
|
3390
|
-
routes: [
|
3391
|
-
{
|
3392
|
-
method: 'GET',
|
3393
|
-
path: '/iso-locales',
|
3394
|
-
handler: 'iso-locales.listIsoLocales',
|
3395
|
-
config: {
|
3396
|
-
policies: [
|
3397
|
-
'admin::isAuthenticatedAdmin',
|
3398
|
-
{
|
3399
|
-
name: 'plugin::content-manager.hasPermissions',
|
3400
|
-
config: {
|
3401
|
-
actions: [
|
3402
|
-
'plugin::i18n.locale.read'
|
3403
|
-
]
|
3404
|
-
}
|
3405
|
-
}
|
3406
|
-
]
|
3407
|
-
}
|
3408
|
-
},
|
3409
|
-
{
|
3410
|
-
method: 'GET',
|
3411
|
-
path: '/locales',
|
3412
|
-
handler: 'locales.listLocales',
|
3413
|
-
config: {
|
3414
|
-
policies: [
|
3415
|
-
'admin::isAuthenticatedAdmin'
|
3416
|
-
]
|
3417
|
-
}
|
3418
|
-
},
|
3419
|
-
{
|
3420
|
-
method: 'POST',
|
3421
|
-
path: '/locales',
|
3422
|
-
handler: 'locales.createLocale',
|
3423
|
-
config: {
|
3424
|
-
policies: [
|
3425
|
-
'admin::isAuthenticatedAdmin',
|
3426
|
-
{
|
3427
|
-
name: 'plugin::content-manager.hasPermissions',
|
3428
|
-
config: {
|
3429
|
-
actions: [
|
3430
|
-
'plugin::i18n.locale.create'
|
3431
|
-
]
|
3432
|
-
}
|
3433
|
-
}
|
3434
|
-
]
|
3435
|
-
}
|
3436
|
-
},
|
3437
|
-
{
|
3438
|
-
method: 'PUT',
|
3439
|
-
path: '/locales/:id',
|
3440
|
-
handler: 'locales.updateLocale',
|
3441
|
-
config: {
|
3442
|
-
policies: [
|
3443
|
-
'admin::isAuthenticatedAdmin',
|
3444
|
-
{
|
3445
|
-
name: 'plugin::content-manager.hasPermissions',
|
3446
|
-
config: {
|
3447
|
-
actions: [
|
3448
|
-
'plugin::i18n.locale.update'
|
3449
|
-
]
|
3450
|
-
}
|
3451
|
-
}
|
3452
|
-
]
|
3453
|
-
}
|
3454
|
-
},
|
3455
|
-
{
|
3456
|
-
method: 'DELETE',
|
3457
|
-
path: '/locales/:id',
|
3458
|
-
handler: 'locales.deleteLocale',
|
3459
|
-
config: {
|
3460
|
-
policies: [
|
3461
|
-
'admin::isAuthenticatedAdmin',
|
3462
|
-
{
|
3463
|
-
name: 'plugin::content-manager.hasPermissions',
|
3464
|
-
config: {
|
3465
|
-
actions: [
|
3466
|
-
'plugin::i18n.locale.delete'
|
3467
|
-
]
|
3468
|
-
}
|
3469
|
-
}
|
3470
|
-
]
|
3471
|
-
}
|
3472
|
-
},
|
3473
|
-
{
|
3474
|
-
method: 'POST',
|
3475
|
-
path: '/content-manager/actions/get-non-localized-fields',
|
3476
|
-
handler: 'content-types.getNonLocalizedAttributes',
|
3477
|
-
config: {
|
3478
|
-
policies: [
|
3479
|
-
'admin::isAuthenticatedAdmin'
|
3480
|
-
]
|
3481
|
-
}
|
3482
|
-
}
|
3483
|
-
]
|
3484
|
-
};
|
3485
|
-
|
3486
|
-
var contentApi = {
|
3487
|
-
type: 'content-api',
|
3488
|
-
routes: [
|
3489
|
-
{
|
3490
|
-
method: 'GET',
|
3491
|
-
path: '/locales',
|
3492
|
-
handler: 'locales.listLocales'
|
3493
|
-
}
|
3494
|
-
]
|
3495
|
-
};
|
3496
|
-
|
3497
|
-
var routes = {
|
3498
|
-
admin,
|
3499
|
-
'content-api': contentApi
|
3500
|
-
};
|
3501
|
-
|
3502
|
-
const allowedLocaleCodes = isoLocales.map(prop('code'));
|
3503
|
-
const createLocaleSchema = yup.object().shape({
|
3504
|
-
name: yup.string().max(50).nullable(),
|
3505
|
-
code: yup.string().oneOf(allowedLocaleCodes).required(),
|
3506
|
-
isDefault: yup.boolean().required()
|
3507
|
-
}).noUnknown();
|
3508
|
-
const updateLocaleSchema = yup.object().shape({
|
3509
|
-
name: yup.string().min(1).max(50).nullable(),
|
3510
|
-
isDefault: yup.boolean()
|
3511
|
-
}).noUnknown();
|
3512
|
-
const validateCreateLocaleInput = validateYupSchema(createLocaleSchema);
|
3513
|
-
const validateUpdateLocaleInput = validateYupSchema(updateLocaleSchema);
|
3514
|
-
|
3515
|
-
const formatLocale = (locale)=>{
|
3516
|
-
return {
|
3517
|
-
...locale,
|
3518
|
-
name: locale.name || null
|
3519
|
-
};
|
3520
|
-
};
|
3521
|
-
|
3522
|
-
const { setCreatorFields } = utils;
|
3523
|
-
const { ApplicationError: ApplicationError$1 } = utils.errors;
|
3524
|
-
const sanitizeLocale = (locale)=>{
|
3525
|
-
const model = strapi.getModel('plugin::i18n.locale');
|
3526
|
-
return strapi.contentAPI.sanitize.output(locale, model);
|
3527
|
-
};
|
3528
|
-
const controller$2 = {
|
3529
|
-
async listLocales (ctx) {
|
3530
|
-
const localesService = getService('locales');
|
3531
|
-
const locales = await localesService.find();
|
3532
|
-
const sanitizedLocales = await sanitizeLocale(locales);
|
3533
|
-
ctx.body = await localesService.setIsDefault(sanitizedLocales);
|
3534
|
-
},
|
3535
|
-
async createLocale (ctx) {
|
3536
|
-
const { user } = ctx.state;
|
3537
|
-
const body = ctx.request.body;
|
3538
|
-
const { isDefault, ...localeToCreate } = body;
|
3539
|
-
await validateCreateLocaleInput(body);
|
3540
|
-
const localesService = getService('locales');
|
3541
|
-
const existingLocale = await localesService.findByCode(body.code);
|
3542
|
-
if (existingLocale) {
|
3543
|
-
throw new ApplicationError$1('This locale already exists');
|
3544
|
-
}
|
3545
|
-
const localeToPersist = setCreatorFields({
|
3546
|
-
user
|
3547
|
-
})(formatLocale(localeToCreate));
|
3548
|
-
const locale = await localesService.create(localeToPersist);
|
3549
|
-
if (isDefault) {
|
3550
|
-
await localesService.setDefaultLocale(locale);
|
3551
|
-
}
|
3552
|
-
const sanitizedLocale = await sanitizeLocale(locale);
|
3553
|
-
ctx.body = await localesService.setIsDefault(sanitizedLocale);
|
3554
|
-
},
|
3555
|
-
async updateLocale (ctx) {
|
3556
|
-
const { user } = ctx.state;
|
3557
|
-
const { id } = ctx.params;
|
3558
|
-
const body = ctx.request.body;
|
3559
|
-
const { isDefault, ...updates } = body;
|
3560
|
-
await validateUpdateLocaleInput(body);
|
3561
|
-
const localesService = getService('locales');
|
3562
|
-
const existingLocale = await localesService.findById(id);
|
3563
|
-
if (!existingLocale) {
|
3564
|
-
return ctx.notFound('locale.notFound');
|
3565
|
-
}
|
3566
|
-
const allowedParams = [
|
3567
|
-
'name'
|
3568
|
-
];
|
3569
|
-
const cleanUpdates = setCreatorFields({
|
3570
|
-
user,
|
3571
|
-
isEdition: true
|
3572
|
-
})(pick(allowedParams, updates));
|
3573
|
-
const updatedLocale = await localesService.update({
|
3574
|
-
id
|
3575
|
-
}, cleanUpdates);
|
3576
|
-
if (isDefault) {
|
3577
|
-
await localesService.setDefaultLocale(updatedLocale);
|
3578
|
-
}
|
3579
|
-
const sanitizedLocale = await sanitizeLocale(updatedLocale);
|
3580
|
-
ctx.body = await localesService.setIsDefault(sanitizedLocale);
|
3581
|
-
},
|
3582
|
-
async deleteLocale (ctx) {
|
3583
|
-
const { id } = ctx.params;
|
3584
|
-
const localesService = getService('locales');
|
3585
|
-
const existingLocale = await localesService.findById(id);
|
3586
|
-
if (!existingLocale) {
|
3587
|
-
return ctx.notFound('locale.notFound');
|
3588
|
-
}
|
3589
|
-
const defaultLocaleCode = await localesService.getDefaultLocale();
|
3590
|
-
if (existingLocale.code === defaultLocaleCode) {
|
3591
|
-
throw new ApplicationError$1('Cannot delete the default locale');
|
3592
|
-
}
|
3593
|
-
await localesService.delete({
|
3594
|
-
id
|
3595
|
-
});
|
3596
|
-
const sanitizedLocale = await sanitizeLocale(existingLocale);
|
3597
|
-
ctx.body = await localesService.setIsDefault(sanitizedLocale);
|
3598
|
-
}
|
3599
|
-
};
|
3600
|
-
|
3601
|
-
const validateGetNonLocalizedAttributesSchema = yup.object().shape({
|
3602
|
-
model: yup.string().required(),
|
3603
|
-
id: yup.mixed().when('model', {
|
3604
|
-
is: (model)=>get('kind', strapi.contentType(model)) === 'singleType',
|
3605
|
-
then: yup.strapiID().nullable(),
|
3606
|
-
otherwise: yup.strapiID().required()
|
3607
|
-
}),
|
3608
|
-
locale: yup.string().required()
|
3609
|
-
}).noUnknown().required();
|
3610
|
-
const validateGetNonLocalizedAttributesInput = validateYupSchema(validateGetNonLocalizedAttributesSchema);
|
3611
|
-
|
3612
|
-
const { ApplicationError } = errors;
|
3613
|
-
const { PUBLISHED_AT_ATTRIBUTE } = contentTypes$2.constants;
|
3614
|
-
const getLocalesProperty = getOr([], 'properties.locales');
|
3615
|
-
const getFieldsProperty = prop('properties.fields');
|
3616
|
-
const getFirstLevelPath = map((path)=>path.split('.')[0]);
|
3617
|
-
const controller$1 = {
|
3618
|
-
async getNonLocalizedAttributes (ctx) {
|
3619
|
-
const { user } = ctx.state;
|
3620
|
-
const body = ctx.request.body;
|
3621
|
-
const { model, id, locale } = body;
|
3622
|
-
await validateGetNonLocalizedAttributesInput({
|
3623
|
-
model,
|
3624
|
-
id,
|
3625
|
-
locale
|
3626
|
-
});
|
3627
|
-
const { copyNonLocalizedAttributes, isLocalizedContentType, getNestedPopulateOfNonLocalizedAttributes } = getService('content-types');
|
3628
|
-
const { default: { READ_ACTION, CREATE_ACTION } } = strapi.service('admin::constants');
|
3629
|
-
const modelDef = strapi.contentType(model);
|
3630
|
-
const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(model);
|
3631
|
-
if (!isLocalizedContentType(modelDef)) {
|
3632
|
-
throw new ApplicationError(`Model ${model} is not localized`);
|
3633
|
-
}
|
3634
|
-
const params = modelDef.kind === 'singleType' ? {} : {
|
3635
|
-
id
|
3636
|
-
};
|
3637
|
-
const entity = await strapi.db.query(model).findOne({
|
3638
|
-
where: params,
|
3639
|
-
populate: attributesToPopulate
|
3640
|
-
});
|
3641
|
-
if (!entity) {
|
3642
|
-
return ctx.notFound();
|
3643
|
-
}
|
3644
|
-
const permissions = await strapi.admin.services.permission.findMany({
|
3645
|
-
where: {
|
3646
|
-
action: [
|
3647
|
-
READ_ACTION,
|
3648
|
-
CREATE_ACTION
|
3649
|
-
],
|
3650
|
-
subject: model,
|
3651
|
-
role: {
|
3652
|
-
id: user.roles.map(prop('id'))
|
3653
|
-
}
|
3654
|
-
}
|
3655
|
-
});
|
3656
|
-
const localePermissions = permissions.filter((perm)=>getLocalesProperty(perm).includes(locale)).map(getFieldsProperty);
|
3657
|
-
const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);
|
3658
|
-
const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);
|
3659
|
-
const sanitizedNonLocalizedFields = pick(permittedFields, nonLocalizedFields);
|
3660
|
-
const availableLocalesResult = await strapi.plugins['content-manager'].service('document-metadata').getMetadata(model, entity, {
|
3661
|
-
availableLocales: true
|
3662
|
-
});
|
3663
|
-
const availableLocales = availableLocalesResult.availableLocales.map((localeResult)=>pick([
|
3664
|
-
'id',
|
3665
|
-
'locale',
|
3666
|
-
PUBLISHED_AT_ATTRIBUTE
|
3667
|
-
], localeResult));
|
3668
|
-
ctx.body = {
|
3669
|
-
nonLocalizedFields: sanitizedNonLocalizedFields,
|
3670
|
-
localizations: availableLocales.concat(pick([
|
3671
|
-
'id',
|
3672
|
-
'locale',
|
3673
|
-
PUBLISHED_AT_ATTRIBUTE
|
3674
|
-
], entity))
|
3675
|
-
};
|
3676
|
-
}
|
3677
|
-
};
|
3678
|
-
|
3679
|
-
const controller = {
|
3680
|
-
listIsoLocales (ctx) {
|
3681
|
-
const isoLocalesService = getService('iso-locales');
|
3682
|
-
ctx.body = isoLocalesService.getIsoLocales();
|
3683
|
-
}
|
3684
|
-
};
|
3685
|
-
|
3686
|
-
var controllers = {
|
3687
|
-
locales: controller$2,
|
3688
|
-
'iso-locales': controller,
|
3689
|
-
'content-types': controller$1
|
3690
|
-
};
|
1
|
+
import bootstrap from './bootstrap.mjs';
|
2
|
+
import register from './register.mjs';
|
3
|
+
import contentTypes from './content-types/index.mjs';
|
4
|
+
import services from './services/index.mjs';
|
5
|
+
import routes from './routes/index.mjs';
|
6
|
+
import controllers from './controllers/index.mjs';
|
3691
7
|
|
3692
8
|
var index = (()=>({
|
3693
9
|
register,
|
3694
10
|
bootstrap,
|
3695
11
|
routes,
|
3696
12
|
controllers,
|
3697
|
-
contentTypes
|
13
|
+
contentTypes,
|
3698
14
|
services
|
3699
15
|
}));
|
3700
16
|
|