From 70c6211e2ce632a2ed9bfc72a305c3b0b363b9fa Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Sat, 23 Jul 2022 22:56:13 -0700 Subject: [PATCH 01/34] Add draggable rows to table component --- components/common/Table.js | 39 +++++++++++++++++-- package.json | 1 + yarn.lock | 80 +++++++++++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/components/common/Table.js b/components/common/Table.js index 77a07712..acd4f160 100644 --- a/components/common/Table.js +++ b/components/common/Table.js @@ -1,3 +1,4 @@ +import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; @@ -13,6 +14,9 @@ function Table({ rowKey, showHeader = true, children, + isDraggable = false, + dragId, + onDragEnd, }) { if (empty && rows.length === 0) { return empty; @@ -36,10 +40,37 @@ function Table({
{rows.length === 0 && } {!children && - rows.map((row, index) => { - const id = rowKey ? rowKey(row) : index; - return ; - })} + (isDraggable ? ( + + + {provided => ( +
+ {rows.map((row, index) => { + const id = rowKey ? rowKey(row) : index; + return ( + + {provided => ( +
+ +
+ )} +
+ ); + })} +
+ )} +
+
+ ) : ( + rows.map((row, index) => { + const id = rowKey ? rowKey(row) : index; + return ; + }) + ))} {children}
diff --git a/package.json b/package.json index d37ba99b..53e3ca7d 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "npm-run-all": "^4.1.5", "prop-types": "^15.7.2", "react": "^17.0.0", + "react-beautiful-dnd": "^13.1.0", "react-dom": "^17.0.0", "react-intl": "^5.24.7", "react-simple-maps": "^2.3.0", diff --git a/yarn.lock b/yarn.lock index 144118b7..fe3bab24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -989,6 +989,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.15.4", "@babel/runtime@^7.9.2": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.8.4": version "7.17.2" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz" @@ -1725,7 +1732,7 @@ dependencies: "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -1778,6 +1785,16 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/react-redux@^7.1.20": + version "7.1.24" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.24.tgz#6caaff1603aba17b27d20f8ad073e4c077e975c0" + integrity sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react@*", "@types/react@16 || 17 || 18": version "18.0.10" resolved "https://registry.npmjs.org/@types/react/-/react-18.0.10.tgz" @@ -2617,6 +2634,13 @@ css-blank-pseudo@^3.0.3: dependencies: postcss-selector-parser "^6.0.9" +css-box-model@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== + dependencies: + tiny-invariant "^1.0.6" + css-functions-list@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b" @@ -4474,7 +4498,7 @@ mdn-data@2.0.14: resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== -"memoize-one@>=3.1.1 <6": +"memoize-one@>=3.1.1 <6", memoize-one@^5.1.1: version "5.2.1" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== @@ -5400,6 +5424,11 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +raf-schd@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a" + integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" @@ -5407,6 +5436,19 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +react-beautiful-dnd@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz#ec97c81093593526454b0de69852ae433783844d" + integrity sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA== + dependencies: + "@babel/runtime" "^7.9.2" + css-box-model "^1.2.0" + memoize-one "^5.1.1" + raf-schd "^4.0.2" + react-redux "^7.2.0" + redux "^4.0.4" + use-memo-one "^1.1.1" + react-dom@^17.0.0: version "17.0.2" resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" @@ -5442,6 +5484,23 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-redux@^7.2.0: + version "7.2.8" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de" + integrity sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw== + dependencies: + "@babel/runtime" "^7.15.4" + "@types/react-redux" "^7.1.20" + hoist-non-react-statics "^3.3.2" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^17.0.2" + react-simple-maps@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-2.3.0.tgz" @@ -5546,6 +5605,13 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redux@^4.0.0, redux@^4.0.4: + version "4.2.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" + integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA== + dependencies: + "@babel/runtime" "^7.9.2" + regenerate-unicode-properties@^10.0.1: version "10.0.1" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz" @@ -6319,6 +6385,11 @@ timezone-support@^2.0.2: dependencies: commander "2.20.0" +tiny-invariant@^1.0.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" + integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== + tiny-lru@8.0.2: version "8.0.2" resolved "https://registry.npmjs.org/tiny-lru/-/tiny-lru-8.0.2.tgz" @@ -6527,6 +6598,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +use-memo-one@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.2.tgz#0c8203a329f76e040047a35a1197defe342fab20" + integrity sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ== + use-sync-external-store@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82" From 3926d3fe93fc850fab8bea80ac3b78fd93f0532a Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Sat, 23 Jul 2022 23:01:59 -0700 Subject: [PATCH 02/34] Add website ordering to state and settings page --- components/settings/WebsiteSettings.js | 36 ++++++++++++++++++++++++-- lib/format.js | 11 ++++++++ store/app.js | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/components/settings/WebsiteSettings.js b/components/settings/WebsiteSettings.js index 257876be..4c39cf0c 100644 --- a/components/settings/WebsiteSettings.js +++ b/components/settings/WebsiteSettings.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import Link from 'components/common/Link'; @@ -24,8 +24,12 @@ import Code from 'assets/code.svg'; import LinkIcon from 'assets/link.svg'; import useFetch from 'hooks/useFetch'; import useUser from 'hooks/useUser'; +import { orderByWebsiteMap } from 'lib/format'; +import useStore, { setDashboard } from 'store/app'; import styles from './WebsiteSettings.module.css'; +const selector = state => state.dashboard; + export default function WebsiteSettings() { const { user } = useUser(); const [editWebsite, setEditWebsite] = useState(); @@ -36,8 +40,14 @@ export default function WebsiteSettings() { const [showUrl, setShowUrl] = useState(); const [saved, setSaved] = useState(0); const [message, setMessage] = useState(); + + const store = useStore(selector); + const { websiteOrdering } = store; + const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]); + const ordered = useMemo(() => orderByWebsiteMap(data, websiteOrdering), [data, websiteOrdering]); + const Buttons = row => ( {row.share_id && ( @@ -157,6 +167,21 @@ export default function WebsiteSettings() { setShowUrl(null); } + function handleWebsiteDrag({ destination, source }) { + if (!destination || destination.index === source.index) return; + + const orderedWebsites = [...ordered]; + const [removed] = orderedWebsites.splice(source.index, 1); + orderedWebsites.splice(destination.index, 0, removed); + + setDashboard({ + ...store, + websiteOrdering: orderedWebsites + .map((i, k) => ({ [i.website_uuid]: k })) + .reduce((a, b) => ({ ...a, ...b })), + }); + } + if (!data) { return null; } @@ -186,7 +211,14 @@ export default function WebsiteSettings() { - +
{editWebsite && ( }> diff --git a/lib/format.js b/lib/format.js index a336c1c4..26f02f3b 100644 --- a/lib/format.js +++ b/lib/format.js @@ -78,3 +78,14 @@ export function stringToColor(str) { } return color; } + +export function orderByWebsiteMap(websites, orderMap) { + if (!websites) return []; + + let ordered = [...websites]; + for (let website of websites) { + ordered[orderMap[website.website_uuid]] = website; + } + + return ordered; +} diff --git a/store/app.js b/store/app.js index 65295fd0..0b2abd47 100644 --- a/store/app.js +++ b/store/app.js @@ -12,6 +12,7 @@ import { getItem, setItem } from 'lib/web'; export const defaultDashboardConfig = { showCharts: true, limit: DEFAULT_WEBSITE_LIMIT, + websiteOrdering: {}, }; const initialState = { From 5bd83b8127e12bcb2e6e4ce93cb7a52d46a5ce9a Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Sat, 23 Jul 2022 23:02:47 -0700 Subject: [PATCH 03/34] Change dashboard websites to use ordered list --- components/pages/WebsiteList.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/components/pages/WebsiteList.js b/components/pages/WebsiteList.js index e2cba6b2..9e3c641a 100644 --- a/components/pages/WebsiteList.js +++ b/components/pages/WebsiteList.js @@ -5,8 +5,21 @@ import Page from 'components/layout/Page'; import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import Arrow from 'assets/arrow-right.svg'; import styles from './WebsiteList.module.css'; +import { orderByWebsiteMap } from 'lib/format'; +import { useMemo } from 'react'; +import useStore from 'store/app'; + +const selector = state => state.dashboard; export default function WebsiteList({ websites, showCharts, limit }) { + const store = useStore(selector); + const { websiteOrdering } = store; + + const ordered = useMemo( + () => orderByWebsiteMap(websites, websiteOrdering), + [websites, websiteOrdering], + ); + if (websites.length === 0) { return ( @@ -28,7 +41,7 @@ export default function WebsiteList({ websites, showCharts, limit }) { return (
- {websites.map(({ website_id, name, domain }, index) => + {ordered.map(({ website_id, name, domain }, index) => index < limit ? (
Date: Sat, 23 Jul 2022 23:04:07 -0700 Subject: [PATCH 04/34] Fix bug where toggle charts would reset ordering --- components/settings/DashboardSettingsButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/settings/DashboardSettingsButton.js b/components/settings/DashboardSettingsButton.js index 8c04aa00..8bdaf311 100644 --- a/components/settings/DashboardSettingsButton.js +++ b/components/settings/DashboardSettingsButton.js @@ -2,7 +2,7 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; import MenuButton from 'components/common/MenuButton'; import Gear from 'assets/gear.svg'; -import useStore, { setDashboard, defaultDashboardConfig } from 'store/app'; +import useStore, { setDashboard } from 'store/app'; const selector = state => state.dashboard; @@ -18,7 +18,7 @@ export default function DashboardSettingsButton() { function handleSelect(value) { if (value === 'charts') { - setDashboard({ ...defaultDashboardConfig, showCharts: !settings.showCharts }); + setDashboard({ ...settings, showCharts: !settings.showCharts }); } //setDashboard(value); } From 76bdb6b1d61db7e03ada042f69b8678cce41270b Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Sat, 23 Jul 2022 23:07:53 -0700 Subject: [PATCH 05/34] Add reset order button to website settings --- components/settings/WebsiteSettings.js | 18 +++++++++++++++--- components/settings/WebsiteSettings.module.css | 6 ++++++ lang/en-US.json | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/components/settings/WebsiteSettings.js b/components/settings/WebsiteSettings.js index 4c39cf0c..46f953d3 100644 --- a/components/settings/WebsiteSettings.js +++ b/components/settings/WebsiteSettings.js @@ -182,6 +182,13 @@ export default function WebsiteSettings() { }); } + function resetWebsiteOrder() { + setDashboard({ + ...store, + websiteOrdering: {}, + }); + } + if (!data) { return null; } @@ -207,9 +214,14 @@ export default function WebsiteSettings() {
- +
+ + +
Date: Sun, 24 Jul 2022 23:07:56 -0700 Subject: [PATCH 06/34] Restore table component and website settings page --- components/common/Table.js | 39 ++-------------- components/settings/WebsiteSettings.js | 44 +++---------------- .../settings/WebsiteSettings.module.css | 6 --- 3 files changed, 9 insertions(+), 80 deletions(-) diff --git a/components/common/Table.js b/components/common/Table.js index acd4f160..77a07712 100644 --- a/components/common/Table.js +++ b/components/common/Table.js @@ -1,4 +1,3 @@ -import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; @@ -14,9 +13,6 @@ function Table({ rowKey, showHeader = true, children, - isDraggable = false, - dragId, - onDragEnd, }) { if (empty && rows.length === 0) { return empty; @@ -40,37 +36,10 @@ function Table({
{rows.length === 0 && } {!children && - (isDraggable ? ( - - - {provided => ( -
- {rows.map((row, index) => { - const id = rowKey ? rowKey(row) : index; - return ( - - {provided => ( -
- -
- )} -
- ); - })} -
- )} -
-
- ) : ( - rows.map((row, index) => { - const id = rowKey ? rowKey(row) : index; - return ; - }) - ))} + rows.map((row, index) => { + const id = rowKey ? rowKey(row) : index; + return ; + })} {children}
diff --git a/components/settings/WebsiteSettings.js b/components/settings/WebsiteSettings.js index 46f953d3..f5cd31e6 100644 --- a/components/settings/WebsiteSettings.js +++ b/components/settings/WebsiteSettings.js @@ -25,7 +25,7 @@ import LinkIcon from 'assets/link.svg'; import useFetch from 'hooks/useFetch'; import useUser from 'hooks/useUser'; import { orderByWebsiteMap } from 'lib/format'; -import useStore, { setDashboard } from 'store/app'; +import useStore from 'store/app'; import styles from './WebsiteSettings.module.css'; const selector = state => state.dashboard; @@ -167,28 +167,6 @@ export default function WebsiteSettings() { setShowUrl(null); } - function handleWebsiteDrag({ destination, source }) { - if (!destination || destination.index === source.index) return; - - const orderedWebsites = [...ordered]; - const [removed] = orderedWebsites.splice(source.index, 1); - orderedWebsites.splice(destination.index, 0, removed); - - setDashboard({ - ...store, - websiteOrdering: orderedWebsites - .map((i, k) => ({ [i.website_uuid]: k })) - .reduce((a, b) => ({ ...a, ...b })), - }); - } - - function resetWebsiteOrder() { - setDashboard({ - ...store, - websiteOrdering: {}, - }); - } - if (!data) { return null; } @@ -214,23 +192,11 @@ export default function WebsiteSettings() {
-
- - -
+ -
+
{editWebsite && ( }> diff --git a/components/settings/WebsiteSettings.module.css b/components/settings/WebsiteSettings.module.css index dbb04eb8..a69d4101 100644 --- a/components/settings/WebsiteSettings.module.css +++ b/components/settings/WebsiteSettings.module.css @@ -11,9 +11,3 @@ .detailLink { width: 100%; } - -.headerButtons { - display: flex; - justify-content: flex-end; - gap: 10px; -} From 137ff97c072b3d6db199f51581d75dc14722526b Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Sun, 24 Jul 2022 23:25:04 -0700 Subject: [PATCH 07/34] Move reordering of websites onto dashboard --- components/pages/WebsiteList.js | 86 +++++++++++++++---- components/pages/WebsiteList.module.css | 9 ++ .../settings/DashboardSettingsButton.js | 30 +++++++ .../DashboardSettingsButton.module.css | 5 ++ lang/en-US.json | 2 + store/app.js | 1 + 6 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 components/settings/DashboardSettingsButton.module.css diff --git a/components/pages/WebsiteList.js b/components/pages/WebsiteList.js index 9e3c641a..07cc4107 100644 --- a/components/pages/WebsiteList.js +++ b/components/pages/WebsiteList.js @@ -1,3 +1,4 @@ +import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import { FormattedMessage } from 'react-intl'; import Link from 'components/common/Link'; import WebsiteChart from 'components/metrics/WebsiteChart'; @@ -7,19 +8,36 @@ import Arrow from 'assets/arrow-right.svg'; import styles from './WebsiteList.module.css'; import { orderByWebsiteMap } from 'lib/format'; import { useMemo } from 'react'; -import useStore from 'store/app'; +import useStore, { setDashboard } from 'store/app'; const selector = state => state.dashboard; export default function WebsiteList({ websites, showCharts, limit }) { const store = useStore(selector); - const { websiteOrdering } = store; + const { websiteOrdering, changeOrderMode } = store; const ordered = useMemo( () => orderByWebsiteMap(websites, websiteOrdering), [websites, websiteOrdering], ); + const dragId = 'dashboard-website-ordering'; + + function handleWebsiteDrag({ destination, source }) { + if (!destination || destination.index === source.index) return; + + const orderedWebsites = [...ordered]; + const [removed] = orderedWebsites.splice(source.index, 1); + orderedWebsites.splice(destination.index, 0, removed); + + setDashboard({ + ...store, + websiteOrdering: orderedWebsites + .map((i, k) => ({ [i.website_uuid]: k })) + .reduce((a, b) => ({ ...a, ...b })), + }); + } + if (websites.length === 0) { return ( @@ -40,19 +58,57 @@ export default function WebsiteList({ websites, showCharts, limit }) { } return ( -
- {ordered.map(({ website_id, name, domain }, index) => - index < limit ? ( -
- -
- ) : null, +
+ {changeOrderMode ? ( + + + {provided => ( +
+ {ordered.map(({ website_id, name, domain }, index) => + index < limit ? ( +
+ + {provided => ( +
+ +
+ )} +
+
+ ) : null, + )} +
+ )} +
+
+ ) : ( + ordered.map(({ website_id, name, domain }, index) => + index < limit ? ( +
+ +
+ ) : null, + ) )}
); diff --git a/components/pages/WebsiteList.module.css b/components/pages/WebsiteList.module.css index fc6a94c2..9b5e6968 100644 --- a/components/pages/WebsiteList.module.css +++ b/components/pages/WebsiteList.module.css @@ -9,3 +9,12 @@ border-bottom: 0; margin-bottom: 20px; } + +.websiteDragActive { + opacity: 0.6; + cursor: grab; +} + +.websiteDragActive:active { + cursor: grabbing; +} diff --git a/components/settings/DashboardSettingsButton.js b/components/settings/DashboardSettingsButton.js index 8bdaf311..1c4b98c7 100644 --- a/components/settings/DashboardSettingsButton.js +++ b/components/settings/DashboardSettingsButton.js @@ -3,6 +3,9 @@ import { FormattedMessage } from 'react-intl'; import MenuButton from 'components/common/MenuButton'; import Gear from 'assets/gear.svg'; import useStore, { setDashboard } from 'store/app'; +import Button from 'components/common/Button'; +import Check from 'assets/check.svg'; +import styles from './DashboardSettingsButton.module.css'; const selector = state => state.dashboard; @@ -14,14 +17,41 @@ export default function DashboardSettingsButton() { label: , value: 'charts', }, + { + label: , + value: 'order', + }, ]; function handleSelect(value) { if (value === 'charts') { setDashboard({ ...settings, showCharts: !settings.showCharts }); } + if (value === 'order') { + setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode }); + } //setDashboard(value); } + function handleExitChangeOrderMode() { + setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode }); + } + + function resetWebsiteOrder() { + setDashboard({ ...settings, websiteOrdering: {} }); + } + + if (settings.changeOrderMode) + return ( +
+ + +
+ ); + return } options={menuOptions} onSelect={handleSelect} hideLabel />; } diff --git a/components/settings/DashboardSettingsButton.module.css b/components/settings/DashboardSettingsButton.module.css new file mode 100644 index 00000000..6e0d19c2 --- /dev/null +++ b/components/settings/DashboardSettingsButton.module.css @@ -0,0 +1,5 @@ +.buttonGroup { + display: flex; + place-items: center; + gap: 10px; +} diff --git a/lang/en-US.json b/lang/en-US.json index 69a68980..0687e553 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -10,6 +10,7 @@ "label.back": "Back", "label.cancel": "Cancel", "label.change-password": "Change password", + "label.change-order": "Change order", "label.confirm-password": "Confirm password", "label.copy-to-clipboard": "Copy to clipboard", "label.current-password": "Current password", @@ -22,6 +23,7 @@ "label.delete-website": "Delete website", "label.dismiss": "Dismiss", "label.domain": "Domain", + "label.done": "Done", "label.edit": "Edit", "label.edit-account": "Edit account", "label.edit-website": "Edit website", diff --git a/store/app.js b/store/app.js index 0b2abd47..fd84b975 100644 --- a/store/app.js +++ b/store/app.js @@ -13,6 +13,7 @@ export const defaultDashboardConfig = { showCharts: true, limit: DEFAULT_WEBSITE_LIMIT, websiteOrdering: {}, + changeOrderMode: false, }; const initialState = { From 79ae5b0571b3ad8906a0b6245a0a2d1d52e11560 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Mon, 25 Jul 2022 23:52:59 -0700 Subject: [PATCH 08/34] add migration prisma 4 --- .../migrations/02_prisma_4_upgrade/migration.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 db/postgresql/migrations/02_prisma_4_upgrade/migration.sql diff --git a/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql b/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql new file mode 100644 index 00000000..d52a495f --- /dev/null +++ b/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql @@ -0,0 +1,11 @@ +-- RenameIndex +ALTER INDEX "account.username_unique" RENAME TO "account_username_key"; + +-- RenameIndex +ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key"; + +-- RenameIndex +ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_idx"; + +-- RenameIndex +ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; From 689091212ebb447c7d97067bb3a243bb0da6f8d1 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Tue, 26 Jul 2022 00:33:52 -0700 Subject: [PATCH 09/34] update migration --- .../02_prisma_4_upgrade/migration.sql | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql b/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql index d52a495f..b5a5767e 100644 --- a/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql +++ b/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql @@ -1,3 +1,39 @@ +-- DropForeignKey +ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey"; + +-- DropForeignKey +ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey"; + +-- DropForeignKey +ALTER TABLE "pageview" DROP CONSTRAINT "pageview_session_id_fkey"; + +-- DropForeignKey +ALTER TABLE "pageview" DROP CONSTRAINT "pageview_website_id_fkey"; + +-- DropForeignKey +ALTER TABLE "session" DROP CONSTRAINT "session_website_id_fkey"; + +-- DropForeignKey +ALTER TABLE "website" DROP CONSTRAINT "website_user_id_fkey"; + +-- AddForeignKey +ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "pageview" ADD CONSTRAINT "pageview_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "pageview" ADD CONSTRAINT "pageview_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "session" ADD CONSTRAINT "session_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "website" ADD CONSTRAINT "website_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "account"("user_id") ON DELETE NO ACTION ON UPDATE NO ACTION; + -- RenameIndex ALTER INDEX "account.username_unique" RENAME TO "account_username_key"; From c8302390c52d0822ae8aa6da7ef9809a5affb24f Mon Sep 17 00:00:00 2001 From: biqette Date: Tue, 26 Jul 2022 18:49:38 +0200 Subject: [PATCH 10/34] Fix utm request --- queries/analytics/pageview/getPageviewParams.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/queries/analytics/pageview/getPageviewParams.js b/queries/analytics/pageview/getPageviewParams.js index fd25c77e..6b505529 100644 --- a/queries/analytics/pageview/getPageviewParams.js +++ b/queries/analytics/pageview/getPageviewParams.js @@ -9,7 +9,7 @@ export async function getPageviewParams(...args) { } function relationalQuery(param, website_id, start_at, end_at, column, table, filters = {}) { - const params = [param, website_id, start_at, end_at]; + const params = [param, param, website_id, start_at, end_at]; const { pageviewQuery, sessionQuery, eventQuery, joinSession } = parseFilters( table, column, @@ -26,12 +26,13 @@ function relationalQuery(param, website_id, start_at, end_at, column, table, fil return rawQuery( `select * from ( select - url, ${splitFn}(${splitFn}(url, concat($1, '='), 2), '&', 1) param + url, + IF( LENGTH(url) - LENGTH(${splitFn}(url, concat($1, '='), -1)) > 1, ${splitFn}(${splitFn}(url, concat($2, '='), -1), '&', 1), null ) param from pageview ${joinSession} where - ${table}.website_id=$2 and ${table}.created_at between $3 and $4 + ${table}.website_id=$3 and ${table}.created_at between $4 and $5 ${pageviewQuery} ${joinSession && sessionQuery} ${eventQuery} From c7476aa59e25a94cb2f67d7c418bedb41d1dc787 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Tue, 26 Jul 2022 11:01:43 -0700 Subject: [PATCH 11/34] add deploy if missing migrations. add logic to hand 01_init --- scripts/check-db.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/check-db.js b/scripts/check-db.js index 6b4b0749..190aeef6 100644 --- a/scripts/check-db.js +++ b/scripts/check-db.js @@ -59,12 +59,17 @@ async function checkMigrations() { const output = await run('prisma', ['migrate', 'status']); const missingMigrations = output.includes('have not yet been applied'); + const missingInitialMigration = output.includes('01_init'); const notManaged = output.includes('The current database is not managed'); if (notManaged || missingMigrations) { console.log('Running update...'); - console.log(execSync('prisma migrate resolve --applied "01_init"').toString()); + if (missingInitialMigration) { + console.log(execSync('prisma migrate resolve --applied "01_init"').toString()); + } + + console.log(execSync('prisma migrate deploy').toString()); } success('Database is up to date.'); From b415892b7db7b900f50314b40242c4e3f4df6244 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Wed, 27 Jul 2022 12:03:12 -0700 Subject: [PATCH 12/34] restart migration. refresh schema --- .../02_prisma_4_upgrade/migration.sql | 47 ------------------- db/postgresql/schema.prisma | 26 +++++----- 2 files changed, 13 insertions(+), 60 deletions(-) delete mode 100644 db/postgresql/migrations/02_prisma_4_upgrade/migration.sql diff --git a/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql b/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql deleted file mode 100644 index b5a5767e..00000000 --- a/db/postgresql/migrations/02_prisma_4_upgrade/migration.sql +++ /dev/null @@ -1,47 +0,0 @@ --- DropForeignKey -ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey"; - --- DropForeignKey -ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey"; - --- DropForeignKey -ALTER TABLE "pageview" DROP CONSTRAINT "pageview_session_id_fkey"; - --- DropForeignKey -ALTER TABLE "pageview" DROP CONSTRAINT "pageview_website_id_fkey"; - --- DropForeignKey -ALTER TABLE "session" DROP CONSTRAINT "session_website_id_fkey"; - --- DropForeignKey -ALTER TABLE "website" DROP CONSTRAINT "website_user_id_fkey"; - --- AddForeignKey -ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE NO ACTION; - --- AddForeignKey -ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; - --- AddForeignKey -ALTER TABLE "pageview" ADD CONSTRAINT "pageview_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE NO ACTION; - --- AddForeignKey -ALTER TABLE "pageview" ADD CONSTRAINT "pageview_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; - --- AddForeignKey -ALTER TABLE "session" ADD CONSTRAINT "session_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE NO ACTION; - --- AddForeignKey -ALTER TABLE "website" ADD CONSTRAINT "website_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "account"("user_id") ON DELETE NO ACTION ON UPDATE NO ACTION; - --- RenameIndex -ALTER INDEX "account.username_unique" RENAME TO "account_username_key"; - --- RenameIndex -ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key"; - --- RenameIndex -ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_idx"; - --- RenameIndex -ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index 6e974de8..e425475f 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -9,7 +9,7 @@ datasource db { model account { user_id Int @id @default(autoincrement()) - username String @unique @db.VarChar(255) + username String @unique(map: "account.username_unique") @db.VarChar(255) password String @db.VarChar(60) is_admin Boolean @default(false) created_at DateTime? @default(now()) @db.Timestamptz(6) @@ -25,8 +25,8 @@ model event { url String @db.VarChar(500) event_type String @db.VarChar(50) event_value String @db.VarChar(50) - session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction) - website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction) + session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade) + website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) @@index([created_at]) @@index([session_id]) @@ -40,8 +40,8 @@ model pageview { created_at DateTime? @default(now()) @db.Timestamptz(6) url String @db.VarChar(500) referrer String? @db.VarChar(500) - session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction) - website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction) + session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade) + website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) @@index([created_at]) @@index([session_id]) @@ -52,17 +52,17 @@ model pageview { model session { session_id Int @id @default(autoincrement()) - session_uuid String @unique @db.Uuid + session_uuid String @unique(map: "session.session_uuid_unique") @db.Uuid website_id Int created_at DateTime? @default(now()) @db.Timestamptz(6) hostname String? @db.VarChar(100) browser String? @db.VarChar(20) os String? @db.VarChar(20) + device String? @db.VarChar(20) screen String? @db.VarChar(11) language String? @db.VarChar(35) country String? @db.Char(2) - device String? @db.VarChar(20) - website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction) + website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) event event[] pageview pageview[] @@ -72,13 +72,13 @@ model session { model website { website_id Int @id @default(autoincrement()) - website_uuid String @unique @db.Uuid - name String @db.VarChar(100) - created_at DateTime? @default(now()) @db.Timestamptz(6) + website_uuid String @unique(map: "website.website_uuid_unique") @db.Uuid user_id Int + name String @db.VarChar(100) domain String? @db.VarChar(500) - share_id String? @unique(map: "website_share_id_idx") @db.VarChar(64) - account account @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction) + share_id String? @unique(map: "website.share_id_unique") @db.VarChar(64) + created_at DateTime? @default(now()) @db.Timestamptz(6) + account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade) event event[] pageview pageview[] session session[] From 6fbd566b290e0fd4e312c22787fce392bfb6fdf2 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Wed, 27 Jul 2022 17:13:53 -0700 Subject: [PATCH 13/34] add prisma migration --- .../02_add_event_data/migration.sql | 47 +++++++++++++++++++ db/postgresql/schema.prisma | 33 ++++++++----- 2 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 db/postgresql/migrations/02_add_event_data/migration.sql diff --git a/db/postgresql/migrations/02_add_event_data/migration.sql b/db/postgresql/migrations/02_add_event_data/migration.sql new file mode 100644 index 00000000..c4d9862d --- /dev/null +++ b/db/postgresql/migrations/02_add_event_data/migration.sql @@ -0,0 +1,47 @@ +-- AlterTable +ALTER TABLE "event" ADD COLUMN "event_name" VARCHAR(50); + +-- CreateTable +CREATE TABLE "event_data" ( + "event_data_id" SERIAL NOT NULL, + "event_id" INTEGER NOT NULL, + "event_data" JSONB NOT NULL, + + CONSTRAINT "event_data_pkey" PRIMARY KEY ("event_data_id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "event_data_event_id_key" ON "event_data"("event_id"); + +-- AddForeignKey +ALTER TABLE "event_data" ADD CONSTRAINT "event_data_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "event"("event_id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- RenameIndex +ALTER INDEX "account.username_unique" RENAME TO "account_username_key"; + +-- RenameIndex +ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key"; + +-- RenameIndex +ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_key"; + +-- RenameIndex +ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; + +/* + Warnings: + + - You are about to drop the column `event_type` on the `event` table. All the data in the column will be lost. + - You are about to drop the column `event_value` on the `event` table. All the data in the column will be lost. + +*/ +-- Populate event_name +update event +set "event_name" = event.event_value || '-' || event.event_type; + +--Set event_name not null +ALTER TABLE "event" ALTER COLUMN "event_name" SET NOT NULL; + +-- Drop old columns +ALTER TABLE "event" DROP COLUMN "event_type", +DROP COLUMN "event_value"; diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index e425475f..2f2cc8de 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -9,7 +9,7 @@ datasource db { model account { user_id Int @id @default(autoincrement()) - username String @unique(map: "account.username_unique") @db.VarChar(255) + username String @unique @db.VarChar(255) password String @db.VarChar(60) is_admin Boolean @default(false) created_at DateTime? @default(now()) @db.Timestamptz(6) @@ -18,21 +18,28 @@ model account { } model event { - event_id Int @id @default(autoincrement()) - website_id Int - session_id Int - created_at DateTime? @default(now()) @db.Timestamptz(6) - url String @db.VarChar(500) - event_type String @db.VarChar(50) - event_value String @db.VarChar(50) - session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade) - website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) + event_id Int @id @default(autoincrement()) + website_id Int + session_id Int + created_at DateTime? @default(now()) @db.Timestamptz(6) + url String @db.VarChar(500) + event_name String @db.VarChar(50) + session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade) + website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) + eventData event_data? @@index([created_at]) @@index([session_id]) @@index([website_id]) } +model event_data { + id Int @id @default(autoincrement()) @map("event_data_id") + eventId Int @unique @map("event_id") + eventData Json @map("event_data") + event event @relation(fields: [eventId], references: [event_id]) +} + model pageview { view_id Int @id @default(autoincrement()) website_id Int @@ -52,7 +59,7 @@ model pageview { model session { session_id Int @id @default(autoincrement()) - session_uuid String @unique(map: "session.session_uuid_unique") @db.Uuid + session_uuid String @unique @db.Uuid website_id Int created_at DateTime? @default(now()) @db.Timestamptz(6) hostname String? @db.VarChar(100) @@ -72,11 +79,11 @@ model session { model website { website_id Int @id @default(autoincrement()) - website_uuid String @unique(map: "website.website_uuid_unique") @db.Uuid + website_uuid String @unique @db.Uuid user_id Int name String @db.VarChar(100) domain String? @db.VarChar(500) - share_id String? @unique(map: "website.share_id_unique") @db.VarChar(64) + share_id String? @unique @db.VarChar(64) created_at DateTime? @default(now()) @db.Timestamptz(6) account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade) event event[] From 3e2c098c05c6cd6f337ec8b256a76c147e62946c Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Wed, 27 Jul 2022 23:16:16 -0700 Subject: [PATCH 14/34] create mysql migration --- .../02_add_event_data/migration.sql | 49 +++++++++++++++++++ .../02_add_event_data/migration.sql | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 db/mysql/migrations/02_add_event_data/migration.sql diff --git a/db/mysql/migrations/02_add_event_data/migration.sql b/db/mysql/migrations/02_add_event_data/migration.sql new file mode 100644 index 00000000..80ff8e26 --- /dev/null +++ b/db/mysql/migrations/02_add_event_data/migration.sql @@ -0,0 +1,49 @@ +-- AlterTable +ALTER TABLE `event` ADD COLUMN `event_name` VARCHAR(50) NULL; + +-- CreateTable +CREATE TABLE `event_data` ( + `event_data_id` INTEGER NOT NULL AUTO_INCREMENT, + `event_id` INTEGER UNSIGNED NOT NULL, + `event_data` JSON NOT NULL, + + UNIQUE INDEX `event_data_event_id_key`(`event_id`), + PRIMARY KEY (`event_data_id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `event_data` ADD CONSTRAINT `event_data_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `event`(`event_id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- RenameIndex +ALTER TABLE `account` RENAME INDEX `username` TO `account_username_key`; + +-- RenameIndex +ALTER TABLE `session` RENAME INDEX `session_uuid` TO `session_session_uuid_key`; + +-- RenameIndex +ALTER TABLE `website` RENAME INDEX `share_id` TO `website_share_id_key`; + +-- RenameIndex +ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`; + + +/* + Warnings: + + - You are about to drop the column `event_type` on the `event` table. All the data in the column will be lost. + - You are about to drop the column `event_value` on the `event` table. All the data in the column will be lost. + +*/ +-- Populate event_name +update `event` +set event_name = concat(event_value, "-", event_type) +where 1 = 1; + +-- Set event_name not null +ALTER TABLE `event` +MODIFY `event_name` VARCHAR(50) NOT NULL; + +-- Drop old columns +ALTER TABLE `event` +DROP COLUMN `event_type`, +DROP COLUMN `event_value`; \ No newline at end of file diff --git a/db/postgresql/migrations/02_add_event_data/migration.sql b/db/postgresql/migrations/02_add_event_data/migration.sql index c4d9862d..703bca38 100644 --- a/db/postgresql/migrations/02_add_event_data/migration.sql +++ b/db/postgresql/migrations/02_add_event_data/migration.sql @@ -39,7 +39,7 @@ ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; update event set "event_name" = event.event_value || '-' || event.event_type; ---Set event_name not null +-- Set event_name not null ALTER TABLE "event" ALTER COLUMN "event_name" SET NOT NULL; -- Drop old columns From 934d569bb23a27203f47c8f6f511fbd2e33b8ca8 Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Thu, 28 Jul 2022 16:59:44 -0700 Subject: [PATCH 15/34] Rename "change order" to "edit dashboard" --- components/settings/DashboardSettingsButton.js | 2 +- lang/en-US.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/settings/DashboardSettingsButton.js b/components/settings/DashboardSettingsButton.js index 1c4b98c7..5425bca5 100644 --- a/components/settings/DashboardSettingsButton.js +++ b/components/settings/DashboardSettingsButton.js @@ -18,7 +18,7 @@ export default function DashboardSettingsButton() { value: 'charts', }, { - label: , + label: , value: 'order', }, ]; diff --git a/lang/en-US.json b/lang/en-US.json index 0687e553..f35005ad 100644 --- a/lang/en-US.json +++ b/lang/en-US.json @@ -10,7 +10,6 @@ "label.back": "Back", "label.cancel": "Cancel", "label.change-password": "Change password", - "label.change-order": "Change order", "label.confirm-password": "Confirm password", "label.copy-to-clipboard": "Copy to clipboard", "label.current-password": "Current password", @@ -26,6 +25,7 @@ "label.done": "Done", "label.edit": "Edit", "label.edit-account": "Edit account", + "label.edit-dashboard": "Edit dashboard", "label.edit-website": "Edit website", "label.enable-share-url": "Enable share URL", "label.invalid": "Invalid", From 88d1c194549b90654f1aa988ddee11794a776b6b Mon Sep 17 00:00:00 2001 From: Chris Walsh Date: Thu, 28 Jul 2022 17:16:03 -0700 Subject: [PATCH 16/34] Fix graphical bugs when dragging --- components/pages/WebsiteList.js | 53 +++++++++++++++++---------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/components/pages/WebsiteList.js b/components/pages/WebsiteList.js index 07cc4107..12e2f7d9 100644 --- a/components/pages/WebsiteList.js +++ b/components/pages/WebsiteList.js @@ -62,33 +62,36 @@ export default function WebsiteList({ websites, showCharts, limit }) { {changeOrderMode ? ( - {provided => ( -
+ {(provided, snapshot) => ( +
{ordered.map(({ website_id, name, domain }, index) => index < limit ? ( -
- - {provided => ( -
- -
- )} -
-
+ + {provided => ( +
+ +
+ )} +
) : null, )}
From 8f934c7e6cbf7a12af22fc2654febc256933e90b Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Fri, 29 Jul 2022 22:30:09 -0700 Subject: [PATCH 17/34] checkpoint --- components/metrics/EventsChart.js | 6 +-- components/metrics/RealtimeLog.js | 7 ++-- components/pages/TestConsole.js | 3 +- .../02_add_event_data/migration.sql | 3 +- db/mysql/schema.prisma | 33 +++++++++------- .../02_add_event_data/migration.sql | 4 +- lib/db.js | 8 ++-- pages/api/collect.js | 4 +- pages/api/website/[id]/events.js | 4 +- pages/api/website/[id]/metrics.js | 3 +- queries/analytics/event/getEventMetrics.js | 2 +- queries/analytics/event/getEvents.js | 2 +- queries/analytics/event/saveEvent.js | 39 ++++++++++--------- tracker/index.js | 18 ++++----- 14 files changed, 73 insertions(+), 63 deletions(-) diff --git a/components/metrics/EventsChart.js b/components/metrics/EventsChart.js index ef9a142f..50dc940d 100644 --- a/components/metrics/EventsChart.js +++ b/components/metrics/EventsChart.js @@ -12,7 +12,7 @@ export default function EventsChart({ websiteId, className, token }) { const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId); const [timezone] = useTimezone(); const { - query: { url, eventType }, + query: { url, eventName }, } = usePageQuery(); const { data, loading } = useFetch( @@ -24,11 +24,11 @@ export default function EventsChart({ websiteId, className, token }) { unit, tz: timezone, url, - event_type: eventType, + event_name: eventName, token, }, }, - [modified, eventType], + [modified, eventName], ); const datasets = useMemo(() => { diff --git a/components/metrics/RealtimeLog.js b/components/metrics/RealtimeLog.js index f4e87834..278f64a4 100644 --- a/components/metrics/RealtimeLog.js +++ b/components/metrics/RealtimeLog.js @@ -92,8 +92,7 @@ export default function RealtimeLog({ data, websites, websiteId }) { } function getDetail({ - event_type, - event_value, + event_name, view_id, session_id, url, @@ -103,10 +102,10 @@ export default function RealtimeLog({ data, websites, websiteId }) { device, website_id, }) { - if (event_type) { + if (event_name) { return (
- {event_type} {event_value} + {event_name}
); } diff --git a/components/pages/TestConsole.js b/components/pages/TestConsole.js index 9f4d7ca2..8a2afa88 100644 --- a/components/pages/TestConsole.js +++ b/components/pages/TestConsole.js @@ -37,7 +37,8 @@ export default function TestConsole() { function handleClick() { window.umami('event (default)'); window.umami.trackView('/page-view', 'https://www.google.com'); - window.umami.trackEvent('event (custom)', 'custom-type'); + window.umami.trackEvent('event (custom)', null, 'custom-type'); + window.umami.trackEvent('event (custom)', { test: 'test-data' }, 'custom-data-type'); } return ( diff --git a/db/mysql/migrations/02_add_event_data/migration.sql b/db/mysql/migrations/02_add_event_data/migration.sql index 80ff8e26..d8bfa0b0 100644 --- a/db/mysql/migrations/02_add_event_data/migration.sql +++ b/db/mysql/migrations/02_add_event_data/migration.sql @@ -36,8 +36,7 @@ ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`; */ -- Populate event_name update `event` -set event_name = concat(event_value, "-", event_type) -where 1 = 1; +set event_name = event_value; -- Set event_name not null ALTER TABLE `event` diff --git a/db/mysql/schema.prisma b/db/mysql/schema.prisma index e2985142..3d920c53 100644 --- a/db/mysql/schema.prisma +++ b/db/mysql/schema.prisma @@ -9,7 +9,7 @@ datasource db { model account { user_id Int @id @default(autoincrement()) @db.UnsignedInt - username String @unique(map: "username") @db.VarChar(255) + username String @unique() @db.VarChar(255) password String @db.VarChar(60) is_admin Boolean @default(false) created_at DateTime? @default(now()) @db.Timestamp(0) @@ -18,21 +18,28 @@ model account { } model event { - event_id Int @id @default(autoincrement()) @db.UnsignedInt - website_id Int @db.UnsignedInt - session_id Int @db.UnsignedInt - created_at DateTime? @default(now()) @db.Timestamp(0) - url String @db.VarChar(500) - event_type String @db.VarChar(50) - event_value String @db.VarChar(50) - session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2") - website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1") + event_id Int @id @default(autoincrement()) @db.UnsignedInt + website_id Int @db.UnsignedInt + session_id Int @db.UnsignedInt + created_at DateTime? @default(now()) @db.Timestamp(0) + url String @db.VarChar(500) + event_name String @db.VarChar(50) + session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2") + website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1") + event_data event_data? @@index([created_at]) @@index([session_id]) @@index([website_id]) } +model event_data { + id Int @id @default(autoincrement()) @map("event_data_id") + eventId Int @unique @map("event_id") @db.UnsignedInt + eventData Json @map("event_data") + event event @relation(fields: [eventId], references: [event_id]) +} + model pageview { view_id Int @id @default(autoincrement()) @db.UnsignedInt website_id Int @db.UnsignedInt @@ -52,7 +59,7 @@ model pageview { model session { session_id Int @id @default(autoincrement()) @db.UnsignedInt - session_uuid String @unique(map: "session_uuid") @db.VarChar(36) + session_uuid String @unique() @db.VarChar(36) website_id Int @db.UnsignedInt created_at DateTime? @default(now()) @db.Timestamp(0) hostname String? @db.VarChar(100) @@ -72,11 +79,11 @@ model session { model website { website_id Int @id @default(autoincrement()) @db.UnsignedInt - website_uuid String @unique(map: "website_uuid") @db.VarChar(36) + website_uuid String @unique() @db.VarChar(36) user_id Int @db.UnsignedInt name String @db.VarChar(100) domain String? @db.VarChar(500) - share_id String? @unique(map: "share_id") @db.VarChar(64) + share_id String? @unique() @db.VarChar(64) created_at DateTime? @default(now()) @db.Timestamp(0) account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1") event event[] diff --git a/db/postgresql/migrations/02_add_event_data/migration.sql b/db/postgresql/migrations/02_add_event_data/migration.sql index 703bca38..0574abbd 100644 --- a/db/postgresql/migrations/02_add_event_data/migration.sql +++ b/db/postgresql/migrations/02_add_event_data/migration.sql @@ -1,5 +1,5 @@ -- AlterTable -ALTER TABLE "event" ADD COLUMN "event_name" VARCHAR(50); +ALTER TABLE event RENAME TO event_old; -- CreateTable CREATE TABLE "event_data" ( @@ -37,7 +37,7 @@ ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; */ -- Populate event_name update event -set "event_name" = event.event_value || '-' || event.event_type; +set "event_name" = event.event_value; -- Set event_name not null ALTER TABLE "event" ALTER COLUMN "event_name" SET NOT NULL; diff --git a/lib/db.js b/lib/db.js index cb9237bb..1a5f8b2c 100644 --- a/lib/db.js +++ b/lib/db.js @@ -182,7 +182,7 @@ export function getFilterQuery(table, column, filters = {}, params = []) { } break; - case 'event_type': + case 'event_name': if (table === 'event') { arr.push(`and ${table}.${key}=$${params.length + 1}`); params.push(decodeURIComponent(filter)); @@ -212,17 +212,17 @@ export function getFilterQuery(table, column, filters = {}, params = []) { } export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') { - const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters; + const { domain, url, event_url, referrer, os, browser, device, country, event_name } = filters; const pageviewFilters = { domain, url, referrer }; const sessionFilters = { os, browser, device, country }; - const eventFilters = { url: event_url, event_type }; + const eventFilters = { url: event_url, event_name }; return { pageviewFilters, sessionFilters, eventFilters, - event: { event_type }, + event: { event_name }, joinSession: os || browser || device || country ? `inner join session on ${table}.${sessionKey} = session.${sessionKey}` diff --git a/pages/api/collect.js b/pages/api/collect.js index 4ff533b9..92451016 100644 --- a/pages/api/collect.js +++ b/pages/api/collect.js @@ -65,7 +65,7 @@ export default async (req, res) => { const { type, payload } = getJsonBody(req); - let { url, referrer, event_type, event_value } = payload; + let { url, referrer, event_name, event_data } = payload; if (process.env.REMOVE_TRAILING_SLASH) { url = removeTrailingSlash(url); @@ -74,7 +74,7 @@ export default async (req, res) => { if (type === 'pageview') { await savePageView(website_id, { session_id, session_uuid, url, referrer }); } else if (type === 'event') { - await saveEvent(website_id, { session_id, session_uuid, url, event_type, event_value }); + await saveEvent(website_id, { session_id, session_uuid, url, event_name, event_data }); } else { return badRequest(res); } diff --git a/pages/api/website/[id]/events.js b/pages/api/website/[id]/events.js index e4fc1e2a..ab4ddc7d 100644 --- a/pages/api/website/[id]/events.js +++ b/pages/api/website/[id]/events.js @@ -14,7 +14,7 @@ export default async (req, res) => { return unauthorized(res); } - const { id, start_at, end_at, unit, tz, url, event_type } = req.query; + const { id, start_at, end_at, unit, tz, url, event_name } = req.query; if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) { return badRequest(res); @@ -26,7 +26,7 @@ export default async (req, res) => { const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, { url, - event_type, + event_name, }); return ok(res, events); diff --git a/pages/api/website/[id]/metrics.js b/pages/api/website/[id]/metrics.js index b12566fd..50f568d3 100644 --- a/pages/api/website/[id]/metrics.js +++ b/pages/api/website/[id]/metrics.js @@ -22,7 +22,8 @@ function getTable(type) { function getColumn(type) { if (type === 'event') { - return `concat(event_type, '\t', event_value)`; + //return `concat(event_type, '\t', event_value)`; + return `event_name`; } return type; } diff --git a/queries/analytics/event/getEventMetrics.js b/queries/analytics/event/getEventMetrics.js index 73f7e469..1dbe10f4 100644 --- a/queries/analytics/event/getEventMetrics.js +++ b/queries/analytics/event/getEventMetrics.js @@ -29,7 +29,7 @@ async function relationalQuery( return rawQuery( ` select - event_value x, + event_name x, ${getDateQuery('created_at', unit, timezone)} t, count(*) y from event diff --git a/queries/analytics/event/getEvents.js b/queries/analytics/event/getEvents.js index fc5c0aeb..7969877a 100644 --- a/queries/analytics/event/getEvents.js +++ b/queries/analytics/event/getEvents.js @@ -40,7 +40,7 @@ function clickhouseQuery(websites, start_at) { session_id, created_at, url, - event_type + event_name from event where website_id in (${websites.join[',']} and created_at >= ${getDateFormatClickhouse(start_at)}) diff --git a/queries/analytics/event/saveEvent.js b/queries/analytics/event/saveEvent.js index 41c068c3..3e71c61c 100644 --- a/queries/analytics/event/saveEvent.js +++ b/queries/analytics/event/saveEvent.js @@ -14,33 +14,36 @@ export async function saveEvent(...args) { }); } -async function relationalQuery(website_id, { session_id, url, event_type, event_value }) { +async function relationalQuery(website_id, { session_id, url, event_name, event_data }) { + const data = { + website_id, + session_id, + url: url?.substr(0, URL_LENGTH), + event_name: event_name?.substr(0, 50), + }; + + if (event_data) { + data.eventData = { + create: { + eventData: event_data, + }, + }; + } + return runQuery( prisma.event.create({ - data: { - website_id, - session_id, - url: url?.substr(0, URL_LENGTH), - event_type: event_type?.substr(0, 50), - event_value: event_value?.substr(0, 50), - }, + data, }), ); } -async function clickhouseQuery(website_id, { session_uuid, url, event_type, event_value }) { - const params = [ - website_id, - session_uuid, - url?.substr(0, URL_LENGTH), - event_type?.substr(0, 50), - event_value?.substr(0, 50), - ]; +async function clickhouseQuery(website_id, { session_uuid, url, event_name }) { + const params = [website_id, session_uuid, url?.substr(0, URL_LENGTH), event_name?.substr(0, 50)]; return rawQueryClickhouse( ` - insert into umami_dev.event (created_at, website_id, session_uuid, url, event_type, event_value) - values (${getDateFormatClickhouse(new Date())}, $1, $2, $3, $4, $5);`, + insert into umami_dev.event (created_at, website_id, session_uuid, url, event_name) + values (${getDateFormatClickhouse(new Date())}, $1, $2, $3, $4);`, params, ); } diff --git a/tracker/index.js b/tracker/index.js index f6329633..f0584288 100644 --- a/tracker/index.js +++ b/tracker/index.js @@ -97,25 +97,24 @@ import { removeTrailingSlash } from '../lib/url'; ); }; - const trackEvent = (event_value, event_type = 'custom', url = currentUrl, uuid = website) => { + const trackEvent = (event_name = 'custom', event_data, url = currentUrl, uuid = website) => { collect( 'event', assign(getPayload(), { website: uuid, url, - event_type, - event_value, + event_name, + event_data, }), ); }; /* Handle events */ - const sendEvent = (value, type) => { + const sendEvent = name => { const payload = getPayload(); - payload.event_type = type; - payload.event_value = value; + payload.event_name = name; const data = JSON.stringify({ type: 'event', @@ -138,14 +137,15 @@ import { removeTrailingSlash } from '../lib/url'; (element.getAttribute('class') || '').split(' ').forEach(className => { if (!eventClass.test(className)) return; - const [, type, value] = className.split('--'); + const [, type, name] = className.split('--'); + const listener = listeners[className] ? listeners[className] : (listeners[className] = () => { if (element.tagName === 'A') { - sendEvent(value, type); + sendEvent(name); } else { - trackEvent(value, type); + trackEvent(name); } }); From 32458b51ac5bb62764cebfe1767909995b3b1d64 Mon Sep 17 00:00:00 2001 From: max180643 Date: Sun, 31 Jul 2022 04:33:34 +0700 Subject: [PATCH 18/34] Add Thai language --- lang/th-TH.json | 117 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 lang/th-TH.json diff --git a/lang/th-TH.json b/lang/th-TH.json new file mode 100644 index 00000000..2f9999d8 --- /dev/null +++ b/lang/th-TH.json @@ -0,0 +1,117 @@ +{ + "label.accounts": "บัญชี", + "label.add-account": "เพิ่มบัญชี", + "label.add-website": "เพิ่มเว็บไซต์", + "label.administrator": "ผู้ดูแลระบบ", + "label.all": "ทั้งหมด", + "label.all-events": "เหตุการณ์ทั้งหมด", + "label.all-time": "ทุกช่วงเวลา", + "label.all-websites": "เว็บไซต์ทั้งหมด", + "label.back": "ย้อนกลับ", + "label.cancel": "ยกเลิก", + "label.change-password": "เปลี่ยนรหัสผ่าน", + "label.confirm-password": "ยืนยันรหัสผ่าน", + "label.copy-to-clipboard": "คัดลอกไปยังคลิปบอร์ด", + "label.current-password": "รหัสผ่านปัจจุบัน", + "label.custom-range": "กำหนดช่วงเวลา", + "label.dashboard": "แดชบอร์ด", + "label.date-range": "ตั้งแต่วันที่", + "label.default-date-range": "ช่วงเวลา", + "label.delete": "ลบ", + "label.delete-account": "ลบบัญชี", + "label.delete-website": "ลบเว็บไซต์", + "label.dismiss": "ยกเลิก", + "label.domain": "โดเมน", + "label.edit": "แก้ไข", + "label.edit-account": "แก้ไขบัญชี", + "label.edit-website": "แก้ไขเว็บไซต์", + "label.enable-share-url": "เปิดใช้งานการแชร์ลิงก์", + "label.invalid": "ไม่ถูกต้อง", + "label.invalid-domain": "โดเมนไม่ถูกต้อง", + "label.language": "ภาษา", + "label.last-days": "{x} วันที่ผ่านมา", + "label.last-hours": "{x} ชั่วโมงที่ผ่านมา", + "label.logged-in-as": "เข้าสู่ระบบโดย {username}", + "label.login": "เข้าสู่ระบบ", + "label.logout": "ออกจากระบบ", + "label.more": "เพิ่มเติม", + "label.name": "ชื่อ", + "label.new-password": "รหัสผ่านใหม่", + "label.none": "ไม่ได้กำหนด", + "label.owner": "เจ้าของ", + "label.password": "รหัสผ่าน", + "label.passwords-dont-match": "รหัสผ่านไม่ตรงกัน", + "label.profile": "โปรไฟล์", + "label.realtime": "เรียลไทม์", + "label.realtime-logs": "Log แบบเรียลไทม์", + "label.refresh": "รีเฟรช", + "label.required": "ต้องการ", + "label.reset": "รีเซต", + "label.reset-website": "รีเซตข้อมูลสถิติ", + "label.save": "บันทึก", + "label.settings": "ตั้งค่า", + "label.share-url": "แชร์ลิงก์", + "label.single-day": "วันที่", + "label.theme": "ธีม", + "label.this-month": "เดือนปัจจุบัน", + "label.this-week": "สัปดาห์ปัจจุบัน", + "label.this-year": "ปีปัจจุบัน", + "label.timezone": "เขตเวลา", + "label.today": "วันนี้", + "label.tracking-code": "โค้ดสำหรับใช้ติดตาม", + "label.unknown": "ไม่รู้จัก", + "label.username": "ชื่อผู้ใช้", + "label.view-details": "แสดงรายละเอียด", + "label.websites": "เว็บไซต์", + "message.active-users": "มีผู้ใช้งาน {x} {x, plural, one {คนในขณะนี้} other {คนในขณะนี้}}", + "message.confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?", + "message.confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?", + "message.copied": "คัดลอกแล้ว!", + "message.delete-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.", + "message.failure": "เกิดข้อผิดพลาด.", + "message.get-share-url": "รับลิงก์สำหรับแชร์", + "message.get-tracking-code": "รับโค้ดสำหรับใช้ติดตาม", + "message.go-to-settings": "ไปที่การตั้งค่า", + "message.incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.", + "message.log.visitor": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}", + "message.new-version-available": "umami เวอร์ชันใหม่ ({version}) มาแล้ว!", + "message.no-data-available": "ไม่มีข้อมูล.", + "message.no-websites-configured": "คุณยังไม่ได้ตั้งค่าเว็บไซต์ใด ๆ ไว้.", + "message.page-not-found": "ไม่พบหน้านี้.", + "message.powered-by": "ขับเคลื่อนโดย {name}", + "message.reset-warning": "สถิติทั้งหมดสำหรับเว็บไซต์นี้จะถูกลบออก แต่โค้ดสำหรับใช้ติดตามของคุณจะยังคงอยู่เหมือนเดิม.", + "message.save-success": "บันทึกข้อมูลเรียบร้อย.", + "message.share-url": "นี่คือลิงก์ที่แชร์แบบสาธารณะสำหรับ {target}.", + "message.toggle-charts": "เปิด/ปิดแผนภูมิ", + "message.track-stats": "หากต้องการติดตามสถิติสำหรับ {target} ให้วางโค้ดต่อไปนี้ในส่วน {head} ของเว็บไซต์ของคุณ.", + "message.type-delete": "พิมพ์ข้อความ {delete} ในช่องด้านล่างเพื่อยืนยัน.", + "message.type-reset": "พิมพ์ข้อความ {reset} ในช่องด้านล่างเพื่อยืนยัน.", + "metrics.actions": "การกระทำ", + "metrics.average-visit-time": "ระยะเวลาเข้าชมเฉลี่ย", + "metrics.bounce-rate": "อัตราตีกลับ", + "metrics.browsers": "เบราว์เซอร์", + "metrics.countries": "ประเทศ", + "metrics.device.desktop": "เดสก์ท็อป", + "metrics.device.laptop": "แล็ปท็อป", + "metrics.device.mobile": "โทรศัพท์มือถือ", + "metrics.device.tablet": "แท็บเล็ต", + "metrics.devices": "อุปกรณ์", + "metrics.events": "เหตุการณ์", + "metrics.filter.combined": "ข้อมูลรวม", + "metrics.filter.raw": "ข้อมูลดิบ", + "metrics.languages": "ภาษา", + "metrics.operating-systems": "ระบบปฏิบัติการ", + "metrics.page-views": "การเข้าชม", + "metrics.pages": "หน้าเพจ", + "metrics.referrers": "แหล่งที่มา", + "metrics.screens": "ขนาดหน้าจอ", + "metrics.unique-visitors": "ผู้เข้าชม", + "metrics.utm": "UTM", + "metrics.utm_campaign": "UTM Campaign", + "metrics.utm_content": "UTM Content", + "metrics.utm_medium": "UTM Medium", + "metrics.utm_source": "UTM Source", + "metrics.utm_term": "UTM Term", + "metrics.views": "การเข้าชม", + "metrics.visitors": "ผู้เข้าชม" +} From adb069babc48e194562b02b1a9f8e5f9d3c59534 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Sun, 31 Jul 2022 23:29:47 -0700 Subject: [PATCH 19/34] Added content security policy. --- middleware.js | 10 +--------- next.config.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/middleware.js b/middleware.js index cf957b74..fb7fe7f5 100644 --- a/middleware.js +++ b/middleware.js @@ -33,14 +33,6 @@ function customScriptName(req) { } } -function forceSSL(req, res) { - if (process.env.FORCE_SSL && req.nextUrl.protocol === 'http:') { - res.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains'); - } - - return res; -} - export default function middleware(req) { const fns = [customCollectEndpoint, customScriptName]; @@ -51,5 +43,5 @@ export default function middleware(req) { } } - return forceSSL(req, NextResponse.next()); + return NextResponse.next(); } diff --git a/next.config.js b/next.config.js index 10624451..b5e4b806 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,37 @@ require('dotenv').config(); const pkg = require('./package.json'); +const contentSecurityPolicy = ` + default-src 'self'; + img-src *; + script-src 'self' 'unsafe-eval'; + style-src 'self' 'unsafe-inline'; + connect-src 'self' api.umami.is; + frame-ancestors 'self'; +`; + +const headers = [ + { + key: 'X-DNS-Prefetch-Control', + value: 'on', + }, + { + key: 'X-Frame-Options', + value: 'SAMEORIGIN', + }, + { + key: 'Content-Security-Policy', + value: contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(), + }, +]; + +if (process.env.FORCE_SSL) { + headers.push({ + key: 'Strict-Transport-Security', + value: 'max-age=63072000; includeSubDomains; preload', + }); +} + module.exports = { env: { currentVersion: pkg.version, @@ -24,6 +55,10 @@ module.exports = { }, async headers() { return [ + { + source: '/:path*', + headers, + }, { source: `/(.*\\.js)`, headers: [ From 7b0d6af14744c58e0e4241e96c7337e1225d2d7d Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Mon, 1 Aug 2022 12:22:17 -0700 Subject: [PATCH 20/34] refactor table drop --- .../02_add_event_data/migration.sql | 68 ++++++++++++------- db/mysql/schema.prisma | 8 +-- .../02_add_event_data/migration.sql | 61 +++++++++++------ db/postgresql/schema.prisma | 26 +++++-- 4 files changed, 108 insertions(+), 55 deletions(-) diff --git a/db/mysql/migrations/02_add_event_data/migration.sql b/db/mysql/migrations/02_add_event_data/migration.sql index d8bfa0b0..83392fb4 100644 --- a/db/mysql/migrations/02_add_event_data/migration.sql +++ b/db/mysql/migrations/02_add_event_data/migration.sql @@ -1,5 +1,46 @@ --- AlterTable -ALTER TABLE `event` ADD COLUMN `event_name` VARCHAR(50) NULL; +-- DropForeignKey +alter table `event` drop foreign key `event_ibfk_1`; +alter table `event` drop foreign key `event_ibfk_2`; + +drop index `event_created_at_idx` on `event`; +drop index `event_session_id_idx` on `event`; +drop index `event_website_id_idx` on `event`; + +create index `event_old_created_at_idx` on `event` (created_at); +create index `event_old_session_id_idx` on `event` (session_id); +create index `event_old_website_id_idx` on `event` (website_id); + +-- RenameTable +rename table `event` to `_event_old`; + +-- CreateTable +create table `event` +( + event_id int unsigned auto_increment + primary key, + website_id int unsigned not null, + session_id int unsigned not null, + created_at timestamp default CURRENT_TIMESTAMP null, + url varchar(500) not null, + event_name varchar(50) NOT NULL, + constraint event_ibfk_1 + foreign key (website_id) references `website` (website_id) + on delete cascade, + constraint event_ibfk_2 + foreign key (session_id) references `session` (session_id) + on delete cascade +) + collate = utf8mb4_unicode_ci; + +create index `event_created_at_idx` + on `event` (created_at); + +create index `event_session_id_idx` + on `event` (session_id); + +create index `event_website_id_idx` + on `event` (website_id); + -- CreateTable CREATE TABLE `event_data` ( @@ -24,25 +65,4 @@ ALTER TABLE `session` RENAME INDEX `session_uuid` TO `session_session_uuid_key`; ALTER TABLE `website` RENAME INDEX `share_id` TO `website_share_id_key`; -- RenameIndex -ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`; - - -/* - Warnings: - - - You are about to drop the column `event_type` on the `event` table. All the data in the column will be lost. - - You are about to drop the column `event_value` on the `event` table. All the data in the column will be lost. - -*/ --- Populate event_name -update `event` -set event_name = event_value; - --- Set event_name not null -ALTER TABLE `event` -MODIFY `event_name` VARCHAR(50) NOT NULL; - --- Drop old columns -ALTER TABLE `event` -DROP COLUMN `event_type`, -DROP COLUMN `event_value`; \ No newline at end of file +ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`; \ No newline at end of file diff --git a/db/mysql/schema.prisma b/db/mysql/schema.prisma index 3d920c53..7b7036a7 100644 --- a/db/mysql/schema.prisma +++ b/db/mysql/schema.prisma @@ -34,10 +34,10 @@ model event { } model event_data { - id Int @id @default(autoincrement()) @map("event_data_id") - eventId Int @unique @map("event_id") @db.UnsignedInt - eventData Json @map("event_data") - event event @relation(fields: [eventId], references: [event_id]) + event_data_id Int @id @default(autoincrement()) + event_id Int @unique @db.UnsignedInt + event_data Json + event event @relation(fields: [event_id], references: [event_id]) } model pageview { diff --git a/db/postgresql/migrations/02_add_event_data/migration.sql b/db/postgresql/migrations/02_add_event_data/migration.sql index 0574abbd..62587e29 100644 --- a/db/postgresql/migrations/02_add_event_data/migration.sql +++ b/db/postgresql/migrations/02_add_event_data/migration.sql @@ -1,5 +1,42 @@ --- AlterTable -ALTER TABLE event RENAME TO event_old; +-- DropForeignKey +ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey"; +ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey"; + +-- RenameIndex +ALTER INDEX "event_pkey" RENAME TO "event_old_pkey"; +ALTER INDEX "event_created_at_idx" RENAME TO "event_old_created_at_idx"; +ALTER INDEX "event_session_id_idx" RENAME TO "event_old_session_id_idx"; +ALTER INDEX "event_website_id_idx" RENAME TO "event_old_website_id_idx"; + +-- RenameTable +ALTER TABLE "event" RENAME TO "_event_old"; + +-- CreateTable +CREATE TABLE "event" ( + "event_id" SERIAL NOT NULL, + "website_id" INTEGER NOT NULL, + "session_id" INTEGER NOT NULL, + "created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP, + "url" VARCHAR(500) NOT NULL, + "event_name" VARCHAR(50) NOT NULL, + + PRIMARY KEY ("event_id") +); + +-- CreateIndex +CREATE INDEX "event_created_at_idx" ON "event"("created_at"); + +-- CreateIndex +CREATE INDEX "event_session_id_idx" ON "event"("session_id"); + +-- CreateIndex +CREATE INDEX "event_website_id_idx" ON "event"("website_id"); + +-- AddForeignKey +ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE CASCADE; -- CreateTable CREATE TABLE "event_data" ( @@ -26,22 +63,4 @@ ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key"; ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_key"; -- RenameIndex -ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; - -/* - Warnings: - - - You are about to drop the column `event_type` on the `event` table. All the data in the column will be lost. - - You are about to drop the column `event_value` on the `event` table. All the data in the column will be lost. - -*/ --- Populate event_name -update event -set "event_name" = event.event_value; - --- Set event_name not null -ALTER TABLE "event" ALTER COLUMN "event_name" SET NOT NULL; - --- Drop old columns -ALTER TABLE "event" DROP COLUMN "event_type", -DROP COLUMN "event_value"; +ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key"; \ No newline at end of file diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index 2f2cc8de..f4106877 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -33,11 +33,25 @@ model event { @@index([website_id]) } +model event_old { + event_id Int @id @default(autoincrement()) + website_id Int + session_id Int + created_at DateTime? @default(now()) @db.Timestamptz(6) + url String @db.VarChar(500) + event_type String @db.VarChar(50) + event_value String @db.VarChar(50) + + @@index([created_at]) + @@index([session_id]) + @@index([website_id]) +} + model event_data { - id Int @id @default(autoincrement()) @map("event_data_id") - eventId Int @unique @map("event_id") - eventData Json @map("event_data") - event event @relation(fields: [eventId], references: [event_id]) + id Int @id @default(autoincrement()) + event_id Int @unique + event_data Json + event event @relation(fields: [event_id], references: [event_id]) } model pageview { @@ -70,8 +84,8 @@ model session { language String? @db.VarChar(35) country String? @db.Char(2) website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) - event event[] pageview pageview[] + event event[] @@index([created_at]) @@index([website_id]) @@ -86,9 +100,9 @@ model website { share_id String? @unique @db.VarChar(64) created_at DateTime? @default(now()) @db.Timestamptz(6) account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade) - event event[] pageview pageview[] session session[] + event event[] @@index([user_id]) } From 01b517f68e92693068c25dc8b3a5d0083057e0bd Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Mon, 1 Aug 2022 13:49:56 -0700 Subject: [PATCH 21/34] remove event_old from schema --- db/postgresql/schema.prisma | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index f4106877..f466300b 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -33,20 +33,6 @@ model event { @@index([website_id]) } -model event_old { - event_id Int @id @default(autoincrement()) - website_id Int - session_id Int - created_at DateTime? @default(now()) @db.Timestamptz(6) - url String @db.VarChar(500) - event_type String @db.VarChar(50) - event_value String @db.VarChar(50) - - @@index([created_at]) - @@index([session_id]) - @@index([website_id]) -} - model event_data { id Int @id @default(autoincrement()) event_id Int @unique From ab1e49e703f996a5657c6e198b76ebe9975dd178 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 1 Aug 2022 17:14:36 -0700 Subject: [PATCH 22/34] Added Bengali and Thai languages. --- lib/lang.js | 4 + package.json | 2 +- public/intl/country/bn-BD.json | 1 + public/intl/country/th-TH.json | 1 + public/intl/language/bn-BD.json | 1 + public/intl/language/th-TH.json | 1 + public/intl/messages/bn-BD.json | 832 ++++++++++++++++++++++++++++++++ public/intl/messages/id-ID.json | 30 +- public/intl/messages/pl-PL.json | 14 +- public/intl/messages/pt-PT.json | 4 +- public/intl/messages/th-TH.json | 832 ++++++++++++++++++++++++++++++++ public/intl/messages/zh-CN.json | 12 +- public/intl/messages/zh-TW.json | 26 +- scripts/format-lang.js | 9 +- 14 files changed, 1717 insertions(+), 52 deletions(-) create mode 100644 public/intl/country/bn-BD.json create mode 100644 public/intl/country/th-TH.json create mode 100644 public/intl/language/bn-BD.json create mode 100644 public/intl/language/th-TH.json create mode 100644 public/intl/messages/bn-BD.json create mode 100644 public/intl/messages/th-TH.json diff --git a/lib/lang.js b/lib/lang.js index ea555729..dcb5cd1a 100644 --- a/lib/lang.js +++ b/lib/lang.js @@ -1,5 +1,6 @@ import { arSA, + bn, cs, sk, da, @@ -30,6 +31,7 @@ import { sl, sv, ta, + th, tr, uk, zhCN, @@ -41,6 +43,7 @@ import { export const languages = { 'ar-SA': { label: 'العربية', dateLocale: arSA, dir: 'rtl' }, + 'bn-BD': { label: 'বাংলা', dateLocale: bn }, 'zh-CN': { label: '中文', dateLocale: zhCN }, 'zh-TW': { label: '中文(繁體)', dateLocale: zhTW }, 'ca-ES': { label: 'Català', dateLocale: ca }, @@ -77,6 +80,7 @@ export const languages = { 'fi-FI': { label: 'Suomi', dateLocale: fi }, 'sv-SE': { label: 'Svenska', dateLocale: sv }, 'ta-IN': { label: 'தமிழ்', dateLocale: ta }, + 'th-TH': { label: 'ภาษาไทย', dateLocale: th }, 'tr-TR': { label: 'Türkçe', dateLocale: tr }, 'uk-UA': { label: 'українська', dateLocale: uk }, 'ur-PK': { label: 'Urdu (Pakistan)', dateLocale: uk, dir: 'rtl' }, diff --git a/package.json b/package.json index 5ddab6e7..33333b87 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "build-app": "next build", "build-tracker": "rollup -c rollup.tracker.config.js", "build-db": "npm-run-all copy-db-files build-db-client", - "build-lang": "npm-run-all format-lang compile-lang", + "build-lang": "npm-run-all format-lang compile-lang download-country-names download-language-names", "build-geo": "node scripts/build-geo.js", "build-db-schema": "prisma db pull", "build-db-client": "prisma generate", diff --git a/public/intl/country/bn-BD.json b/public/intl/country/bn-BD.json new file mode 100644 index 00000000..f7366fef --- /dev/null +++ b/public/intl/country/bn-BD.json @@ -0,0 +1 @@ +{"AT":"\u0985\u09b8\u09cd\u099f\u09cd\u09b0\u09bf\u09af\u09bc\u09be","AU":"\u0985\u09b8\u09cd\u099f\u09cd\u09b0\u09c7\u09b2\u09bf\u09af\u09bc\u09be","AO":"\u0985\u09cd\u09af\u09be\u0999\u09cd\u0997\u09cb\u09b2\u09be","AQ":"\u0985\u09cd\u09af\u09be\u09a8\u09cd\u099f\u09be\u09b0\u09cd\u0995\u099f\u09bf\u0995\u09be","AG":"\u0985\u09cd\u09af\u09be\u09a8\u09cd\u099f\u09bf\u0997\u09c1\u09af\u09bc\u09be \u0993 \u09ac\u09be\u09b0\u09ac\u09c1\u09a1\u09be","IM":"\u0986\u0987\u09b2 \u0985\u09ab \u09ae\u09cd\u09af\u09be\u09a8","IS":"\u0986\u0987\u09b8\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","AZ":"\u0986\u099c\u09be\u09b0\u09ac\u09be\u0987\u099c\u09be\u09a8","AD":"\u0986\u09a8\u09cd\u09a1\u09cb\u09b0\u09be","AF":"\u0986\u09ab\u0997\u09be\u09a8\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","AS":"\u0986\u09ae\u09c7\u09b0\u09bf\u0995\u09be\u09a8 \u09b8\u09be\u09ae\u09cb\u09af\u09bc\u09be","IE":"\u0986\u09af\u09bc\u09be\u09b0\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","AW":"\u0986\u09b0\u09c1\u09ac\u09be","AR":"\u0986\u09b0\u09cd\u099c\u09c7\u09a8\u09cd\u099f\u09bf\u09a8\u09be","AM":"\u0986\u09b0\u09cd\u09ae\u09c7\u09a8\u09bf\u09af\u09bc\u09be","DZ":"\u0986\u09b2\u099c\u09c7\u09b0\u09bf\u09af\u09bc\u09be","AL":"\u0986\u09b2\u09ac\u09c7\u09a8\u09bf\u09af\u09bc\u09be","AX":"\u0986\u09b2\u09be\u09a8\u09cd\u09a1 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","UA":"\u0987\u0989\u0995\u09cd\u09b0\u09c7\u09a8","EC":"\u0987\u0995\u09c1\u09af\u09bc\u09c7\u09a1\u09b0","IL":"\u0987\u099c\u09b0\u09be\u09af\u09bc\u09c7\u09b2","IT":"\u0987\u09a4\u09be\u09b2\u09bf","ET":"\u0987\u09a5\u09bf\u0993\u09aa\u09bf\u09af\u09bc\u09be","ID":"\u0987\u09a8\u09cd\u09a6\u09cb\u09a8\u09c7\u09b6\u09bf\u09af\u09bc\u09be","YE":"\u0987\u09af\u09bc\u09c7\u09ae\u09c7\u09a8","IQ":"\u0987\u09b0\u09be\u0995","IR":"\u0987\u09b0\u09be\u09a8","ER":"\u0987\u09b0\u09bf\u09a4\u09cd\u09b0\u09bf\u09af\u09bc\u09be","SZ":"\u0987\u09b8\u0993\u09af\u09bc\u09be\u09a4\u09bf\u09a8\u09bf","UG":"\u0989\u0997\u09be\u09a8\u09cd\u09a1\u09be","UZ":"\u0989\u099c\u09ac\u09c7\u0995\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","KP":"\u0989\u09a4\u09cd\u09a4\u09b0 \u0995\u09cb\u09b0\u09bf\u09af\u09bc\u09be","MK":"\u0989\u09a4\u09cd\u09a4\u09b0 \u09ae\u09cd\u09af\u09be\u09b8\u09c7\u09a1\u09cb\u09a8\u09bf\u09af\u09bc\u09be","MP":"\u0989\u09a4\u09cd\u09a4\u09b0\u09be\u099e\u09cd\u099a\u09b2\u09c0\u09af\u09bc \u09ae\u09be\u09b0\u09bf\u09af\u09bc\u09be\u09a8\u09be \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","UY":"\u0989\u09b0\u09c1\u0997\u09c1\u09af\u09bc\u09c7","SV":"\u098f\u09b2 \u09b8\u09be\u09b2\u09ad\u09c7\u09a6\u09b0","EE":"\u098f\u09b8\u09cd\u09a4\u09cb\u09a8\u09bf\u09af\u09bc\u09be","AI":"\u098f\u09cd\u09af\u09be\u0999\u09cd\u0997\u09c1\u0987\u09b2\u09be","OM":"\u0993\u09ae\u09be\u09a8","WF":"\u0993\u09af\u09bc\u09be\u09b2\u09bf\u09b8 \u0993 \u09ab\u09c1\u099f\u09c1\u09a8\u09be","CG":"\u0995\u0999\u09cd\u0997\u09cb - \u09ac\u09cd\u09b0\u09be\u099c\u09be\u09ad\u09bf\u09b2","CD":"\u0995\u0999\u09cd\u0997\u09cb-\u0995\u09bf\u09a8\u09b6\u09be\u09b8\u09be","KM":"\u0995\u09ae\u09cb\u09b0\u09cb\u09b8","KH":"\u0995\u09ae\u09cd\u09ac\u09cb\u09a1\u09bf\u09af\u09bc\u09be","CO":"\u0995\u09b2\u09ae\u09cd\u09ac\u09bf\u09af\u09bc\u09be","KZ":"\u0995\u09be\u099c\u09be\u0996\u09b8\u09cd\u09a4\u09be\u09a8","QA":"\u0995\u09be\u09a4\u09be\u09b0","CA":"\u0995\u09be\u09a8\u09be\u09a1\u09be","CU":"\u0995\u09bf\u0989\u09ac\u09be","KG":"\u0995\u09bf\u09b0\u0997\u09bf\u099c\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","KI":"\u0995\u09bf\u09b0\u09bf\u09ac\u09be\u09a4\u09bf","CK":"\u0995\u09c1\u0995 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","KW":"\u0995\u09c1\u09af\u09bc\u09c7\u09a4","CW":"\u0995\u09c1\u09b0\u09be\u09b8\u09be\u0993","KE":"\u0995\u09c7\u09a8\u09bf\u09af\u09bc\u09be","CV":"\u0995\u09c7\u09aa\u09ad\u09be\u09b0\u09cd\u09a6\u09c7","KY":"\u0995\u09c7\u09ae\u09cd\u09af\u09be\u09a8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","CC":"\u0995\u09cb\u0995\u09cb\u09b8 (\u0995\u09bf\u09b2\u09bf\u0982) \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","CI":"\u0995\u09cb\u09a4 \u09a6\u09bf\u09ad\u09cb\u09af\u09bc\u09be\u09b0","CR":"\u0995\u09cb\u09b8\u09cd\u099f\u09be\u09b0\u09bf\u0995\u09be","CM":"\u0995\u09cd\u09af\u09be\u09ae\u09c7\u09b0\u09c1\u09a8","BQ":"\u0995\u09cd\u09af\u09be\u09b0\u09bf\u09ac\u09bf\u09af\u09bc\u09be\u09a8 \u09a8\u09c7\u09a6\u09be\u09b0\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u09b8","CX":"\u0995\u09cd\u09b0\u09bf\u09b8\u09ae\u09be\u09b8 \u09a6\u09cd\u09ac\u09c0\u09aa","HR":"\u0995\u09cd\u09b0\u09cb\u09af\u09bc\u09c7\u09b6\u09bf\u09af\u09bc\u09be","GM":"\u0997\u09be\u09ae\u09cd\u09ac\u09bf\u09af\u09bc\u09be","GN":"\u0997\u09bf\u09a8\u09bf","GW":"\u0997\u09bf\u09a8\u09bf-\u09ac\u09bf\u09b8\u09be\u0989","GY":"\u0997\u09bf\u09af\u09bc\u09be\u09a8\u09be","GT":"\u0997\u09c1\u09af\u09bc\u09be\u09a4\u09c7\u09ae\u09be\u09b2\u09be","GP":"\u0997\u09c1\u09af\u09bc\u09be\u09a6\u09c7\u09b2\u09cc\u09aa","GU":"\u0997\u09c1\u09af\u09bc\u09be\u09ae","GG":"\u0997\u09c1\u09af\u09bc\u09be\u09b0\u09cd\u09a8\u09b8\u09bf","GA":"\u0997\u09cd\u09af\u09be\u09ac\u09a8","GL":"\u0997\u09cd\u09b0\u09c0\u09a8\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","GR":"\u0997\u09cd\u09b0\u09c0\u09b8","GD":"\u0997\u09cd\u09b0\u09c7\u09a8\u09be\u09a1\u09be","GH":"\u0998\u09be\u09a8\u09be","TD":"\u099a\u09be\u09a6","CL":"\u099a\u09bf\u09b2\u09bf","CN":"\u099a\u09c0\u09a8","CZ":"\u099a\u09c7\u099a\u09bf\u09af\u09bc\u09be","GE":"\u099c\u09b0\u09cd\u099c\u09bf\u09af\u09bc\u09be","JO":"\u099c\u09b0\u09cd\u09a1\u09a8","JP":"\u099c\u09be\u09aa\u09be\u09a8","JM":"\u099c\u09be\u09ae\u09be\u0987\u0995\u09be","ZM":"\u099c\u09be\u09ae\u09cd\u09ac\u09bf\u09af\u09bc\u09be","DE":"\u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8\u09bf","JE":"\u099c\u09be\u09b0\u09cd\u09b8\u09bf","DJ":"\u099c\u09bf\u09ac\u09c1\u09a4\u09bf","GI":"\u099c\u09bf\u09ac\u09cd\u09b0\u09be\u09b2\u09cd\u099f\u09be\u09b0","ZW":"\u099c\u09bf\u09ae\u09cd\u09ac\u09be\u09ac\u09cb\u09af\u09bc\u09c7","TV":"\u099f\u09c1\u09ad\u09be\u09b2\u09c1","TK":"\u099f\u09cb\u0995\u09c7\u09b2\u09be\u0989","TG":"\u099f\u09cb\u0997\u09cb","TO":"\u099f\u09cb\u0999\u09cd\u0997\u09be","DK":"\u09a1\u09c7\u09a8\u09ae\u09be\u09b0\u09cd\u0995","DM":"\u09a1\u09cb\u09ae\u09bf\u09a8\u09bf\u0995\u09be","DO":"\u09a1\u09cb\u09ae\u09c7\u09a8\u09bf\u0995\u09be\u09a8 \u09aa\u09cd\u09b0\u099c\u09be\u09a4\u09a8\u09cd\u09a4\u09cd\u09b0","TW":"\u09a4\u09be\u0987\u0993\u09af\u09bc\u09be\u09a8","TJ":"\u09a4\u09be\u099c\u09bf\u0995\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","TZ":"\u09a4\u09be\u099e\u09cd\u099c\u09be\u09a8\u09bf\u09af\u09bc\u09be","TN":"\u09a4\u09bf\u0989\u09a8\u09bf\u09b8\u09bf\u09af\u09bc\u09be","TL":"\u09a4\u09bf\u09ae\u09c1\u09b0-\u09b2\u09c7\u09b8\u09cd\u09a4\u09c7","TR":"\u09a4\u09c1\u09b0\u09b8\u09cd\u0995","TM":"\u09a4\u09c1\u09b0\u09cd\u0995\u09ae\u09c7\u09a8\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","TC":"\u09a4\u09c1\u09b0\u09cd\u0995\u09b8 \u0993 \u0995\u09be\u0987\u0995\u09cb\u09b8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","TT":"\u09a4\u09cd\u09b0\u09bf\u09a8\u09bf\u09a8\u09be\u09a6 \u0993 \u099f\u09cb\u09ac\u09cd\u09af\u09be\u0997\u09cb","TH":"\u09a5\u09be\u0987\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","ZA":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u0986\u09ab\u09cd\u09b0\u09bf\u0995\u09be","KR":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u0995\u09cb\u09b0\u09bf\u09af\u09bc\u09be","GS":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u099c\u09b0\u09cd\u099c\u09bf\u09af\u09bc\u09be \u0993 \u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u09b8\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u0989\u0987\u099a \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","SS":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u09b8\u09c1\u09a6\u09be\u09a8","NO":"\u09a8\u09b0\u0993\u09af\u09bc\u09c7","NF":"\u09a8\u09b0\u09ab\u09cb\u0995 \u09a6\u09cd\u09ac\u09c0\u09aa","NE":"\u09a8\u09be\u0987\u099c\u09be\u09b0","NG":"\u09a8\u09be\u0987\u099c\u09c7\u09b0\u09bf\u09af\u09bc\u09be","NR":"\u09a8\u09be\u0989\u09b0\u09c1","NA":"\u09a8\u09be\u09ae\u09bf\u09ac\u09bf\u09af\u09bc\u09be","NC":"\u09a8\u09bf\u0989 \u0995\u09cd\u09af\u09be\u09b2\u09c7\u09a1\u09cb\u09a8\u09bf\u09af\u09bc\u09be","NZ":"\u09a8\u09bf\u0989\u099c\u09bf\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","NU":"\u09a8\u09bf\u0989\u09af\u09bc\u09c7","NI":"\u09a8\u09bf\u0995\u09be\u09b0\u09be\u0997\u09c1\u09af\u09bc\u09be","GQ":"\u09a8\u09bf\u09b0\u0995\u09cd\u09b7\u09c0\u09af\u09bc \u0997\u09bf\u09a8\u09bf","NL":"\u09a8\u09c7\u09a6\u09be\u09b0\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u09b8","NP":"\u09a8\u09c7\u09aa\u09be\u09b2","PT":"\u09aa\u09b0\u09cd\u09a4\u09c1\u0997\u09be\u09b2","EH":"\u09aa\u09b6\u09cd\u099a\u09bf\u09ae \u09b8\u09be\u09b9\u09be\u09b0\u09be","PK":"\u09aa\u09be\u0995\u09bf\u09b8\u09cd\u09a4\u09be\u09a8","PA":"\u09aa\u09be\u09a8\u09be\u09ae\u09be","PG":"\u09aa\u09be\u09aa\u09c1\u09af\u09bc\u09be \u09a8\u09bf\u0989 \u0997\u09bf\u09a8\u09bf","PW":"\u09aa\u09be\u09b2\u09be\u0989","PN":"\u09aa\u09bf\u099f\u0995\u09c7\u09af\u09bc\u09be\u09b0\u09cd\u09a8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","PR":"\u09aa\u09c1\u09af\u09bc\u09c7\u09b0\u09cd\u09a4\u09cb \u09b0\u09bf\u0995\u09cb","PE":"\u09aa\u09c7\u09b0\u09c1","PL":"\u09aa\u09cb\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","PY":"\u09aa\u09cd\u09af\u09be\u09b0\u09be\u0997\u09c1\u09af\u09bc\u09c7","PS":"\u09aa\u09cd\u09af\u09be\u09b2\u09c7\u09b8\u09cd\u099f\u09be\u0987\u09a8\u09c7\u09b0 \u0985\u099e\u09cd\u099a\u09b2\u09b8\u09ae\u09c2\u09b9","FK":"\u09ab\u0995\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","GF":"\u09ab\u09b0\u09be\u09b8\u09c0 \u0997\u09be\u09af\u09bc\u09be\u09a8\u09be","TF":"\u09ab\u09b0\u09be\u09b8\u09c0 \u09a6\u0995\u09cd\u09b7\u09bf\u09a3\u09be\u099e\u09cd\u099a\u09b2","PF":"\u09ab\u09b0\u09be\u09b8\u09c0 \u09aa\u09b2\u09bf\u09a8\u09c7\u09b6\u09bf\u09af\u09bc\u09be","FJ":"\u09ab\u09bf\u099c\u09bf","FI":"\u09ab\u09bf\u09a8\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","PH":"\u09ab\u09bf\u09b2\u09bf\u09aa\u09be\u0987\u09a8","FO":"\u09ab\u09cd\u09af\u09be\u09b0\u0993 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","FR":"\u09ab\u09cd\u09b0\u09be\u09a8\u09cd\u09b8","BW":"\u09ac\u09a4\u09b8\u09cb\u09af\u09bc\u09be\u09a8\u09be","BO":"\u09ac\u09b2\u09bf\u09ad\u09bf\u09af\u09bc\u09be","BA":"\u09ac\u09b8\u09a8\u09bf\u09af\u09bc\u09be \u0993 \u09b9\u09be\u09b0\u09cd\u099c\u09c7\u0997\u09cb\u09ad\u09bf\u09a8\u09be","BD":"\u09ac\u09be\u0982\u09b2\u09be\u09a6\u09c7\u09b6","BB":"\u09ac\u09be\u09b0\u09ac\u09be\u09a6\u09cb\u09b8","BM":"\u09ac\u09be\u09b0\u09ae\u09c1\u09a1\u09be","BH":"\u09ac\u09be\u09b9\u09b0\u09be\u0987\u09a8","BS":"\u09ac\u09be\u09b9\u09be\u09ae\u09be \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","BF":"\u09ac\u09c1\u09b0\u0995\u09bf\u09a8\u09be \u09ab\u09be\u09b8\u09cb","BI":"\u09ac\u09c1\u09b0\u09c1\u09a8\u09cd\u09a1\u09bf","BG":"\u09ac\u09c1\u09b2\u0997\u09c7\u09b0\u09bf\u09af\u09bc\u09be","BJ":"\u09ac\u09c7\u09a8\u09bf\u09a8","BE":"\u09ac\u09c7\u09b2\u099c\u09bf\u09af\u09bc\u09be\u09ae","BY":"\u09ac\u09c7\u09b2\u09be\u09b0\u09c1\u09b6","BZ":"\u09ac\u09c7\u09b2\u09bf\u099c","BV":"\u09ac\u09cb\u09ad\u09c7\u099f \u09a6\u09cd\u09ac\u09c0\u09aa","BR":"\u09ac\u09cd\u09b0\u09be\u099c\u09bf\u09b2","IO":"\u09ac\u09cd\u09b0\u09bf\u099f\u09bf\u09b6 \u09ad\u09be\u09b0\u09a4 \u09ae\u09b9\u09be\u09b8\u09be\u0997\u09b0\u09c0\u09af\u09bc \u0985\u099e\u09cd\u099a\u09b2","VG":"\u09ac\u09cd\u09b0\u09bf\u099f\u09bf\u09b6 \u09ad\u09be\u09b0\u09cd\u099c\u09bf\u09a8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","BN":"\u09ac\u09cd\u09b0\u09c1\u09a8\u09c7\u0987","VU":"\u09ad\u09be\u09a8\u09c1\u09af\u09bc\u09be\u099f\u09c1","IN":"\u09ad\u09be\u09b0\u09a4","VN":"\u09ad\u09bf\u09af\u09bc\u09c7\u09a4\u09a8\u09be\u09ae","BT":"\u09ad\u09c1\u099f\u09be\u09a8","VE":"\u09ad\u09c7\u09a8\u09c7\u099c\u09c1\u09af\u09bc\u09c7\u09b2\u09be","VA":"\u09ad\u09cd\u09af\u09be\u099f\u09bf\u0995\u09be\u09a8 \u09b8\u09bf\u099f\u09bf","MN":"\u09ae\u0999\u09cd\u0997\u09cb\u09b2\u09bf\u09af\u09bc\u09be","CF":"\u09ae\u09a7\u09cd\u09af \u0986\u09ab\u09cd\u09b0\u09bf\u0995\u09be\u09b0 \u09aa\u09cd\u09b0\u099c\u09be\u09a4\u09a8\u09cd\u09a4\u09cd\u09b0","MS":"\u09ae\u09a8\u09cd\u099f\u09b8\u09c7\u09b0\u09be\u099f","ME":"\u09ae\u09a8\u09cd\u099f\u09bf\u09a8\u09bf\u0997\u09cd\u09b0\u09cb","MR":"\u09ae\u09b0\u09bf\u09a4\u09be\u09a8\u09bf\u09af\u09bc\u09be","MU":"\u09ae\u09b0\u09bf\u09b6\u09be\u09b8","MD":"\u09ae\u09b2\u09a1\u09cb\u09ad\u09be","FM":"\u09ae\u09be\u0987\u0995\u09cd\u09b0\u09cb\u09a8\u09c7\u09b6\u09bf\u09af\u09bc\u09be","MG":"\u09ae\u09be\u09a6\u09be\u0997\u09be\u09b8\u09cd\u0995\u09be\u09b0","MM":"\u09ae\u09be\u09af\u09bc\u09be\u09a8\u09ae\u09be\u09b0 (\u09ac\u09be\u09b0\u09cd\u09ae\u09be)","YT":"\u09ae\u09be\u09af\u09bc\u09cb\u09a4\u09cd\u09a4\u09c7","US":"\u09ae\u09be\u09b0\u09cd\u0995\u09bf\u09a8 \u09af\u09c1\u0995\u09cd\u09a4\u09b0\u09be\u09b7\u09cd\u099f\u09cd\u09b0","VI":"\u09ae\u09be\u09b0\u09cd\u0995\u09bf\u09a8 \u09af\u09c1\u0995\u09cd\u09a4\u09b0\u09be\u09b7\u09cd\u099f\u09cd\u09b0\u09c7\u09b0 \u09ad\u09be\u09b0\u09cd\u099c\u09bf\u09a8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","MQ":"\u09ae\u09be\u09b0\u09cd\u099f\u09bf\u09a8\u09bf\u0995","MH":"\u09ae\u09be\u09b0\u09cd\u09b6\u09be\u09b2 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","MV":"\u09ae\u09be\u09b2\u09a6\u09cd\u09ac\u09c0\u09aa","MY":"\u09ae\u09be\u09b2\u09af\u09bc\u09c7\u09b6\u09bf\u09af\u09bc\u09be","MW":"\u09ae\u09be\u09b2\u09be\u0989\u0987","ML":"\u09ae\u09be\u09b2\u09bf","MT":"\u09ae\u09be\u09b2\u09cd\u099f\u09be","EG":"\u09ae\u09bf\u09b6\u09b0","MX":"\u09ae\u09c7\u0995\u09cd\u09b8\u09bf\u0995\u09cb","MZ":"\u09ae\u09cb\u099c\u09be\u09ae\u09cd\u09ac\u09bf\u0995","MC":"\u09ae\u09cb\u09a8\u09be\u0995\u09cb","MA":"\u09ae\u09cb\u09b0\u0995\u09cd\u0995\u09cb","MO":"\u09ae\u09cd\u09af\u09be\u0995\u09be\u0993 \u098f\u09b8\u098f\u0986\u09b0 \u099a\u09c0\u09a8\u09be","GB":"\u09af\u09c1\u0995\u09cd\u09a4\u09b0\u09be\u099c\u09cd\u09af","UM":"\u09af\u09c1\u0995\u09cd\u09a4\u09b0\u09be\u09b7\u09cd\u099f\u09cd\u09b0\u09c7\u09b0 \u09aa\u09be\u09b0\u09cd\u09b6\u09cd\u09ac\u09ac\u09b0\u09cd\u09a4\u09c0 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","RU":"\u09b0\u09be\u09b6\u09bf\u09af\u09bc\u09be","RE":"\u09b0\u09bf\u0987\u0989\u09a8\u09bf\u09af\u09bc\u09a8","RW":"\u09b0\u09c1\u09af\u09bc\u09be\u09a8\u09cd\u09a1\u09be","RO":"\u09b0\u09cb\u09ae\u09be\u09a8\u09bf\u09af\u09bc\u09be","LR":"\u09b2\u09be\u0987\u09ac\u09c7\u09b0\u09bf\u09af\u09bc\u09be","LA":"\u09b2\u09be\u0993\u09b8","LU":"\u09b2\u09be\u0995\u09cd\u09b8\u09c7\u09ae\u09ac\u09be\u09b0\u09cd\u0997","LV":"\u09b2\u09be\u09a4\u09cd\u09ad\u09bf\u09af\u09bc\u09be","LI":"\u09b2\u09bf\u099a\u09c7\u09a8\u09b8\u09cd\u099f\u09c7\u0987\u09a8","LT":"\u09b2\u09bf\u09a5\u09c1\u09af\u09bc\u09be\u09a8\u09bf\u09af\u09bc\u09be","LY":"\u09b2\u09bf\u09ac\u09bf\u09af\u09bc\u09be","LB":"\u09b2\u09c7\u09ac\u09be\u09a8\u09a8","LS":"\u09b2\u09c7\u09b8\u09cb\u09a5\u09cb","LK":"\u09b6\u09cd\u09b0\u09c0\u09b2\u0999\u09cd\u0995\u09be","AE":"\u09b8\u0982\u09af\u09c1\u0995\u09cd\u09a4 \u0986\u09b0\u09ac \u0986\u09ae\u09bf\u09b0\u09be\u09a4","SB":"\u09b8\u09b2\u09cb\u09ae\u09a8 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c","CY":"\u09b8\u09be\u0987\u09aa\u09cd\u09b0\u09be\u09b8","ST":"\u09b8\u09be\u0993\u099f\u09cb\u09ae\u09be \u0993 \u09aa\u09cd\u09b0\u09bf\u09a8\u09cd\u09b8\u09bf\u09aa\u09bf","SM":"\u09b8\u09be\u09a8 \u09ae\u09be\u09b0\u09bf\u09a8\u09cb","WS":"\u09b8\u09be\u09ae\u09cb\u09af\u09bc\u09be","RS":"\u09b8\u09be\u09b0\u09cd\u09ac\u09bf\u09af\u09bc\u09be","SG":"\u09b8\u09bf\u0999\u09cd\u0997\u09be\u09aa\u09c1\u09b0","SX":"\u09b8\u09bf\u09a8\u09cd\u099f \u09ae\u09be\u09b0\u09cd\u099f\u09c7\u09a8","SL":"\u09b8\u09bf\u09af\u09bc\u09c7\u09b0\u09be \u09b2\u09bf\u0993\u09a8","SY":"\u09b8\u09bf\u09b0\u09bf\u09af\u09bc\u09be","SC":"\u09b8\u09bf\u09b8\u09bf\u09b2\u09bf","CH":"\u09b8\u09c1\u0987\u099c\u09be\u09b0\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1","SE":"\u09b8\u09c1\u0987\u09a1\u09c7\u09a8","SD":"\u09b8\u09c1\u09a6\u09be\u09a8","SR":"\u09b8\u09c1\u09b0\u09bf\u09a8\u09be\u09ae","SN":"\u09b8\u09c7\u09a8\u09c7\u0997\u09be\u09b2","KN":"\u09b8\u09c7\u09a8\u09cd\u099f \u0995\u09bf\u099f\u09b8 \u0993 \u09a8\u09c7\u09ad\u09bf\u09b8","PM":"\u09b8\u09c7\u09a8\u09cd\u099f \u09aa\u09bf\u09af\u09bc\u09c7\u09b0 \u0993 \u09ae\u09bf\u0995\u09c1\u09af\u09bc\u09c7\u09b2\u09a8","BL":"\u09b8\u09c7\u09a8\u09cd\u099f \u09ac\u09be\u09b0\u09a5\u09c7\u09b2\u09bf\u09ae\u09bf","VC":"\u09b8\u09c7\u09a8\u09cd\u099f \u09ad\u09bf\u09a8\u09b8\u09c7\u09a8\u09cd\u099f \u0993 \u0997\u09cd\u09b0\u09c7\u09a8\u09be\u09a1\u09bf\u09a8\u09b8","MF":"\u09b8\u09c7\u09a8\u09cd\u099f \u09ae\u09be\u09b0\u09cd\u099f\u09bf\u09a8","LC":"\u09b8\u09c7\u09a8\u09cd\u099f \u09b2\u09c1\u09b8\u09bf\u09af\u09bc\u09be","SH":"\u09b8\u09c7\u09a8\u09cd\u099f \u09b9\u09c7\u09b2\u09c7\u09a8\u09be","SO":"\u09b8\u09cb\u09ae\u09be\u09b2\u09bf\u09af\u09bc\u09be","SA":"\u09b8\u09cc\u09a6\u09bf \u0986\u09b0\u09ac","ES":"\u09b8\u09cd\u09aa\u09c7\u09a8","SJ":"\u09b8\u09cd\u09ac\u09be\u09b2\u09ac\u09be\u09b0\u09cd\u09a1 \u0993 \u099c\u09be\u09a8 \u09ae\u09c7\u09af\u09bc\u09c7\u09a8","SK":"\u09b8\u09cd\u09b2\u09cb\u09ad\u09be\u0995\u09bf\u09af\u09bc\u09be","SI":"\u09b8\u09cd\u09b2\u09cb\u09ad\u09be\u09a8\u09bf\u09af\u09bc\u09be","HK":"\u09b9\u0982\u0995\u0982 \u098f\u09b8\u098f\u0986\u09b0 \u099a\u09c0\u09a8\u09be","HN":"\u09b9\u09a8\u09cd\u09a1\u09c1\u09b0\u09be\u09b8","HT":"\u09b9\u09be\u0987\u09a4\u09bf","HU":"\u09b9\u09be\u0999\u09cd\u0997\u09c7\u09b0\u09bf","HM":"\u09b9\u09be\u09b0\u09cd\u09a1 \u098f\u09ac\u0982 \u09ae\u09cd\u09af\u09be\u0995\u09a1\u09cb\u09a8\u09be\u09b2\u09cd\u09a1 \u09a6\u09cd\u09ac\u09c0\u09aa\u09aa\u09c1\u099e\u09cd\u099c"} \ No newline at end of file diff --git a/public/intl/country/th-TH.json b/public/intl/country/th-TH.json new file mode 100644 index 00000000..beb0b25b --- /dev/null +++ b/public/intl/country/th-TH.json @@ -0,0 +1 @@ +{"GR":"\u0e01\u0e23\u0e35\u0e0b","GL":"\u0e01\u0e23\u0e35\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c","GU":"\u0e01\u0e27\u0e21","GP":"\u0e01\u0e27\u0e32\u0e40\u0e14\u0e2d\u0e25\u0e39\u0e1b","KH":"\u0e01\u0e31\u0e21\u0e1e\u0e39\u0e0a\u0e32","GT":"\u0e01\u0e31\u0e27\u0e40\u0e15\u0e21\u0e32\u0e25\u0e32","QA":"\u0e01\u0e32\u0e15\u0e32\u0e23\u0e4c","GH":"\u0e01\u0e32\u0e19\u0e32","GA":"\u0e01\u0e32\u0e1a\u0e2d\u0e07","GY":"\u0e01\u0e32\u0e22\u0e2d\u0e32\u0e19\u0e32","GN":"\u0e01\u0e34\u0e19\u0e35","GW":"\u0e01\u0e34\u0e19\u0e35-\u0e1a\u0e34\u0e2a\u0e40\u0e0b\u0e32","GD":"\u0e40\u0e01\u0e23\u0e40\u0e19\u0e14\u0e32","KR":"\u0e40\u0e01\u0e32\u0e2b\u0e25\u0e35\u0e43\u0e15\u0e49","KP":"\u0e40\u0e01\u0e32\u0e2b\u0e25\u0e35\u0e40\u0e2b\u0e19\u0e37\u0e2d","CX":"\u0e40\u0e01\u0e32\u0e30\u0e04\u0e23\u0e34\u0e2a\u0e15\u0e4c\u0e21\u0e32\u0e2a","GS":"\u0e40\u0e01\u0e32\u0e30\u0e40\u0e0b\u0e32\u0e17\u0e4c\u0e08\u0e2d\u0e23\u0e4c\u0e40\u0e08\u0e35\u0e22\u0e41\u0e25\u0e30\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e40\u0e0b\u0e32\u0e17\u0e4c\u0e41\u0e0b\u0e19\u0e14\u0e4c\u0e27\u0e34\u0e0a","NF":"\u0e40\u0e01\u0e32\u0e30\u0e19\u0e2d\u0e23\u0e4c\u0e1f\u0e2d\u0e25\u0e4c\u0e01","BV":"\u0e40\u0e01\u0e32\u0e30\u0e1a\u0e39\u0e40\u0e27","IM":"\u0e40\u0e01\u0e32\u0e30\u0e41\u0e21\u0e19","HM":"\u0e40\u0e01\u0e32\u0e30\u0e40\u0e2e\u0e34\u0e23\u0e4c\u0e14\u0e41\u0e25\u0e30\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e41\u0e21\u0e01\u0e14\u0e2d\u0e19\u0e31\u0e25\u0e14\u0e4c","GG":"\u0e40\u0e01\u0e34\u0e23\u0e4c\u0e19\u0e0b\u0e35\u0e22\u0e4c","GM":"\u0e41\u0e01\u0e21\u0e40\u0e1a\u0e35\u0e22","CI":"\u0e42\u0e01\u0e15\u0e14\u0e34\u0e27\u0e31\u0e27\u0e23\u0e4c","MO":"\u0e40\u0e02\u0e15\u0e1b\u0e01\u0e04\u0e23\u0e2d\u0e07\u0e1e\u0e34\u0e40\u0e28\u0e29\u0e21\u0e32\u0e40\u0e01\u0e4a\u0e32\u0e41\u0e2b\u0e48\u0e07\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e23\u0e31\u0e10\u0e1b\u0e23\u0e30\u0e0a\u0e32\u0e0a\u0e19\u0e08\u0e35\u0e19","HK":"\u0e40\u0e02\u0e15\u0e1b\u0e01\u0e04\u0e23\u0e2d\u0e07\u0e1e\u0e34\u0e40\u0e28\u0e29\u0e2e\u0e48\u0e2d\u0e07\u0e01\u0e07\u0e41\u0e2b\u0e48\u0e07\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e23\u0e31\u0e10\u0e1b\u0e23\u0e30\u0e0a\u0e32\u0e0a\u0e19\u0e08\u0e35\u0e19","CD":"\u0e04\u0e2d\u0e07\u0e42\u0e01 - \u0e01\u0e34\u0e19\u0e0a\u0e32\u0e0b\u0e32","CG":"\u0e04\u0e2d\u0e07\u0e42\u0e01 - \u0e1a\u0e23\u0e32\u0e0b\u0e0b\u0e32\u0e27\u0e34\u0e25","KM":"\u0e04\u0e2d\u0e42\u0e21\u0e42\u0e23\u0e2a","CR":"\u0e04\u0e2d\u0e2a\u0e15\u0e32\u0e23\u0e34\u0e01\u0e32","KZ":"\u0e04\u0e32\u0e0b\u0e31\u0e04\u0e2a\u0e16\u0e32\u0e19","KI":"\u0e04\u0e34\u0e23\u0e34\u0e1a\u0e32\u0e2a","CU":"\u0e04\u0e34\u0e27\u0e1a\u0e32","KG":"\u0e04\u0e35\u0e23\u0e4c\u0e01\u0e35\u0e0b\u0e2a\u0e16\u0e32\u0e19","CW":"\u0e04\u0e39\u0e23\u0e32\u0e40\u0e0b\u0e32","KW":"\u0e04\u0e39\u0e40\u0e27\u0e15","KE":"\u0e40\u0e04\u0e19\u0e22\u0e32","CV":"\u0e40\u0e04\u0e1b\u0e40\u0e27\u0e34\u0e23\u0e4c\u0e14","CA":"\u0e41\u0e04\u0e19\u0e32\u0e14\u0e32","CM":"\u0e41\u0e04\u0e40\u0e21\u0e2d\u0e23\u0e39\u0e19","HR":"\u0e42\u0e04\u0e23\u0e40\u0e2d\u0e40\u0e0a\u0e35\u0e22","CO":"\u0e42\u0e04\u0e25\u0e2d\u0e21\u0e40\u0e1a\u0e35\u0e22","GE":"\u0e08\u0e2d\u0e23\u0e4c\u0e40\u0e08\u0e35\u0e22","JO":"\u0e08\u0e2d\u0e23\u0e4c\u0e41\u0e14\u0e19","JM":"\u0e08\u0e32\u0e40\u0e21\u0e01\u0e32","DJ":"\u0e08\u0e34\u0e1a\u0e39\u0e15\u0e35","CN":"\u0e08\u0e35\u0e19","JE":"\u0e40\u0e08\u0e2d\u0e23\u0e4c\u0e0b\u0e35\u0e22\u0e4c","TD":"\u0e0a\u0e32\u0e14","CL":"\u0e0a\u0e34\u0e25\u0e35","CZ":"\u0e40\u0e0a\u0e47\u0e01","SM":"\u0e0b\u0e32\u0e19\u0e21\u0e32\u0e23\u0e34\u0e42\u0e19","WS":"\u0e0b\u0e32\u0e21\u0e31\u0e27","SA":"\u0e0b\u0e32\u0e2d\u0e38\u0e14\u0e35\u0e2d\u0e32\u0e23\u0e30\u0e40\u0e1a\u0e35\u0e22","EH":"\u0e0b\u0e32\u0e2e\u0e32\u0e23\u0e32\u0e15\u0e30\u0e27\u0e31\u0e19\u0e15\u0e01","SX":"\u0e0b\u0e34\u0e19\u0e15\u0e4c\u0e21\u0e32\u0e23\u0e4c\u0e40\u0e17\u0e19","ZW":"\u0e0b\u0e34\u0e21\u0e1a\u0e31\u0e1a\u0e40\u0e27","SY":"\u0e0b\u0e35\u0e40\u0e23\u0e35\u0e22","SD":"\u0e0b\u0e39\u0e14\u0e32\u0e19","SS":"\u0e0b\u0e39\u0e14\u0e32\u0e19\u0e43\u0e15\u0e49","SR":"\u0e0b\u0e39\u0e23\u0e34\u0e19\u0e32\u0e40\u0e21","SC":"\u0e40\u0e0b\u0e40\u0e0a\u0e25\u0e2a\u0e4c","KN":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e04\u0e34\u0e15\u0e2a\u0e4c\u0e41\u0e25\u0e30\u0e40\u0e19\u0e27\u0e34\u0e2a","BL":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e1a\u0e32\u0e23\u0e4c\u0e40\u0e18\u0e40\u0e25\u0e21\u0e35","MF":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e21\u0e32\u0e23\u0e4c\u0e15\u0e34\u0e19","LC":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e25\u0e39\u0e40\u0e0b\u0e35\u0e22","VC":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e27\u0e34\u0e19\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e41\u0e25\u0e30\u0e40\u0e01\u0e23\u0e19\u0e32\u0e14\u0e35\u0e19\u0e2a\u0e4c","SH":"\u0e40\u0e0b\u0e19\u0e15\u0e4c\u0e40\u0e2e\u0e40\u0e25\u0e19\u0e32","SN":"\u0e40\u0e0b\u0e40\u0e19\u0e01\u0e31\u0e25","RS":"\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e40\u0e1a\u0e35\u0e22","ST":"\u0e40\u0e0b\u0e32\u0e15\u0e39\u0e40\u0e21\u0e41\u0e25\u0e30\u0e1b\u0e23\u0e34\u0e19\u0e0b\u0e34\u0e1b\u0e35","SL":"\u0e40\u0e0b\u0e35\u0e22\u0e23\u0e4c\u0e23\u0e32\u0e25\u0e35\u0e42\u0e2d\u0e19","PM":"\u0e41\u0e0b\u0e07\u0e1b\u0e35\u0e41\u0e22\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e21\u0e35\u0e40\u0e01\u0e2d\u0e25\u0e07","ZM":"\u0e41\u0e0b\u0e21\u0e40\u0e1a\u0e35\u0e22","SO":"\u0e42\u0e0b\u0e21\u0e32\u0e40\u0e25\u0e35\u0e22","CY":"\u0e44\u0e0b\u0e1b\u0e23\u0e31\u0e2a","JP":"\u0e0d\u0e35\u0e48\u0e1b\u0e38\u0e48\u0e19","PS":"\u0e14\u0e34\u0e19\u0e41\u0e14\u0e19\u0e1b\u0e32\u0e40\u0e25\u0e2a\u0e44\u0e15\u0e19\u0e4c","DK":"\u0e40\u0e14\u0e19\u0e21\u0e32\u0e23\u0e4c\u0e01","DM":"\u0e42\u0e14\u0e21\u0e34\u0e19\u0e34\u0e01\u0e32","TT":"\u0e15\u0e23\u0e34\u0e19\u0e34\u0e41\u0e14\u0e14\u0e41\u0e25\u0e30\u0e42\u0e15\u0e40\u0e1a\u0e42\u0e01","TO":"\u0e15\u0e2d\u0e07\u0e01\u0e32","TL":"\u0e15\u0e34\u0e21\u0e2d\u0e23\u0e4c-\u0e40\u0e25\u0e2a\u0e40\u0e15","TR":"\u0e15\u0e38\u0e23\u0e01\u0e35","TN":"\u0e15\u0e39\u0e19\u0e34\u0e40\u0e0b\u0e35\u0e22","TV":"\u0e15\u0e39\u0e27\u0e32\u0e25\u0e39","TM":"\u0e40\u0e15\u0e34\u0e23\u0e4c\u0e01\u0e40\u0e21\u0e19\u0e34\u0e2a\u0e16\u0e32\u0e19","TK":"\u0e42\u0e15\u0e40\u0e01\u0e40\u0e25\u0e32","TG":"\u0e42\u0e15\u0e42\u0e01","TW":"\u0e44\u0e15\u0e49\u0e2b\u0e27\u0e31\u0e19","TJ":"\u0e17\u0e32\u0e08\u0e34\u0e01\u0e34\u0e2a\u0e16\u0e32\u0e19","TZ":"\u0e41\u0e17\u0e19\u0e0b\u0e32\u0e40\u0e19\u0e35\u0e22","TH":"\u0e44\u0e17\u0e22","VA":"\u0e19\u0e04\u0e23\u0e27\u0e32\u0e15\u0e34\u0e01\u0e31\u0e19","NO":"\u0e19\u0e2d\u0e23\u0e4c\u0e40\u0e27\u0e22\u0e4c","NA":"\u0e19\u0e32\u0e21\u0e34\u0e40\u0e1a\u0e35\u0e22","NR":"\u0e19\u0e32\u0e2d\u0e39\u0e23\u0e39","NI":"\u0e19\u0e34\u0e01\u0e32\u0e23\u0e32\u0e01\u0e31\u0e27","NC":"\u0e19\u0e34\u0e27\u0e41\u0e04\u0e25\u0e34\u0e42\u0e14\u0e40\u0e19\u0e35\u0e22","NZ":"\u0e19\u0e34\u0e27\u0e0b\u0e35\u0e41\u0e25\u0e19\u0e14\u0e4c","NU":"\u0e19\u0e35\u0e2d\u0e39\u0e40\u0e2d","NL":"\u0e40\u0e19\u0e40\u0e18\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","BQ":"\u0e40\u0e19\u0e40\u0e18\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c\u0e41\u0e04\u0e23\u0e34\u0e1a\u0e40\u0e1a\u0e35\u0e22\u0e19","NP":"\u0e40\u0e19\u0e1b\u0e32\u0e25","NG":"\u0e44\u0e19\u0e08\u0e35\u0e40\u0e23\u0e35\u0e22","NE":"\u0e44\u0e19\u0e40\u0e08\u0e2d\u0e23\u0e4c","BR":"\u0e1a\u0e23\u0e32\u0e0b\u0e34\u0e25","IO":"\u0e1a\u0e23\u0e34\u0e15\u0e34\u0e0a\u0e2d\u0e34\u0e19\u0e40\u0e14\u0e35\u0e22\u0e19\u0e42\u0e2d\u0e40\u0e0a\u0e35\u0e22\u0e19\u0e40\u0e17\u0e23\u0e4c\u0e23\u0e34\u0e17\u0e2d\u0e23\u0e35","BN":"\u0e1a\u0e23\u0e39\u0e44\u0e19","BW":"\u0e1a\u0e2d\u0e15\u0e2a\u0e27\u0e32\u0e19\u0e32","BA":"\u0e1a\u0e2d\u0e2a\u0e40\u0e19\u0e35\u0e22\u0e41\u0e25\u0e30\u0e40\u0e2e\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e42\u0e01\u0e27\u0e35\u0e19\u0e32","BD":"\u0e1a\u0e31\u0e07\u0e01\u0e25\u0e32\u0e40\u0e17\u0e28","BG":"\u0e1a\u0e31\u0e25\u0e41\u0e01\u0e40\u0e23\u0e35\u0e22","BB":"\u0e1a\u0e32\u0e23\u0e4c\u0e40\u0e1a\u0e42\u0e14\u0e2a","BH":"\u0e1a\u0e32\u0e2b\u0e4c\u0e40\u0e23\u0e19","BS":"\u0e1a\u0e32\u0e2e\u0e32\u0e21\u0e32\u0e2a","BI":"\u0e1a\u0e38\u0e23\u0e38\u0e19\u0e14\u0e35","BF":"\u0e1a\u0e39\u0e23\u0e4c\u0e01\u0e34\u0e19\u0e32\u0e1f\u0e32\u0e42\u0e0b","BJ":"\u0e40\u0e1a\u0e19\u0e34\u0e19","BE":"\u0e40\u0e1a\u0e25\u0e40\u0e22\u0e35\u0e22\u0e21","BY":"\u0e40\u0e1a\u0e25\u0e32\u0e23\u0e38\u0e2a","BZ":"\u0e40\u0e1a\u0e25\u0e35\u0e0b","BM":"\u0e40\u0e1a\u0e2d\u0e23\u0e4c\u0e21\u0e34\u0e27\u0e14\u0e32","BO":"\u0e42\u0e1a\u0e25\u0e34\u0e40\u0e27\u0e35\u0e22","PK":"\u0e1b\u0e32\u0e01\u0e35\u0e2a\u0e16\u0e32\u0e19","PA":"\u0e1b\u0e32\u0e19\u0e32\u0e21\u0e32","PG":"\u0e1b\u0e32\u0e1b\u0e31\u0e27\u0e19\u0e34\u0e27\u0e01\u0e34\u0e19\u0e35","PY":"\u0e1b\u0e32\u0e23\u0e32\u0e01\u0e27\u0e31\u0e22","PW":"\u0e1b\u0e32\u0e40\u0e25\u0e32","PE":"\u0e40\u0e1b\u0e23\u0e39","PR":"\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e42\u0e15\u0e23\u0e34\u0e42\u0e01","PT":"\u0e42\u0e1b\u0e23\u0e15\u0e38\u0e40\u0e01\u0e2a","PL":"\u0e42\u0e1b\u0e41\u0e25\u0e19\u0e14\u0e4c","FR":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a","FJ":"\u0e1f\u0e34\u0e08\u0e34","FI":"\u0e1f\u0e34\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c","PH":"\u0e1f\u0e34\u0e25\u0e34\u0e1b\u0e1b\u0e34\u0e19\u0e2a\u0e4c","GF":"\u0e40\u0e1f\u0e23\u0e19\u0e0a\u0e4c\u0e40\u0e01\u0e35\u0e22\u0e19\u0e32","TF":"\u0e40\u0e1f\u0e23\u0e19\u0e0a\u0e4c\u0e40\u0e0b\u0e32\u0e40\u0e17\u0e34\u0e23\u0e4c\u0e19\u0e40\u0e17\u0e23\u0e4c\u0e23\u0e34\u0e17\u0e2d\u0e23\u0e35\u0e2a\u0e4c","PF":"\u0e40\u0e1f\u0e23\u0e19\u0e0a\u0e4c\u0e42\u0e1b\u0e25\u0e34\u0e19\u0e35\u0e40\u0e0b\u0e35\u0e22","BT":"\u0e20\u0e39\u0e0f\u0e32\u0e19","MN":"\u0e21\u0e2d\u0e07\u0e42\u0e01\u0e40\u0e25\u0e35\u0e22","MS":"\u0e21\u0e2d\u0e19\u0e15\u0e4c\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e23\u0e31\u0e15","ME":"\u0e21\u0e2d\u0e19\u0e40\u0e15\u0e40\u0e19\u0e42\u0e01\u0e23","MU":"\u0e21\u0e2d\u0e23\u0e34\u0e40\u0e0a\u0e35\u0e22\u0e2a","MR":"\u0e21\u0e2d\u0e23\u0e34\u0e40\u0e15\u0e40\u0e19\u0e35\u0e22","MD":"\u0e21\u0e2d\u0e25\u0e42\u0e14\u0e27\u0e32","MT":"\u0e21\u0e2d\u0e25\u0e15\u0e32","MV":"\u0e21\u0e31\u0e25\u0e14\u0e35\u0e1f\u0e2a\u0e4c","MK":"\u0e21\u0e32\u0e0b\u0e34\u0e42\u0e14\u0e40\u0e19\u0e35\u0e22\u0e40\u0e2b\u0e19\u0e37\u0e2d","MG":"\u0e21\u0e32\u0e14\u0e32\u0e01\u0e31\u0e2a\u0e01\u0e32\u0e23\u0e4c","YT":"\u0e21\u0e32\u0e22\u0e2d\u0e15","MQ":"\u0e21\u0e32\u0e23\u0e4c\u0e15\u0e34\u0e19\u0e35\u0e01","MW":"\u0e21\u0e32\u0e25\u0e32\u0e27\u0e35","ML":"\u0e21\u0e32\u0e25\u0e35","MY":"\u0e21\u0e32\u0e40\u0e25\u0e40\u0e0b\u0e35\u0e22","MX":"\u0e40\u0e21\u0e47\u0e01\u0e0b\u0e34\u0e42\u0e01","MM":"\u0e40\u0e21\u0e35\u0e22\u0e19\u0e21\u0e32\u0e23\u0e4c (\u0e1e\u0e21\u0e48\u0e32)","MZ":"\u0e42\u0e21\u0e0b\u0e31\u0e21\u0e1a\u0e34\u0e01","MC":"\u0e42\u0e21\u0e19\u0e32\u0e42\u0e01","MA":"\u0e42\u0e21\u0e23\u0e47\u0e2d\u0e01\u0e42\u0e01","FM":"\u0e44\u0e21\u0e42\u0e04\u0e23\u0e19\u0e35\u0e40\u0e0b\u0e35\u0e22","GI":"\u0e22\u0e34\u0e1a\u0e23\u0e2d\u0e25\u0e15\u0e32\u0e23\u0e4c","UG":"\u0e22\u0e39\u0e01\u0e31\u0e19\u0e14\u0e32","UA":"\u0e22\u0e39\u0e40\u0e04\u0e23\u0e19","YE":"\u0e40\u0e22\u0e40\u0e21\u0e19","DE":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e19\u0e35","RW":"\u0e23\u0e27\u0e31\u0e19\u0e14\u0e32","RU":"\u0e23\u0e31\u0e2a\u0e40\u0e0b\u0e35\u0e22","RE":"\u0e40\u0e23\u0e2d\u0e39\u0e19\u0e35\u0e22\u0e07","RO":"\u0e42\u0e23\u0e21\u0e32\u0e40\u0e19\u0e35\u0e22","LU":"\u0e25\u0e31\u0e01\u0e40\u0e0b\u0e21\u0e40\u0e1a\u0e34\u0e23\u0e4c\u0e01","LV":"\u0e25\u0e31\u0e15\u0e40\u0e27\u0e35\u0e22","LA":"\u0e25\u0e32\u0e27","LI":"\u0e25\u0e34\u0e01\u0e40\u0e15\u0e19\u0e2a\u0e44\u0e15\u0e19\u0e4c","LT":"\u0e25\u0e34\u0e17\u0e31\u0e27\u0e40\u0e19\u0e35\u0e22","LY":"\u0e25\u0e34\u0e40\u0e1a\u0e35\u0e22","LS":"\u0e40\u0e25\u0e42\u0e0b\u0e42\u0e17","LB":"\u0e40\u0e25\u0e1a\u0e32\u0e19\u0e2d\u0e19","LR":"\u0e44\u0e25\u0e1a\u0e35\u0e40\u0e23\u0e35\u0e22","VU":"\u0e27\u0e32\u0e19\u0e39\u0e2d\u0e32\u0e15\u0e39","WF":"\u0e27\u0e32\u0e25\u0e25\u0e34\u0e2a\u0e41\u0e25\u0e30\u0e1f\u0e38\u0e15\u0e39\u0e19\u0e32","VE":"\u0e40\u0e27\u0e40\u0e19\u0e0b\u0e38\u0e40\u0e2d\u0e25\u0e32","VN":"\u0e40\u0e27\u0e35\u0e22\u0e14\u0e19\u0e32\u0e21","LK":"\u0e28\u0e23\u0e35\u0e25\u0e31\u0e07\u0e01\u0e32","ES":"\u0e2a\u0e40\u0e1b\u0e19","SJ":"\u0e2a\u0e1f\u0e32\u0e25\u0e1a\u0e32\u0e23\u0e4c\u0e41\u0e25\u0e30\u0e22\u0e32\u0e19\u0e44\u0e21\u0e40\u0e2d\u0e19","SK":"\u0e2a\u0e42\u0e25\u0e27\u0e30\u0e40\u0e01\u0e35\u0e22","SI":"\u0e2a\u0e42\u0e25\u0e27\u0e35\u0e40\u0e19\u0e35\u0e22","CH":"\u0e2a\u0e27\u0e34\u0e15\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","SE":"\u0e2a\u0e27\u0e35\u0e40\u0e14\u0e19","US":"\u0e2a\u0e2b\u0e23\u0e31\u0e10\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e32","AE":"\u0e2a\u0e2b\u0e23\u0e31\u0e10\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e40\u0e2d\u0e21\u0e34\u0e40\u0e23\u0e15\u0e2a\u0e4c","GB":"\u0e2a\u0e2b\u0e23\u0e32\u0e0a\u0e2d\u0e32\u0e13\u0e32\u0e08\u0e31\u0e01\u0e23","DO":"\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e23\u0e31\u0e10\u0e42\u0e14\u0e21\u0e34\u0e19\u0e34\u0e01\u0e31\u0e19","CF":"\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e23\u0e31\u0e10\u0e41\u0e2d\u0e1f\u0e23\u0e34\u0e01\u0e32\u0e01\u0e25\u0e32\u0e07","SG":"\u0e2a\u0e34\u0e07\u0e04\u0e42\u0e1b\u0e23\u0e4c","CK":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e04\u0e38\u0e01","KY":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e40\u0e04\u0e22\u0e4c\u0e41\u0e21\u0e19","CC":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e42\u0e04\u0e42\u0e04\u0e2a (\u0e04\u0e35\u0e25\u0e34\u0e07)","SB":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e42\u0e0b\u0e42\u0e25\u0e21\u0e2d\u0e19","TC":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e40\u0e15\u0e34\u0e01\u0e2a\u0e4c\u0e41\u0e25\u0e30\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e40\u0e04\u0e04\u0e2d\u0e2a","MP":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e19\u0e2d\u0e23\u0e4c\u0e40\u0e17\u0e34\u0e23\u0e4c\u0e19\u0e21\u0e32\u0e40\u0e23\u0e35\u0e22\u0e19\u0e32","VG":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e1a\u0e23\u0e34\u0e15\u0e34\u0e0a\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e08\u0e34\u0e19","PN":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e1e\u0e34\u0e15\u0e41\u0e04\u0e23\u0e4c\u0e19","FK":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e1f\u0e2d\u0e25\u0e4c\u0e01\u0e41\u0e25\u0e19\u0e14\u0e4c","FO":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e41\u0e1f\u0e42\u0e23","MH":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e21\u0e32\u0e23\u0e4c\u0e41\u0e0a\u0e25\u0e25\u0e4c","UM":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e23\u0e2d\u0e1a\u0e19\u0e2d\u0e01\u0e02\u0e2d\u0e07\u0e2a\u0e2b\u0e23\u0e31\u0e10\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e32","VI":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e08\u0e34\u0e19\u0e02\u0e2d\u0e07\u0e2a\u0e2b\u0e23\u0e31\u0e10\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e32","AX":"\u0e2b\u0e21\u0e39\u0e48\u0e40\u0e01\u0e32\u0e30\u0e42\u0e2d\u0e25\u0e31\u0e19\u0e14\u0e4c","AS":"\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e31\u0e19\u0e0b\u0e32\u0e21\u0e31\u0e27","AU":"\u0e2d\u0e2d\u0e2a\u0e40\u0e15\u0e23\u0e40\u0e25\u0e35\u0e22","AT":"\u0e2d\u0e2d\u0e2a\u0e40\u0e15\u0e23\u0e35\u0e22","AD":"\u0e2d\u0e31\u0e19\u0e14\u0e2d\u0e23\u0e4c\u0e23\u0e32","AF":"\u0e2d\u0e31\u0e1f\u0e01\u0e32\u0e19\u0e34\u0e2a\u0e16\u0e32\u0e19","AZ":"\u0e2d\u0e32\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e44\u0e1a\u0e08\u0e32\u0e19","AR":"\u0e2d\u0e32\u0e23\u0e4c\u0e40\u0e08\u0e19\u0e15\u0e34\u0e19\u0e32","AM":"\u0e2d\u0e32\u0e23\u0e4c\u0e40\u0e21\u0e40\u0e19\u0e35\u0e22","AW":"\u0e2d\u0e32\u0e23\u0e39\u0e1a\u0e32","GQ":"\u0e2d\u0e34\u0e40\u0e04\u0e27\u0e17\u0e2d\u0e40\u0e23\u0e35\u0e22\u0e25\u0e01\u0e34\u0e19\u0e35","IT":"\u0e2d\u0e34\u0e15\u0e32\u0e25\u0e35","IN":"\u0e2d\u0e34\u0e19\u0e40\u0e14\u0e35\u0e22","ID":"\u0e2d\u0e34\u0e19\u0e42\u0e14\u0e19\u0e35\u0e40\u0e0b\u0e35\u0e22","IQ":"\u0e2d\u0e34\u0e23\u0e31\u0e01","IL":"\u0e2d\u0e34\u0e2a\u0e23\u0e32\u0e40\u0e2d\u0e25","IR":"\u0e2d\u0e34\u0e2b\u0e23\u0e48\u0e32\u0e19","EG":"\u0e2d\u0e35\u0e22\u0e34\u0e1b\u0e15\u0e4c","UZ":"\u0e2d\u0e38\u0e0b\u0e40\u0e1a\u0e01\u0e34\u0e2a\u0e16\u0e32\u0e19","UY":"\u0e2d\u0e38\u0e23\u0e38\u0e01\u0e27\u0e31\u0e22","EC":"\u0e40\u0e2d\u0e01\u0e27\u0e32\u0e14\u0e2d\u0e23\u0e4c","ET":"\u0e40\u0e2d\u0e18\u0e34\u0e42\u0e2d\u0e40\u0e1b\u0e35\u0e22","ER":"\u0e40\u0e2d\u0e23\u0e34\u0e40\u0e17\u0e23\u0e35\u0e22","SV":"\u0e40\u0e2d\u0e25\u0e0b\u0e31\u0e25\u0e27\u0e32\u0e14\u0e2d\u0e23\u0e4c","EE":"\u0e40\u0e2d\u0e2a\u0e42\u0e15\u0e40\u0e19\u0e35\u0e22","SZ":"\u0e40\u0e2d\u0e2a\u0e27\u0e32\u0e15\u0e35\u0e19\u0e35","AI":"\u0e41\u0e2d\u0e07\u0e01\u0e27\u0e34\u0e25\u0e25\u0e32","AO":"\u0e41\u0e2d\u0e07\u0e42\u0e01\u0e25\u0e32","AQ":"\u0e41\u0e2d\u0e19\u0e15\u0e32\u0e23\u0e4c\u0e01\u0e15\u0e34\u0e01\u0e32","AG":"\u0e41\u0e2d\u0e19\u0e15\u0e34\u0e01\u0e32\u0e41\u0e25\u0e30\u0e1a\u0e32\u0e23\u0e4c\u0e1a\u0e39\u0e14\u0e32","ZA":"\u0e41\u0e2d\u0e1f\u0e23\u0e34\u0e01\u0e32\u0e43\u0e15\u0e49","DZ":"\u0e41\u0e2d\u0e25\u0e08\u0e35\u0e40\u0e23\u0e35\u0e22","AL":"\u0e41\u0e2d\u0e25\u0e40\u0e1a\u0e40\u0e19\u0e35\u0e22","OM":"\u0e42\u0e2d\u0e21\u0e32\u0e19","IS":"\u0e44\u0e2d\u0e0b\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","IE":"\u0e44\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","HN":"\u0e2e\u0e2d\u0e19\u0e14\u0e39\u0e23\u0e31\u0e2a","HU":"\u0e2e\u0e31\u0e07\u0e01\u0e32\u0e23\u0e35","HT":"\u0e40\u0e2e\u0e15\u0e34"} \ No newline at end of file diff --git a/public/intl/language/bn-BD.json b/public/intl/language/bn-BD.json new file mode 100644 index 00000000..1c9e80b9 --- /dev/null +++ b/public/intl/language/bn-BD.json @@ -0,0 +1 @@ +{"oc":"\u0985\u0995\u09cd\u09b8\u09bf\u099f\u09be\u09a8","und":"\u0985\u099c\u09be\u09a8\u09be \u09ad\u09be\u09b7\u09be","kaj":"\u0985\u099c\u09cd\u099c\u09c1","ota":"\u0985\u099f\u09cb\u09ae\u09be\u09a8 \u09a4\u09c1\u09b0\u09cd\u0995\u09bf","ada":"\u0985\u09a6\u09be\u0997\u09cd\u09ae\u09c7","om":"\u0985\u09b0\u09cb\u09ae\u09cb","de_AT":"\u0985\u09b8\u09cd\u099f\u09cd\u09b0\u09bf\u09af\u09bc\u09be\u09a8 \u099c\u09be\u09b0\u09ae\u09be\u09a8","en_AU":"\u0985\u09b8\u09cd\u099f\u09cd\u09b0\u09c7\u09b2\u09c0\u09af\u09bc \u0987\u0982\u09b0\u09c7\u099c\u09bf","ace":"\u0985\u09cd\u09af\u09be\u099a\u09be\u0987\u09a8\u09bf\u099c","ain":"\u0986\u0987\u09a8\u09c1","ga":"\u0986\u0987\u09b0\u09bf\u09b6","is":"\u0986\u0987\u09b8\u09b2\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u09c0\u09af\u09bc","awa":"\u0986\u0993\u09af\u09bc\u09be\u09a7\u09bf","ak":"\u0986\u0995\u09be\u09a8","ach":"\u0986\u0995\u09cb\u09b2\u09bf","akk":"\u0986\u0995\u09cd\u0995\u09be\u09a6\u09bf\u09af\u09bc\u09be\u09a8","anp":"\u0986\u0999\u09cd\u0997\u09bf\u0995\u09be","az":"\u0986\u099c\u09be\u09b0\u09ac\u09be\u0987\u099c\u09be\u09a8\u09c0","cch":"\u0986\u09a4\u09cd\u09b8\u09be\u09ae","zgh":"\u0986\u09a6\u09b0\u09cd\u09b6 \u09ae\u09b0\u0995\u09cd\u0995\u09cb\u09a8 \u09a4\u09be\u09ae\u09be\u099c\u09bf\u0997\u09be\u09a4","ady":"\u0986\u09a6\u09c7\u0997\u09c7","ar_001":"\u0986\u09a7\u09c1\u09a8\u09bf\u0995 \u0986\u09a6\u09b0\u09cd\u09b6 \u0986\u09b0\u09ac\u09c0","aa":"\u0986\u09ab\u09be\u09b0","af":"\u0986\u09ab\u09cd\u09b0\u09bf\u0995\u09be\u09a8\u09cd\u09b8","afh":"\u0986\u09ab\u09cd\u09b0\u09bf\u09b9\u09bf\u09b2\u09bf","ab":"\u0986\u09ac\u0996\u09be\u099c\u09bf\u09af\u09bc\u09be\u09a8","ae":"\u0986\u09ac\u09c7\u09b8\u09cd\u09a4\u09c0\u09af\u09bc","av":"\u0986\u09ad\u09c7\u09b0\u09bf\u0995","am":"\u0986\u09ae\u09b9\u09be\u09b0\u09bf\u0995","en_US":"\u0986\u09ae\u09c7\u09b0\u09bf\u0995\u09be\u09b0 \u0987\u0982\u09b0\u09c7\u099c\u09bf","ay":"\u0986\u09af\u09bc\u09ae\u09be\u09b0\u09be","ar":"\u0986\u09b0\u09ac\u09c0","rup":"\u0986\u09b0\u09ae\u09c7\u09a8\u09bf\u09af\u09bc\u09be\u09a8","arw":"\u0986\u09b0\u09be\u0993\u09af\u09bc\u09be\u0995","arp":"\u0986\u09b0\u09be\u09aa\u09be\u09b9\u09cb","arc":"\u0986\u09b0\u09be\u09ae\u09be\u0987\u0995","an":"\u0986\u09b0\u09cd\u0997\u09cb\u09a8\u09bf\u099c","hy":"\u0986\u09b0\u09cd\u09ae\u09c7\u09a8\u09bf\u09af\u09bc","sq":"\u0986\u09b2\u09ac\u09c7\u09a8\u09c0\u09af\u09bc","ale":"\u0986\u09b2\u09c7\u0989\u09a4","as":"\u0986\u09b8\u09be\u09ae\u09bf","asa":"\u0986\u09b8\u09c1","ast":"\u0986\u09b8\u09cd\u09a4\u09c1\u09b0\u09bf\u09af\u09bc","uk":"\u0987\u0989\u0995\u09cd\u09b0\u09c7\u09a8\u09c0\u09af\u09bc","es_ES":"\u0987\u0989\u09b0\u09cb\u09aa\u09c0\u09af\u09bc \u09b8\u09cd\u09aa\u09cd\u09af\u09be\u09a8\u09bf\u09b6","pt_PT":"\u0987\u0989\u09b0\u09cb\u09aa\u09c7\u09b0 \u09aa\u09b0\u09cd\u09a4\u09c1\u0997\u09c0\u099c","ewo":"\u0987\u0993\u09a8\u09cd\u09a1\u09cb","yo":"\u0987\u0993\u09b0\u09c1\u09ac\u09be","en":"\u0987\u0982\u09b0\u09c7\u099c\u09bf","eka":"\u0987\u0995\u09be\u099c\u09c1\u0995","ig":"\u0987\u0997\u09cd\u200c\u09ac\u09cb","inh":"\u0987\u0999\u09cd\u0997\u09c1\u09b6","io":"\u0987\u09a1\u09cb","it":"\u0987\u09a4\u09be\u09b2\u09c0\u09af\u09bc","smn":"\u0987\u09a8\u09be\u09b0\u09bf \u09b8\u09be\u09ae\u09bf","iu":"\u0987\u09a8\u09c1\u0995\u09cd\u099f\u09bf\u099f\u09c1\u099f","ik":"\u0987\u09a8\u09c1\u09aa\u09bf\u09af\u09bc\u09be\u0995","ie":"\u0987\u09a8\u09cd\u099f\u09be\u09b0\u09b2\u09bf\u0999\u09cd\u0997","ia":"\u0987\u09a8\u09cd\u099f\u09be\u09b0\u09b2\u09bf\u0999\u09cd\u0997\u09c1\u09af\u09bc\u09be","id":"\u0987\u09a8\u09cd\u09a6\u09cb\u09a8\u09c7\u09b6\u09c0\u09af\u09bc","iba":"\u0987\u09ac\u09be\u09a8","yao":"\u0987\u09af\u09bc\u09be\u0993","sah":"\u0987\u09af\u09bc\u09be\u0995\u09c1\u099f","yap":"\u0987\u09af\u09bc\u09be\u09aa\u09c7\u09b8\u09c7","ilo":"\u0987\u09b2\u09cb\u0995\u09cb","ug":"\u0989\u0987\u0998\u09c1\u09b0","wo":"\u0989\u0993\u09b2\u09cb\u09ab","uga":"\u0989\u0997\u09be\u09b0\u09bf\u099f\u09bf\u0995","hsb":"\u0989\u099a\u09cd\u099a \u09b8\u09cb\u09b0\u09cd\u09ac\u09bf\u09af\u09bc\u09be\u09a8","uz":"\u0989\u099c\u09ac\u09c7\u0995\u09c0\u09af\u09bc","udm":"\u0989\u09a1\u09ae\u09c1\u09b0\u09cd\u099f","nd":"\u0989\u09a4\u09cd\u09a4\u09b0 \u098f\u09a8\u09cd\u09a6\u09c7\u09ac\u09bf\u09b2\u09bf","frr":"\u0989\u09a4\u09cd\u09a4\u09b0\u09be\u099e\u09cd\u099a\u09b2\u09c0\u09af\u09bc \u09ab\u09cd\u09b0\u09bf\u09b8\u09bf\u09af\u09bc\u09be\u09a8","se":"\u0989\u09a4\u09cd\u09a4\u09b0\u09be\u099e\u09cd\u099a\u09b2\u09c0\u09af\u09bc \u09b8\u09be\u09ae\u09bf","nso":"\u0989\u09a4\u09cd\u09a4\u09b0\u09be\u099e\u09cd\u099a\u09b2\u09c0\u09af\u09bc \u09b8\u09cb\u09a5\u09cb","umb":"\u0989\u09ae\u09cd\u09ac\u09c1\u09a8\u09cd\u09a6\u09c1","ur":"\u0989\u09b0\u09cd\u09a6\u09c1","agq":"\u098f\u0998\u09c7\u09ae","nqo":"\u098f\u09a8\u2019\u0995\u09cb","nzi":"\u098f\u09a8\u09cd.\u099c\u09bf\u09ae\u09be","ng":"\u098f\u09a8\u09cd\u09a6\u09cb\u0999\u09cd\u0997\u09be","efi":"\u098f\u09ab\u09bf\u0995","ebu":"\u098f\u09ae\u09cd\u09ac\u09c1","ee":"\u098f\u09af\u09bc\u09c7","myv":"\u098f\u09b0\u099c\u09bf\u09af\u09bc\u09be","elx":"\u098f\u09b2\u09be\u09ae\u09be\u0987\u099f","et":"\u098f\u09b8\u09cd\u09a4\u09cb\u09a8\u09c0\u09af\u09bc","eo":"\u098f\u09b8\u09cd\u09aa\u09c7\u09b0\u09be\u09a8\u09cd\u09a4\u09cb","zh_Hant":"\u0990\u09a4\u09bf\u09b9\u09cd\u09af\u09ac\u09be\u09b9\u09bf \u099a\u09c0\u09a8\u09be","oj":"\u0993\u099c\u09bf\u09ac\u0993\u09af\u09bc\u09be","or":"\u0993\u09a1\u09bc\u09bf\u09af\u09bc\u09be","war":"\u0993\u09af\u09bc\u09be\u09b0\u09c7","wal":"\u0993\u09af\u09bc\u09be\u09b2\u09be\u09ae\u09cb","wa":"\u0993\u09af\u09bc\u09be\u09b2\u09c1\u09a8","was":"\u0993\u09af\u09bc\u09be\u09b6\u09cb","cy":"\u0993\u09af\u09bc\u09c7\u09b2\u09b6","osa":"\u0993\u09b8\u09c7\u099c","os":"\u0993\u09b8\u09c7\u099f\u09bf\u0995","kg":"\u0995\u0999\u09cd\u0997\u09cb","swc":"\u0995\u0999\u09cd\u0997\u09cb \u09b8\u09cb\u09af\u09bc\u09be\u09b9\u09bf\u09b2\u09bf","cop":"\u0995\u09aa\u099f\u09bf\u0995","koi":"\u0995\u09ae\u09bf-\u09aa\u09be\u09b0\u09ae\u09bf\u0986\u0995","kw":"\u0995\u09b0\u09cd\u09a3\u09bf\u09b6","co":"\u0995\u09b0\u09cd\u09b8\u09bf\u0995\u09be\u09a8","kaw":"\u0995\u09be\u0989\u0987","kac":"\u0995\u09be\u099a\u09bf\u09a8","kk":"\u0995\u09be\u099c\u09be\u0996","ca":"\u0995\u09be\u09a4\u09be\u09b2\u09be\u09a8","en_CA":"\u0995\u09be\u09a8\u09be\u09a1\u09c0\u09af\u09bc \u0987\u0982\u09b0\u09c7\u099c\u09bf","kr":"\u0995\u09be\u09a8\u09c1\u09b0\u09bf","kn":"\u0995\u09be\u09a8\u09cd\u09a8\u09be\u09a1\u09bc\u09c0","kab":"\u0995\u09be\u09ac\u09be\u0987\u09b2\u09c7","kbd":"\u0995\u09be\u09ac\u09be\u09b0\u09cd\u09a1\u09bf\u09af\u09bc\u09be\u09a8","kea":"\u0995\u09be\u09ac\u09c1\u09ad\u09be\u09b0\u09a6\u09bf\u09af\u09bc\u09be\u09a8\u09c1","kam":"\u0995\u09be\u09ae\u09cd\u09ac\u09be","krc":"\u0995\u09be\u09b0\u099a\u09c7-\u09ac\u09be\u09b2\u09cd\u0995\u09be\u09b0","kaa":"\u0995\u09be\u09b0\u09be-\u0995\u09be\u09b2\u09cd\u09aa\u09be\u0995","krl":"\u0995\u09be\u09b0\u09c7\u09b2\u09bf\u09af\u09bc\u09be\u09a8","kln":"\u0995\u09be\u09b2\u09c7\u09a8\u099c\u09bf\u09a8","xal":"\u0995\u09be\u09b2\u09cd\u09ae\u0987\u0995","csb":"\u0995\u09be\u09b6\u09c1\u09ac\u09bf\u09af\u09bc\u09be\u09a8","ks":"\u0995\u09be\u09b6\u09cd\u09ae\u09c0\u09b0\u09c0","quc":"\u0995\u09bf\u2018\u099a\u09c7","ki":"\u0995\u09bf\u0995\u09c1\u09cd\u0987\u09af\u09bc\u09c1","rw":"\u0995\u09bf\u09a8\u09af\u09bc\u09be\u09b0\u09cb\u09af\u09bc\u09be\u09a8\u09cd\u09a1\u09be","kmb":"\u0995\u09bf\u09ae\u09cd\u09ac\u09c1\u09a8\u09cd\u09a6\u09c1","ky":"\u0995\u09bf\u09b0\u09cd\u0997\u09bf\u099c","kut":"\u0995\u09c1\u099f\u09c7\u09a8\u09be\u0987","kum":"\u0995\u09c1\u09ae\u09bf\u0995","kru":"\u0995\u09c1\u09b0\u09c1\u0996","ku":"\u0995\u09c1\u09b0\u09cd\u09a6\u09bf","qu":"\u0995\u09c7\u099a\u09c1\u09af\u09bc\u09be","kok":"\u0995\u09cb\u0999\u09cd\u0995\u09be\u09a8\u09bf","kv":"\u0995\u09cb\u09ae\u09bf","khq":"\u0995\u09cb\u09af\u09bc\u09b0\u09be \u099a\u09c0\u09a8\u09bf","ses":"\u0995\u09cb\u09af\u09bc\u09b0\u09be\u09ac\u09c7\u09a8\u09cb \u09b8\u09c7\u09a8\u09cd\u09a8\u09c0","kj":"\u0995\u09cb\u09af\u09bc\u09be\u09a8\u09bf\u09af\u09bc\u09be\u09ae\u09be","nmg":"\u0995\u09cb\u09af\u09bc\u09be\u09b8\u09bf\u0993","ko":"\u0995\u09cb\u09b0\u09bf\u09af\u09bc\u09be\u09a8","kfo":"\u0995\u09cb\u09b0\u09cb","kos":"\u0995\u09cb\u09b8\u09cd\u09b0\u09be\u0987\u09a8","kpe":"\u0995\u09cd\u200c\u09aa\u09c7\u09b2\u09cd\u09b2\u09c7","cad":"\u0995\u09cd\u09af\u09be\u09a1\u09cb","fr_CA":"\u0995\u09cd\u09af\u09be\u09a8\u09be\u09a1\u09bf\u09af\u09bc\u09be\u09a8 \u09ab\u09b0\u09be\u09b8\u09c0","car":"\u0995\u09cd\u09af\u09be\u09b0\u09bf\u09ac","kl":"\u0995\u09cd\u09af\u09be\u09b2\u09be\u09b2\u09cd\u09b2\u09bf\u09b8\u09c1\u099f","cr":"\u0995\u09cd\u09b0\u09bf","mus":"\u0995\u09cd\u09b0\u09bf\u0995","crh":"\u0995\u09cd\u09b0\u09bf\u09ae\u09bf\u09af\u09bc\u09be\u09a8 \u09a4\u09c1\u09b0\u09cd\u0995\u09bf","hr":"\u0995\u09cd\u09b0\u09cb\u09af\u09bc\u09c7\u09b6\u09c0\u09af\u09bc","tlh":"\u0995\u09cd\u09b2\u09bf\u0999\u09cd\u0997\u09a8","km":"\u0996\u09ae\u09c7\u09b0","kha":"\u0996\u09be\u09b6\u09bf","kho":"\u0996\u09cb\u099f\u09be\u09a8\u09bf\u099c","gwi":"\u0997\u0993\u0987\u099a\u09cd\u2019\u0987\u09a8","got":"\u0997\u09a5\u09bf\u0995","gaa":"\u0997\u09be","gag":"\u0997\u09be\u0997\u09be\u0989\u099c","lg":"\u0997\u09be\u09a8\u09cd\u09a1\u09be","gay":"\u0997\u09be\u09af\u09bc\u09cb","gil":"\u0997\u09bf\u09b2\u09ac\u09be\u09b0\u09cd\u099f\u09bf\u099c","gez":"\u0997\u09c0\u099c","gu":"\u0997\u09c1\u099c\u09b0\u09be\u099f\u09bf","gn":"\u0997\u09c1\u09af\u09bc\u09be\u09b0\u09be\u09a8\u09bf","guz":"\u0997\u09c1\u09b8\u09c0","gon":"\u0997\u09cb\u09a8\u09cd\u09a1\u09bf","jgo":"\u0997\u09cb\u09ae\u09cd\u09ac\u09be","gor":"\u0997\u09cb\u09b0\u09cb\u09a8\u09cd\u09a4\u09be\u09b2\u09cb","gl":"\u0997\u09cd\u09af\u09be\u09b2\u09bf\u09b6\u09bf\u09af\u09bc","el":"\u0997\u09cd\u09b0\u09bf\u0995","grb":"\u0997\u09cd\u09b0\u09c7\u09ac\u09cb","cho":"\u099a\u0995\u099f\u09cb\u0993","chg":"\u099a\u09be\u0997\u09be\u09a4\u09be\u0987","ch":"\u099a\u09be\u09ae\u09cb\u09b0\u09cb","cu":"\u099a\u09be\u09b0\u09cd\u099a \u09b8\u09cd\u09b2\u09be\u09ad\u09bf\u0995","cgg":"\u099a\u09bf\u0997\u09be","zbl":"\u099a\u09bf\u09a4\u09cd\u09b0 \u09ad\u09be\u09b7\u09be","chn":"\u099a\u09bf\u09a8\u09c1\u0995 \u099c\u09be\u09b0\u09cd\u0997\u09a8","chp":"\u099a\u09bf\u09aa\u09c7\u0993\u09af\u09bc\u09be\u09a8","chb":"\u099a\u09bf\u09ac\u099a\u09be","zh":"\u099a\u09c0\u09a8\u09be","chk":"\u099a\u09c1\u0995\u09bf","cv":"\u099a\u09c1\u09ac\u09be\u09b8","cs":"\u099a\u09c7\u0995","ce":"\u099a\u09c7\u099a\u09c7\u09a8","ceb":"\u099a\u09c7\u09ac\u09c1\u09af\u09bc\u09be\u09a8\u09cb","chr":"\u099a\u09c7\u09b0\u09cb\u0995\u09c0","ka":"\u099c\u09b0\u09cd\u099c\u09bf\u09af\u09bc\u09be\u09a8","dyo":"\u099c\u09b2\u09be-\u09ab\u09a8\u09c0","zza":"\u099c\u09be\u099c\u09be","ja":"\u099c\u09be\u09aa\u09be\u09a8\u09bf","zap":"\u099c\u09be\u09aa\u09cb\u099f\u09c7\u0995","jv":"\u099c\u09be\u09ad\u09be\u09a8\u09bf","dje":"\u099c\u09be\u09b0\u09cd\u09ae\u09be","de":"\u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8","jrb":"\u099c\u09c1\u09a6\u09c7\u0993 \u0986\u09b0\u09ac\u09bf","jpr":"\u099c\u09c1\u09a6\u09c7\u0993 \u09ab\u09be\u09b0\u09cd\u09b8\u09bf","zun":"\u099c\u09c1\u09a8\u09bf","zu":"\u099c\u09c1\u09b2\u09c1","zen":"\u099c\u09c7\u09a8\u09be\u0997\u09be","dz":"\u099c\u09cb\u0999\u09cd\u0997\u09be","xh":"\u099c\u09cb\u09b8\u09be","za":"\u099d\u09c1\u09cd\u09af\u09bc\u09be\u0999","tig":"\u099f\u09be\u0987\u0997\u09cd\u09b0\u09c7","tem":"\u099f\u09be\u0987\u09ae\u09cd\u09a8\u09c7","kcg":"\u099f\u09be\u0987\u09af\u09bc\u09be\u09aa","tiv":"\u099f\u09bf\u09ad","tvl":"\u099f\u09c1\u09ad\u09be\u09b2\u09c1","tyv":"\u099f\u09c1\u09ad\u09bf\u09a8\u09bf\u09af\u09bc\u09be\u09a8","tpi":"\u099f\u09cb\u0995 \u09aa\u09bf\u09b8\u09bf\u09a8","tkl":"\u099f\u09cb\u0995\u09c7\u09b2\u09be\u0989","to":"\u099f\u09cb\u0999\u09cd\u0997\u09be\u09a8","tw":"\u099f\u09cb\u09af\u09bc\u09be\u0987","dak":"\u09a1\u09be\u0995\u09cb\u099f\u09be","nl":"\u09a1\u09be\u099a","dyu":"\u09a1\u09bf\u0989\u09b2\u09be","din":"\u09a1\u09bf\u0982\u0995\u09be","da":"\u09a1\u09c7\u09a8\u09bf\u09b6","del":"\u09a1\u09c7\u09b2\u09be\u0993\u09af\u09bc\u09c7\u09b0","doi":"\u09a1\u09cb\u0997\u09b0\u09bf","dav":"\u09a4\u09be\u0987\u09a4\u09be","tl":"\u09a4\u09be\u0997\u09be\u09b2\u0997","shi":"\u09a4\u09be\u099a\u09c7\u09b2\u09b9\u09bf\u09a4","tg":"\u09a4\u09be\u099c\u09bf\u0995","tt":"\u09a4\u09be\u09a4\u09be\u09b0","tmh":"\u09a4\u09be\u09ae\u09be\u09b6\u09c7\u0995","ta":"\u09a4\u09be\u09ae\u09bf\u09b2","twq":"\u09a4\u09be\u09b8\u09be\u0993\u09af\u09bc\u09be\u0995","ty":"\u09a4\u09be\u09b9\u09bf\u09a4\u09bf\u09af\u09bc\u09be\u09a8","ti":"\u09a4\u09bf\u0997\u09b0\u09bf\u09a8\u09bf\u09af\u09bc\u09be","bo":"\u09a4\u09bf\u09ac\u09cd\u09ac\u09a4\u09bf","tum":"\u09a4\u09c1\u09ae\u09cd\u09ac\u09c1\u0995\u09be","tk":"\u09a4\u09c1\u09b0\u09cd\u0995\u09ae\u09c7\u09a8\u09c0","tr":"\u09a4\u09c1\u09b0\u09cd\u0995\u09c0","tet":"\u09a4\u09c7\u09a4\u09c1\u09ae","ter":"\u09a4\u09c7\u09b0\u09c7\u09a8\u09cb","te":"\u09a4\u09c7\u09b2\u09c7\u0997\u09c1","teo":"\u09a4\u09c7\u09b8\u09cb","tli":"\u09a4\u09cd\u09b2\u09bf\u0999\u09cd\u0997\u09bf\u099f","th":"\u09a5\u09be\u0987","nr":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3 \u098f\u09a8\u09a1\u09c7\u09ac\u09c7\u09b2\u09c7","sma":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a3\u09be\u099e\u09cd\u099a\u09b2\u09c0\u09af\u09bc \u09b8\u09be\u09ae\u09bf","alt":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a8 \u0986\u09b2\u09a4\u09be\u0987","st":"\u09a6\u0995\u09cd\u09b7\u09bf\u09a8 \u09b8\u09cb\u09a5\u09cb","dar":"\u09a6\u09be\u09b0\u09cd\u0997\u0993\u09af\u09bc\u09be","dv":"\u09a6\u09bf\u09ac\u09c7\u09b9\u09bf","dua":"\u09a6\u09c1\u09af\u09bc\u09be\u09b2\u09be","dgr":"\u09a6\u09cb\u0997\u09cd\u09b0\u09c0\u09ac","nb":"\u09a8\u09b0\u0993\u09af\u09bc\u09c7\u099c\u09bf\u09af\u09bc\u09be\u09a8 \u09ac\u09cb\u0995\u09ae\u09be\u09b2","no":"\u09a8\u09b0\u0993\u09af\u09bc\u09c7\u099c\u09c0\u09af\u09bc","nn":"\u09a8\u09b0\u0993\u09af\u09bc\u09c7\u099c\u09c0\u09af\u09bc\u09be\u09a8 \u09a8\u09bf\u09a8\u09b0\u09cd\u09b8\u09cd\u0995","na":"\u09a8\u09be\u0989\u09b0\u09c1","nv":"\u09a8\u09be\u09ad\u09be\u099c\u09cb","naq":"\u09a8\u09be\u09ae\u09be","ny":"\u09a8\u09be\u09af\u09bc\u09be\u099e\u09cd\u099c\u09be","tog":"\u09a8\u09be\u09af\u09bc\u09be\u09b8\u09be \u099f\u09cb\u0999\u09cd\u0997\u09be","niu":"\u09a8\u09bf\u0989\u09af\u09bc\u09be\u09a8","nds":"\u09a8\u09bf\u09ae\u09cd\u09a8 \u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8\u09bf","dsb":"\u09a8\u09bf\u09ae\u09cd\u09a8\u09a4\u09b0 \u09b8\u09cb\u09b0\u09cd\u09ac\u09bf\u09af\u09bc\u09be\u09a8","nia":"\u09a8\u09bf\u09af\u09bc\u09be\u09b8","nus":"\u09a8\u09c1\u09af\u09bc\u09be\u09b0","new":"\u09a8\u09c7\u0993\u09af\u09bc\u09be\u09b0\u09bf","ne":"\u09a8\u09c7\u09aa\u09be\u09b2\u09c0","nap":"\u09a8\u09c7\u09af\u09bc\u09be\u09aa\u09cb\u09b2\u09bf\u099f\u09be\u09a8","nog":"\u09a8\u09cb\u0997\u09be\u0987","nyn":"\u09a8\u09cd\u09af\u09be\u09af\u09bc\u09be\u0999\u09cd\u0995\u09cb\u09b2\u09c7","nym":"\u09a8\u09cd\u09af\u09be\u09af\u09bc\u09be\u09ae\u0993\u09af\u09bc\u09c7\u099c\u09bf","nyo":"\u09a8\u09cd\u09af\u09cb\u09b0\u09cb","pt":"\u09aa\u09b0\u09cd\u09a4\u09c1\u0997\u09c0\u099c","fy":"\u09aa\u09b6\u09cd\u099a\u09bf\u09ae \u09ab\u09cd\u09b0\u09bf\u09b8\u09bf\u09af\u09bc","pag":"\u09aa\u09be\u0999\u09cd\u0997\u09be\u09b8\u09bf\u09a8\u09be\u09a8","pa":"\u09aa\u09be\u099e\u09cd\u099c\u09be\u09ac\u09c0","pap":"\u09aa\u09be\u09aa\u09bf\u09af\u09bc\u09be\u09ae\u09c7\u09a8\u09cd\u099f\u09cb","pam":"\u09aa\u09be\u09ae\u09cd\u09aa\u09be\u0999\u09cd\u0997\u09be","pau":"\u09aa\u09be\u09b2\u09be\u09af\u09bc\u09c1\u09af\u09bc\u09be\u09a8","pi":"\u09aa\u09be\u09b2\u09bf","ps":"\u09aa\u09be\u09b6\u09cd\u09a4\u09c1","pal":"\u09aa\u09be\u09b9\u09cd\u09b2\u09be\u09ad\u09bf","frs":"\u09aa\u09c2\u09b0\u09cd\u09ac \u09ab\u09cd\u09b0\u09bf\u09b8\u09bf\u09af\u09bc","pl":"\u09aa\u09cb\u09b2\u09bf\u09b6","pon":"\u09aa\u09cb\u09b9\u09cd\u09a8\u09aa\u09c7\u0987\u09af\u09bc\u09be\u09a8","sga":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u0986\u0987\u09b0\u09bf\u09b6","ang":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u0987\u0982\u09b0\u09c7\u099c\u09c0","goh":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u0989\u099a\u09cd\u099a \u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8\u09bf","grc":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u0997\u09cd\u09b0\u09c0\u0995","non":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09a8\u09b0\u09cd\u09b8","nwc":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09a8\u09c7\u0993\u09af\u09bc\u09be\u09b0\u09c0","pro":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09aa\u09cd\u09b0\u09cb\u09ad\u09c7\u09a8\u09b8\u09be\u09b2","fro":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09ab\u09b0\u09be\u09b8\u09bf","peo":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09ab\u09be\u09b0\u09cd\u09b8\u09bf","egy":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09ae\u09bf\u09b6\u09b0\u09c0\u09af\u09bc","syc":"\u09aa\u09cd\u09b0\u09be\u099a\u09c0\u09a8 \u09b8\u09bf\u09b0\u09bf\u0993","fon":"\u09ab\u09a8","fr":"\u09ab\u09b0\u09be\u09b8\u09bf","fat":"\u09ab\u09be\u09a8\u09cd\u09a4\u09bf","fa":"\u09ab\u09be\u09b0\u09cd\u09b8\u09bf","fj":"\u09ab\u09bf\u099c\u09bf\u0993","fi":"\u09ab\u09bf\u09a8\u09bf\u09b6","fil":"\u09ab\u09bf\u09b2\u09bf\u09aa\u09bf\u09a8\u09cb","ff":"\u09ab\u09c1\u09b2\u09be\u09b9\u09cd","fo":"\u09ab\u09c7\u09b0\u09be\u0989\u09a8\u09bf","phn":"\u09ab\u09cb\u09a8\u09bf\u09b6\u09c0\u09af\u09bc\u09be\u09a8","fan":"\u09ab\u09cd\u09af\u09be\u0999\u09cd\u0997","fur":"\u09ab\u09cd\u09b0\u09bf\u0989\u09b2\u09bf\u09af\u09bc\u09be\u09a8","nl_BE":"\u09ab\u09cd\u09b2\u09c7\u09ae\u09bf\u09b6","brx":"\u09ac\u09a1\u09bc\u09cb","my":"\u09ac\u09b0\u09cd\u09ae\u09bf","bs":"\u09ac\u09b8\u09a8\u09c0\u09af\u09bc\u09be\u09a8","mul":"\u09ac\u09b9\u09c1\u0997\u09c1\u09a3\u09bf\u09a4\u0995 \u09ad\u09be\u09b7\u09be\u09b8\u09ae\u09c2\u09b9","bn":"\u09ac\u09be\u0982\u09b2\u09be","ksf":"\u09ac\u09be\u09ab\u09bf\u09af\u09bc\u09be","bm":"\u09ac\u09be\u09ae\u09ac\u09be\u09b0\u09be","gba":"\u09ac\u09be\u09af\u09bc\u09be","ban":"\u09ac\u09be\u09b2\u09bf\u09a8\u09c0\u09af\u09bc","ba":"\u09ac\u09be\u09b6\u0995\u09bf\u09b0","bas":"\u09ac\u09be\u09b8\u09be","eu":"\u09ac\u09be\u09b8\u09cd\u0995","bik":"\u09ac\u09bf\u0995\u09cb\u09b2","bin":"\u09ac\u09bf\u09a8\u09bf","bi":"\u09ac\u09bf\u09b8\u09b2\u09be\u09ae\u09be","bug":"\u09ac\u09c1\u0997\u09bf\u09a8\u09bf","bua":"\u09ac\u09c1\u09b0\u09bf\u09af\u09bc\u09be\u09a4","bg":"\u09ac\u09c1\u09b2\u0997\u09c7\u09b0\u09bf\u09af\u09bc","bej":"\u09ac\u09c7\u099c\u09be","bez":"\u09ac\u09c7\u09a8\u09be","bem":"\u09ac\u09c7\u09ae\u09cd\u09ac\u09be","be":"\u09ac\u09c7\u09b2\u09be\u09b0\u09c1\u09b6\u09bf\u09af\u09bc","bal":"\u09ac\u09c7\u09b2\u09c1\u099a\u09c0","bra":"\u09ac\u09cd\u09b0\u09be\u099c","pt_BR":"\u09ac\u09cd\u09b0\u09be\u099c\u09bf\u09b2\u09c7\u09b0 \u09aa\u09b0\u09cd\u09a4\u09c1\u0997\u09c0\u099c","en_GB":"\u09ac\u09cd\u09b0\u09bf\u099f\u09bf\u09b6 \u0987\u0982\u09b0\u09c7\u099c\u09bf","br":"\u09ac\u09cd\u09b0\u09c7\u099f\u09a8","byn":"\u09ac\u09cd\u09b2\u09bf\u09a8","vai":"\u09ad\u09be\u0987","zxx":"\u09ad\u09be\u09b7\u09be\u09ad\u09bf\u09a4\u09cd\u09a4\u09bf\u0995 \u09ac\u09bf\u09b7\u09af\u09bc\u09ac\u09b8\u09cd\u09a4\u09c1 \u09a8\u09c7\u0987","vi":"\u09ad\u09bf\u09af\u09bc\u09c7\u09a4\u09a8\u09be\u09ae\u09c0","vun":"\u09ad\u09c1\u099e\u09cd\u099c\u09cb","ve":"\u09ad\u09c7\u09a8\u09cd\u09a1\u09be","bho":"\u09ad\u09cb\u099c\u09aa\u09c1\u09b0\u09bf","vot":"\u09ad\u09cb\u099f\u09bf\u0995","vo":"\u09ad\u09cb\u09b2\u09be\u09aa\u09c1\u0995","mn":"\u09ae\u0999\u09cd\u0997\u09cb\u09b2\u09bf\u09af\u09bc","mni":"\u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0","mga":"\u09ae\u09a7\u09cd\u09af \u0986\u0987\u09b0\u09bf\u09b6","enm":"\u09ae\u09a7\u09cd\u09af \u0987\u0982\u09b0\u09c7\u099c\u09bf","dum":"\u09ae\u09a7\u09cd\u09af \u09a1\u09be\u099a","frm":"\u09ae\u09a7\u09cd\u09af \u09ab\u09b0\u09be\u09b8\u09bf","gmh":"\u09ae\u09a7\u09cd\u09af-\u0989\u099a\u09cd\u099a \u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8\u09bf","mfe":"\u09ae\u09b0\u09bf\u09b8\u09bf\u09af\u09bc\u09be\u09a8","ro_MD":"\u09ae\u09b2\u09a6\u09be\u09ad\u09bf\u09af\u09bc","mt":"\u09ae\u09b2\u09cd\u099f\u09bf\u09af\u09bc","mos":"\u09ae\u09b8\u09bf","mi":"\u09ae\u09be\u0993\u09b0\u09bf","jmc":"\u09ae\u09be\u0995\u09be\u09ae\u09c7","kde":"\u09ae\u09be\u0995\u09cb\u09a8\u09cd\u09a6\u09c7","mgh":"\u09ae\u09be\u0996\u09c1\u09af\u09bc\u09be-\u09ae\u09c7\u09a4\u09cd\u09a4\u09cb","mag":"\u09ae\u09be\u0997\u09be\u09b9\u09bf","mnc":"\u09ae\u09be\u099e\u09cd\u099a\u09c1","mad":"\u09ae\u09be\u09a6\u09c1\u09b0\u09c7\u09b8\u09c7","arn":"\u09ae\u09be\u09aa\u09c1\u099a\u09bf","mr":"\u09ae\u09be\u09b0\u09be\u09a0\u09bf","chm":"\u09ae\u09be\u09b0\u09bf","mwr":"\u09ae\u09be\u09b0\u09cb\u09af\u09bc\u09be\u09b0\u09bf","mh":"\u09ae\u09be\u09b0\u09cd\u09b6\u09be\u09b2\u09bf\u099c","ms":"\u09ae\u09be\u09b2\u09af\u09bc","mg":"\u09ae\u09be\u09b2\u09be\u0997\u09be\u09b8\u09bf","ml":"\u09ae\u09be\u09b2\u09be\u09af\u09bc\u09be\u09b2\u09be\u09ae","mas":"\u09ae\u09be\u09b8\u09be\u0987","mic":"\u09ae\u09bf\u0995\u09ae\u09cd\u09af\u09be\u0995","min":"\u09ae\u09bf\u09a8\u09be\u0999\u09cd\u0997\u09cd\u200c\u0995\u09be\u09ac\u09be\u0989","mwl":"\u09ae\u09bf\u09b0\u09be\u09a8\u09cd\u09a1\u09bf\u099c","mua":"\u09ae\u09c1\u09a6\u09be\u0999\u09cd\u0997","root":"\u09ae\u09c2\u09b2","mgo":"\u09ae\u09c7\u099f\u09be","men":"\u09ae\u09c7\u09a8\u09cd\u09a1\u09c7","mer":"\u09ae\u09c7\u09b0\u09c1","mai":"\u09ae\u09c8\u09a5\u09bf\u09b2\u09bf","mdf":"\u09ae\u09cb\u0995\u09b6\u09be","lol":"\u09ae\u09cb\u0999\u09cd\u0997\u09cb","moh":"\u09ae\u09cb\u09b9\u09be\u0993\u0995","mak":"\u09ae\u09cd\u09af\u09be\u0995\u09be\u09b8\u09be\u09b0","es_MX":"\u09ae\u09cd\u09af\u09be\u0995\u09cd\u09b8\u09bf\u0995\u09be\u09a8 \u09b8\u09cd\u09aa\u09cd\u09af\u09be\u09a8\u09bf\u09b6","gv":"\u09ae\u09cd\u09af\u09be\u0999\u09cd\u0995\u09b8","mdr":"\u09ae\u09cd\u09af\u09be\u09a3\u09cd\u09a1\u09be\u09b0","man":"\u09ae\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u09bf\u0999\u09cd\u0997\u09cb","mk":"\u09ae\u09cd\u09af\u09be\u09b8\u09bf\u09a1\u09cb\u09a8\u09c0\u09af\u09bc","yi":"\u09af\u09bc\u09bf\u09a6\u09cd\u09a6\u09bf\u09b6","rof":"\u09b0\u09ae\u09cd\u09ac\u09cb","rwk":"\u09b0\u09be\u0993\u09af\u09bc\u09be","raj":"\u09b0\u09be\u099c\u09b8\u09cd\u09a5\u09be\u09a8\u09c0","rap":"\u09b0\u09be\u09aa\u09be\u09a8\u09c1\u0987","rar":"\u09b0\u09be\u09b0\u09cb\u099f\u09cb\u0982\u0997\u09be\u09a8","rn":"\u09b0\u09c1\u09a8\u09cd\u09a6\u09bf","ru":"\u09b0\u09c1\u09b6","rom":"\u09b0\u09cb\u09ae\u09be\u09a8\u09bf","ro":"\u09b0\u09cb\u09ae\u09be\u09a8\u09c0\u09af\u09bc","rm":"\u09b0\u09cb\u09ae\u09be\u09a8\u09cd\u09b8","lo":"\u09b2\u09be\u0993","lkt":"\u09b2\u09be\u0995\u09cb\u099f\u09be","lag":"\u09b2\u09be\u0999\u09cd\u0997\u09bf","la":"\u09b2\u09be\u099f\u09bf\u09a8","lad":"\u09b2\u09be\u09a1\u09bf\u09a8\u09cb","lv":"\u09b2\u09be\u09a4\u09cd\u200c\u09ad\u09c0\u09af\u09bc","lah":"\u09b2\u09be\u09a8\u09cd\u09a1\u09be","lam":"\u09b2\u09be\u09ae\u09cd\u09ac\u09be","ln":"\u09b2\u09bf\u0999\u09cd\u0997\u09be\u09b2\u09be","lt":"\u09b2\u09bf\u09a5\u09c1\u09af\u09bc\u09c7\u09a8\u09c0\u09af\u09bc","li":"\u09b2\u09bf\u09ae\u09cd\u09ac\u09c1\u09b0\u09cd\u0997\u09bf\u09b6","luy":"\u09b2\u09c1\u0987\u09af\u09bc\u09be","lui":"\u09b2\u09c1\u0987\u09b8\u09c7\u09a8\u09cb","lb":"\u09b2\u09c1\u0995\u09cd\u09b8\u09c7\u09ae\u09ac\u09be\u09b0\u09cd\u0997\u09c0\u09af\u09bc","lun":"\u09b2\u09c1\u09a8\u09cd\u09a1\u09be","lu":"\u09b2\u09c1\u09ac\u09be-\u0995\u09be\u099f\u09be\u0999\u09cd\u0997\u09be","lua":"\u09b2\u09c1\u09ac\u09be-\u09b2\u09c1\u09b2\u09c1\u09af\u09bc\u09be","luo":"\u09b2\u09c1\u09af\u09bc\u09cb","smj":"\u09b2\u09c1\u09b2\u09c7 \u09b8\u09be\u09ae\u09bf","lus":"\u09b2\u09c1\u09b6\u09be\u0987","lez":"\u09b2\u09c7\u099c\u0998\u09bf\u09af\u09bc\u09be\u09a8","jbo":"\u09b2\u09cb\u099c\u09ac\u09be\u09a8","loz":"\u09b2\u09cb\u099c\u09bf","es_419":"\u09b2\u09cd\u09af\u09be\u099f\u09bf\u09a8 \u0986\u09ae\u09c7\u09b0\u09bf\u0995\u09be\u09a8 \u09b8\u09cd\u09aa\u09cd\u09af\u09be\u09a8\u09bf\u09b6","chy":"\u09b6\u09be\u0987\u09af\u09bc\u09c7\u09a8","shn":"\u09b6\u09be\u09a8","ksb":"\u09b6\u09be\u09ae\u09cd\u09ac\u09be\u09b2\u09be","sn":"\u09b6\u09cb\u09a8\u09be","sa":"\u09b8\u0982\u09b7\u09cd\u0995\u09c3\u09a4","ts":"\u09b8\u0999\u09cd\u0997\u09be","zh_Hans":"\u09b8\u09b0\u09b2\u09c0\u0995\u09c3\u09a4 \u099a\u09c0\u09a8\u09be","sat":"\u09b8\u09be\u0981\u0993\u09a4\u09be\u09b2\u09bf","sbp":"\u09b8\u09be\u0999\u09cd\u0997\u09c1","sg":"\u09b8\u09be\u0999\u09cd\u0997\u09cb","saq":"\u09b8\u09be\u09ae\u09ac\u09c1\u09b0\u09c1","sam":"\u09b8\u09be\u09ae\u09be\u09b0\u09bf\u099f\u09be\u09a8 \u0986\u09b0\u09be\u09ae\u09bf\u0995","sm":"\u09b8\u09be\u09ae\u09cb\u09af\u09bc\u09be\u09a8","sc":"\u09b8\u09be\u09b0\u09cd\u09a1\u09bf\u09a8\u09bf\u09af\u09bc\u09be\u09a8","sr":"\u09b8\u09be\u09b0\u09cd\u09ac\u09c0\u09af\u09bc","sh":"\u09b8\u09be\u09b0\u09cd\u09ac\u09cb-\u0995\u09cd\u09b0\u09cb\u09af\u09bc\u09c7\u09b6\u09bf\u09af\u09bc","sas":"\u09b8\u09be\u09b8\u09be\u0995","si":"\u09b8\u09bf\u0982\u09b9\u09b2\u09c0","bla":"\u09b8\u09bf\u0995\u09b8\u09bf\u0995\u09be","ii":"\u09b8\u09bf\u099a\u09c1\u09af\u09bc\u09be\u09a8 \u09af\u09bc\u09bf","sid":"\u09b8\u09bf\u09a1\u09be\u09ae\u09cb","sd":"\u09b8\u09bf\u09a8\u09cd\u09a7\u09bf","tsi":"\u09b8\u09bf\u09ae\u09b6\u09bf\u09af\u09bc\u09be\u09a8","syr":"\u09b8\u09bf\u09b0\u09bf\u09af\u09bc\u09be\u0995","scn":"\u09b8\u09bf\u09b8\u09bf\u09b2\u09bf\u09af\u09bc\u09be\u09a8","sv":"\u09b8\u09c1\u0987\u09a1\u09bf\u09b6","de_CH":"\u09b8\u09c1\u0987\u09b8 \u0989\u099a\u09cd\u099a \u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8\u09bf","gsw":"\u09b8\u09c1\u0987\u09b8 \u099c\u09be\u09b0\u09cd\u09ae\u09be\u09a8","fr_CH":"\u09b8\u09c1\u0987\u09b8 \u09ab\u09b0\u09be\u09b8\u09bf","suk":"\u09b8\u09c1\u0995\u09c1\u09ae\u09be","su":"\u09b8\u09c1\u09a6\u09be\u09a8\u09c0","sux":"\u09b8\u09c1\u09ae\u09c7\u09b0\u09c0\u09af\u09bc","sus":"\u09b8\u09c1\u09b8\u09c1","seh":"\u09b8\u09c7\u09a8\u09be","tzm":"\u09b8\u09c7\u09a8\u09cd\u099f\u09cd\u09b0\u09be\u09b2 \u0986\u099f\u09b2\u09be\u09b8 \u09a4\u09be\u09ae\u09be\u099c\u09bf\u0997\u09be\u09a4","srr":"\u09b8\u09c7\u09b0\u09c7\u09b0","sel":"\u09b8\u09c7\u09b2\u09cd\u0995\u09c1\u09aa","sog":"\u09b8\u09cb\u0997\u09a1\u09bf\u09af\u09bc\u09be\u09a8","xog":"\u09b8\u09cb\u0997\u09be","snk":"\u09b8\u09cb\u09a8\u09bf\u0999\u09cd\u0995\u09c7","so":"\u09b8\u09cb\u09ae\u09be\u09b2\u09c0","ss":"\u09b8\u09cb\u09af\u09bc\u09be\u09a4\u09bf","tn":"\u09b8\u09cb\u09af\u09bc\u09be\u09a8\u09be","sw":"\u09b8\u09cb\u09af\u09bc\u09be\u09b9\u09bf\u09b2\u09bf","ckb":"\u09b8\u09cb\u09b0\u09be\u09a8\u09bf \u0995\u09c1\u09b0\u09cd\u09a6\u09bf\u09b6","sco":"\u09b8\u09cd\u0995\u099f\u09b8","gd":"\u09b8\u09cd\u0995\u099f\u09b8-\u0997\u09cd\u09af\u09c7\u09b2\u09bf\u0995","sms":"\u09b8\u09cd\u0995\u09cb\u09b2\u09cd\u099f \u09b8\u09be\u09ae\u09bf","es":"\u09b8\u09cd\u09aa\u09cd\u09af\u09be\u09a8\u09bf\u09b6","sad":"\u09b8\u09cd\u09af\u09be\u09a8\u09cd\u09a1\u09be\u0993\u09af\u09bc\u09c7","srn":"\u09b8\u09cd\u09b0\u09be\u09a8\u09be\u09a8 \u099f\u09cb\u0999\u09cd\u0997\u09cb","sk":"\u09b8\u09cd\u09b2\u09cb\u09ad\u09be\u0995","sl":"\u09b8\u09cd\u09b2\u09cb\u09ad\u09c7\u09a8\u09c0\u09af\u09bc","den":"\u09b8\u09cd\u09b2\u09cd\u09af\u09be\u09ad","hai":"\u09b9\u09be\u0987\u09a1\u09be","ht":"\u09b9\u09be\u0987\u09a4\u09bf\u09af\u09bc\u09be\u09a8","ha":"\u09b9\u09be\u0989\u09b8\u09be","haw":"\u09b9\u09be\u0993\u09af\u09bc\u09be\u0987\u09af\u09bc\u09be\u09a8","hu":"\u09b9\u09be\u0999\u09cd\u0997\u09c7\u09b0\u09c0\u09af\u09bc","hit":"\u09b9\u09bf\u099f\u09cd\u099f\u09bf\u099f","hi":"\u09b9\u09bf\u09a8\u09cd\u09a6\u09bf","he":"\u09b9\u09bf\u09ac\u09cd\u09b0\u09c1","ho":"\u09b9\u09bf\u09b0\u09bf \u09ae\u09cb\u09a4\u09c1","hil":"\u09b9\u09bf\u09b2\u09bf\u0997\u09cd\u09af\u09be\u09af\u09bc\u09a8\u09cb\u09a8","hup":"\u09b9\u09c1\u09aa\u09be","hz":"\u09b9\u09c7\u09b0\u09c7\u09b0\u09cb","hmn":"\u09b9\u09cd\u200c\u09ae\u09cb\u0999","bss":"Akoose","akz":"Alabama","arq":"Algerian Arabic","ase":"American Sign Language","njo":"Ao Naga","aro":"Araona","frp":"Arpitan","bfq":"Badaga","bfd":"Bafut","bqi":"Bakhtiari","bax":"Bamun","bjn":"Banjar","bbc":"Batak Toba","bar":"Bavarian","bew":"Betawi","bpy":"Bishnupriya","brh":"Brahui","bum":"Bulu","frc":"Cajun French","yue":"Cantonese","cps":"Capiznon","cay":"Cayuga","dtp":"Central Dusun","esu":"Central Yupik","shu":"Chadian Arabic","qug":"Chimborazo Highland Quichua","ksh":"Colognian","swb":"Comorian","dzg":"Dazaga","arz":"Egyptian Arabic","egl":"Emilian","ext":"Extremaduran","hif":"Fiji Hindi","gur":"Frafra","gan":"Gan Chinese","aln":"Gheg Albanian","bbj":"Ghomala","glk":"Gilaki","gom":"Goan Konkani","hak":"Hakka Chinese","ibb":"Ibibio","izh":"Ingrian","jam":"Jamaican Creole English","jut":"Jutish","kgp":"Kaingang","kkj":"Kako","kbl":"Kanembu","ken":"Kenyang","khw":"Khowar","krj":"Kinaray-a","kiu":"Kirmanjki","bkm":"Kom","avk":"Kotava","kri":"Krio","ltg":"Latgalian","lzz":"Laz","lij":"Ligurian","lfn":"Lingua Franca Nova","lzh":"Literary Chinese","liv":"Livonian","lmo":"Lombard","sli":"Lower Silesian","mde":"Maba","maf":"Mafa","vmf":"Main-Franconian","mzn":"Mazanderani","byv":"Medumba","mwv":"Mentawai","nan":"Min Nan Chinese","xmf":"Mingrelian","ary":"Moroccan Arabic","ttt":"Muslim Tat","mye":"Myene","sba":"Ngambay","nnh":"Ngiemboon","yrl":"Nheengatu","nov":"Novial","pfl":"Palatine German","pdc":"Pennsylvania German","pcd":"Picard","pms":"Piedmontese","pdt":"Plautdietsch","pnt":"Pontic","prg":"Prussian","rif":"Riffian","rgn":"Romagnol","rtm":"Rotuman","rug":"Roviana","rue":"Rusyn","ssy":"Saho","sgs":"Samogitian","sdc":"Sassarese Sardinian","stq":"Saterland Frisian","saz":"Saurashtra","sly":"Selayar","see":"Seneca","sei":"Seri","szl":"Silesian","azb":"South Azerbaijani","tly":"Talysh","trv":"Taroko","fit":"Tornedalen Finnish","tkr":"Tsakhur","tsd":"Tsakonian","tcy":"Tulu","aeb":"Tunisian Arabic","tru":"Turoyo","vec":"Venetian","vep":"Veps","vro":"V\u00f5ro","wae":"Walser","wbp":"Warlpiri","guc":"Wayuu","vls":"West Flemish","mrj":"Western Mari","wuu":"Wu Chinese","hsn":"Xiang Chinese","yav":"Yangben","ybb":"Yemba","zea":"Zeelandic","gbz":"Zoroastrian Dari"} \ No newline at end of file diff --git a/public/intl/language/th-TH.json b/public/intl/language/th-TH.json new file mode 100644 index 00000000..bc926253 --- /dev/null +++ b/public/intl/language/th-TH.json @@ -0,0 +1 @@ +{"gba":"\u0e01\u0e1a\u0e32\u0e22\u0e32","bkm":"\u0e01\u0e21","el":"\u0e01\u0e23\u0e35\u0e01","grc":"\u0e01\u0e23\u0e35\u0e01\u0e42\u0e1a\u0e23\u0e32\u0e13","kl":"\u0e01\u0e23\u0e35\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c","kj":"\u0e01\u0e27\u0e19\u0e22\u0e32\u0e21\u0e32","yue":"\u0e01\u0e27\u0e32\u0e07\u0e15\u0e38\u0e49\u0e07","nmg":"\u0e01\u0e27\u0e32\u0e0b\u0e34\u0e42\u0e2d","gn":"\u0e01\u0e27\u0e32\u0e23\u0e32\u0e19\u0e35","gwi":"\u0e01\u0e27\u0e34\u0e0a\u0e2d\u0e34\u0e19","kaw":"\u0e01\u0e27\u0e35","kok":"\u0e01\u0e2d\u0e19\u0e01\u0e32\u0e19\u0e35","gom":"\u0e01\u0e2d\u0e19\u0e01\u0e32\u0e19\u0e35\u0e02\u0e2d\u0e07\u0e01\u0e31\u0e27","gon":"\u0e01\u0e2d\u0e19\u0e14\u0e34","gor":"\u0e01\u0e2d\u0e23\u0e2d\u0e19\u0e17\u0e32\u0e42\u0e25","kac":"\u0e01\u0e30\u0e09\u0e34\u0e48\u0e19","kn":"\u0e01\u0e31\u0e19\u0e19\u0e32\u0e14\u0e32","sba":"\u0e01\u0e31\u0e21\u0e40\u0e1a","ks":"\u0e01\u0e31\u0e28\u0e21\u0e35\u0e23\u0e4c","gaa":"\u0e01\u0e32","gag":"\u0e01\u0e32\u0e01\u0e32\u0e2d\u0e38\u0e0b","ca":"\u0e01\u0e32\u0e15\u0e32\u0e25\u0e31\u0e07","kab":"\u0e01\u0e32\u0e44\u0e1a\u0e25","cps":"\u0e01\u0e32\u0e1b\u0e34\u0e0b\u0e19\u0e2d\u0e19","kpe":"\u0e01\u0e32\u0e41\u0e1b\u0e25","gay":"\u0e01\u0e32\u0e42\u0e22","kaa":"\u0e01\u0e32\u0e23\u0e32-\u0e01\u0e32\u0e25\u0e1e\u0e32\u0e01","gl":"\u0e01\u0e32\u0e25\u0e34\u0e40\u0e0b\u0e35\u0e22","kha":"\u0e01\u0e32\u0e2a\u0e35","krj":"\u0e01\u0e34\u0e19\u0e32\u0e23\u0e32\u0e22\u0e2d\u0e32","gil":"\u0e01\u0e34\u0e25\u0e40\u0e1a\u0e2d\u0e23\u0e4c\u0e15","glk":"\u0e01\u0e34\u0e25\u0e32\u0e01\u0e35","ki":"\u0e01\u0e35\u0e01\u0e39\u0e22\u0e39","quc":"\u0e01\u0e35\u0e40\u0e0a","gez":"\u0e01\u0e35\u0e0b","guz":"\u0e01\u0e38\u0e0b\u0e0b\u0e35","kru":"\u0e01\u0e38\u0e23\u0e38\u0e02","aln":"\u0e40\u0e01\u0e01\u0e41\u0e2d\u0e25\u0e40\u0e1a\u0e40\u0e19\u0e35\u0e22","grb":"\u0e40\u0e01\u0e23\u0e42\u0e1a","ko":"\u0e40\u0e01\u0e32\u0e2b\u0e25\u0e35","ken":"\u0e40\u0e01\u0e34\u0e19\u0e22\u0e32\u0e07","krl":"\u0e41\u0e01\u0e23\u0e40\u0e25\u0e35\u0e22\u0e19","got":"\u0e42\u0e01\u0e18\u0e34\u0e01","kv":"\u0e42\u0e01\u0e21\u0e34","km":"\u0e40\u0e02\u0e21\u0e23","kaj":"\u0e04\u0e08\u0e39","kri":"\u0e04\u0e23\u0e34\u0e42\u0e2d","cr":"\u0e04\u0e23\u0e35","mus":"\u0e04\u0e23\u0e35\u0e01","tlh":"\u0e04\u0e25\u0e34\u0e07\u0e01\u0e2d\u0e19","qu":"\u0e04\u0e27\u0e34\u0e0a\u0e31\u0e27","qug":"\u0e04\u0e27\u0e34\u0e0a\u0e31\u0e27\u0e44\u0e2e\u0e41\u0e25\u0e19\u0e14\u0e4c\u0e0a\u0e34\u0e21\u0e42\u0e1a\u0e23\u0e32\u0e42\u0e0b","kg":"\u0e04\u0e2d\u0e07\u0e42\u0e01","cop":"\u0e04\u0e2d\u0e1b\u0e15\u0e34\u0e01","co":"\u0e04\u0e2d\u0e23\u0e4c\u0e0b\u0e34\u0e01\u0e32","kw":"\u0e04\u0e2d\u0e23\u0e4c\u0e19\u0e34\u0e0a","xh":"\u0e04\u0e30\u0e2b\u0e4c\u0e42\u0e2d\u0e0b\u0e32","cad":"\u0e04\u0e31\u0e14\u0e42\u0e14","kam":"\u0e04\u0e31\u0e21\u0e1a\u0e32","xal":"\u0e04\u0e31\u0e25\u0e21\u0e37\u0e22\u0e04\u0e4c","kkj":"\u0e04\u0e32\u0e42\u0e01","kk":"\u0e04\u0e32\u0e0b\u0e31\u0e04","csb":"\u0e04\u0e32\u0e0b\u0e39\u0e40\u0e1a\u0e35\u0e22\u0e19","kr":"\u0e04\u0e32\u0e19\u0e39\u0e23\u0e35","kbl":"\u0e04\u0e32\u0e40\u0e19\u0e21\u0e1a\u0e39","kea":"\u0e04\u0e32\u0e1a\u0e39\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e40\u0e14\u0e35\u0e22\u0e19\u0e39","cay":"\u0e04\u0e32\u0e22\u0e39\u0e01\u0e32","kbd":"\u0e04\u0e32\u0e23\u0e4c\u0e1a\u0e32\u0e40\u0e14\u0e35\u0e22","krc":"\u0e04\u0e32\u0e23\u0e32\u0e44\u0e0a-\u0e1a\u0e31\u0e25\u0e04\u0e32\u0e23\u0e4c","car":"\u0e04\u0e32\u0e23\u0e34\u0e1a","kln":"\u0e04\u0e32\u0e40\u0e25\u0e19\u0e08\u0e34\u0e19","kmb":"\u0e04\u0e34\u0e21\u0e1a\u0e38\u0e19\u0e14\u0e39","cgg":"\u0e04\u0e35\u0e01\u0e32","ky":"\u0e04\u0e35\u0e23\u0e4c\u0e01\u0e35\u0e0b","gu":"\u0e04\u0e38\u0e0a\u0e23\u0e32\u0e15","kut":"\u0e04\u0e39\u0e40\u0e17\u0e44\u0e19","kum":"\u0e04\u0e39\u0e21\u0e37\u0e22\u0e04\u0e4c","kos":"\u0e04\u0e39\u0e2a\u0e44\u0e23","kgp":"\u0e40\u0e04\u0e19\u0e01\u0e48\u0e32\u0e07","kiu":"\u0e40\u0e04\u0e2d\u0e23\u0e4c\u0e21\u0e32\u0e19\u0e34\u0e01\u0e34","ku":"\u0e40\u0e04\u0e34\u0e23\u0e4c\u0e14","ckb":"\u0e40\u0e04\u0e34\u0e23\u0e4c\u0e14\u0e42\u0e0b\u0e23\u0e32\u0e19\u0e35","kho":"\u0e42\u0e04\u0e15\u0e31\u0e19","avk":"\u0e42\u0e04\u0e15\u0e32\u0e27\u0e32","bbj":"\u0e42\u0e04\u0e21\u0e32\u0e25\u0e32","koi":"\u0e42\u0e04\u0e21\u0e34-\u0e40\u0e1b\u0e35\u0e22\u0e23\u0e4c\u0e40\u0e21\u0e35\u0e22\u0e04","swb":"\u0e42\u0e04\u0e40\u0e21\u0e2d\u0e40\u0e23\u0e35\u0e22\u0e19","khq":"\u0e42\u0e04\u0e22\u0e4c\u0e23\u0e32\u0e0a\u0e35\u0e19\u0e35","ses":"\u0e42\u0e04\u0e22\u0e4c\u0e23\u0e32\u0e42\u0e1a\u0e42\u0e23\u0e40\u0e0b\u0e19\u0e19\u0e35","hr":"\u0e42\u0e04\u0e23\u0e40\u0e2d\u0e40\u0e0a\u0e35\u0e22","kfo":"\u0e42\u0e04\u0e42\u0e23","ksh":"\u0e42\u0e04\u0e42\u0e25\u0e0d","khw":"\u0e42\u0e04\u0e27\u0e32\u0e23\u0e4c","za":"\u0e08\u0e49\u0e27\u0e07","ka":"\u0e08\u0e2d\u0e23\u0e4c\u0e40\u0e08\u0e35\u0e22","jut":"\u0e08\u0e31\u0e17","zh":"\u0e08\u0e35\u0e19","gan":"\u0e08\u0e35\u0e19\u0e01\u0e32\u0e19","lzh":"\u0e08\u0e35\u0e19\u0e04\u0e25\u0e32\u0e2a\u0e2a\u0e34\u0e01","hak":"\u0e08\u0e35\u0e19\u0e41\u0e04\u0e30","hsn":"\u0e08\u0e35\u0e19\u0e40\u0e0b\u0e35\u0e22\u0e07","zh_Hant":"\u0e08\u0e35\u0e19\u0e15\u0e31\u0e27\u0e40\u0e15\u0e47\u0e21","zh_Hans":"\u0e08\u0e35\u0e19\u0e15\u0e31\u0e27\u0e22\u0e48\u0e2d","nan":"\u0e08\u0e35\u0e19\u0e21\u0e34\u0e19\u0e2b\u0e19\u0e32\u0e19","wuu":"\u0e08\u0e35\u0e19\u0e2d\u0e39\u0e4b","nnh":"\u0e08\u0e35\u0e21\u0e1a\u0e39\u0e19","dyo":"\u0e42\u0e08\u0e25\u0e32-\u0e1f\u0e2d\u0e19\u0e22\u0e35","jv":"\u0e0a\u0e27\u0e32","cho":"\u0e0a\u0e47\u0e2d\u0e01\u0e17\u0e2d\u0e27\u0e4c","chg":"\u0e0a\u0e30\u0e01\u0e30\u0e44\u0e15","ksb":"\u0e0a\u0e31\u0e21\u0e1a\u0e32\u0e25\u0e32","ch":"\u0e0a\u0e32\u0e21\u0e2d\u0e23\u0e4c\u0e42\u0e23","chn":"\u0e0a\u0e34\u0e19\u0e38\u0e01\u0e08\u0e32\u0e23\u0e4c\u0e01\u0e2d\u0e19","chb":"\u0e0a\u0e34\u0e1a\u0e0a\u0e32","chp":"\u0e0a\u0e34\u0e1e\u0e34\u0e27\u0e22\u0e31\u0e19","chk":"\u0e0a\u0e39\u0e01","cv":"\u0e0a\u0e39\u0e27\u0e31\u0e0a","cs":"\u0e40\u0e0a\u0e47\u0e01","ce":"\u0e40\u0e0a\u0e40\u0e0a\u0e19","chy":"\u0e40\u0e0a\u0e40\u0e22\u0e19\u0e40\u0e19","cu":"\u0e40\u0e0a\u0e2d\u0e23\u0e4c\u0e0a\u0e2a\u0e25\u0e32\u0e27\u0e34\u0e01","chr":"\u0e40\u0e0a\u0e2d\u0e42\u0e23\u0e01\u0e35","sn":"\u0e42\u0e0a\u0e19\u0e32","sog":"\u0e0b\u0e2d\u0e01\u0e14\u0e35\u0e19","dz":"\u0e0b\u0e2d\u0e07\u0e04\u0e32","hsb":"\u0e0b\u0e2d\u0e23\u0e4c\u0e1a\u0e2a\u0e4c\u0e15\u0e2d\u0e19\u0e1a\u0e19","dsb":"\u0e0b\u0e2d\u0e23\u0e4c\u0e1a\u0e2a\u0e4c\u0e15\u0e2d\u0e19\u0e25\u0e48\u0e32\u0e07","sad":"\u0e0b\u0e31\u0e19\u0e14\u0e32\u0e40\u0e27","tsd":"\u0e0b\u0e32\u0e42\u0e04\u0e40\u0e19\u0e35\u0e22","sas":"\u0e0b\u0e32\u0e0b\u0e31\u0e01","zza":"\u0e0b\u0e32\u0e0b\u0e32","zap":"\u0e0b\u0e32\u0e42\u0e1b\u0e40\u0e15\u0e01","sm":"\u0e0b\u0e32\u0e21\u0e31\u0e27","sma":"\u0e0b\u0e32\u0e21\u0e34\u0e43\u0e15\u0e49","smj":"\u0e0b\u0e32\u0e21\u0e34\u0e25\u0e39\u0e40\u0e25","sms":"\u0e0b\u0e32\u0e21\u0e34\u0e2a\u0e04\u0e2d\u0e25\u0e15\u0e4c","se":"\u0e0b\u0e32\u0e21\u0e34\u0e40\u0e2b\u0e19\u0e37\u0e2d","smn":"\u0e0b\u0e32\u0e21\u0e34\u0e2d\u0e35\u0e19\u0e32\u0e23\u0e35","sgs":"\u0e0b\u0e32\u0e42\u0e21\u0e08\u0e34\u0e40\u0e15\u0e35\u0e22\u0e19","sdc":"\u0e0b\u0e32\u0e23\u0e4c\u0e14\u0e34\u0e40\u0e19\u0e35\u0e22\u0e0b\u0e32\u0e2a\u0e0b\u0e32\u0e23\u0e35","sc":"\u0e0b\u0e32\u0e23\u0e4c\u0e40\u0e14\u0e0d\u0e32","dje":"\u0e0b\u0e32\u0e23\u0e4c\u0e21\u0e32","sah":"\u0e0b\u0e32\u0e2e\u0e32","ssy":"\u0e0b\u0e32\u0e42\u0e2e","scn":"\u0e0b\u0e34\u0e0b\u0e34\u0e25\u0e35","sid":"\u0e0b\u0e34\u0e14\u0e32\u0e42\u0e21","tsi":"\u0e0b\u0e34\u0e21\u0e0a\u0e35\u0e41\u0e2d\u0e19","ts":"\u0e0b\u0e34\u0e34\u0e15\u0e0b\u0e2d\u0e07\u0e01\u0e32","syr":"\u0e0b\u0e35\u0e40\u0e23\u0e35\u0e22","syc":"\u0e0b\u0e35\u0e40\u0e23\u0e35\u0e22\u0e41\u0e1a\u0e1a\u0e14\u0e31\u0e49\u0e07\u0e40\u0e14\u0e34\u0e21","su":"\u0e0b\u0e38\u0e19\u0e14\u0e32","suk":"\u0e0b\u0e39\u0e04\u0e39\u0e21\u0e32","sus":"\u0e0b\u0e39\u0e0b\u0e39","zun":"\u0e0b\u0e39\u0e19\u0e34","sux":"\u0e0b\u0e39\u0e40\u0e21\u0e2d","srn":"\u0e0b\u0e39\u0e23\u0e34\u0e19\u0e32\u0e40\u0e21","zu":"\u0e0b\u0e39\u0e25\u0e39","seh":"\u0e40\u0e0b\u0e19\u0e32","zen":"\u0e40\u0e0b\u0e19\u0e32\u0e01\u0e32","see":"\u0e40\u0e0b\u0e19\u0e34\u0e01\u0e32","ceb":"\u0e40\u0e0b\u0e1a\u0e39","sei":"\u0e40\u0e0b\u0e23\u0e35","srr":"\u0e40\u0e0b\u0e41\u0e23\u0e23\u0e4c","sel":"\u0e40\u0e0b\u0e25\u0e04\u0e38\u0e1b","sly":"\u0e40\u0e0b\u0e25\u0e32\u0e22\u0e32\u0e23\u0e4c","zea":"\u0e40\u0e0b\u0e41\u0e25\u0e19\u0e14\u0e4c","sr":"\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e40\u0e1a\u0e35\u0e22","sh":"\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e42\u0e1a-\u0e42\u0e04\u0e23\u0e40\u0e2d\u0e40\u0e0a\u0e35\u0e22","tkr":"\u0e41\u0e0b\u0e04\u0e40\u0e0b\u0e2d\u0e23\u0e4c","sbp":"\u0e41\u0e0b\u0e07\u0e01\u0e39","sg":"\u0e41\u0e0b\u0e07\u0e42\u0e01","saq":"\u0e41\u0e0b\u0e21\u0e1a\u0e39\u0e23\u0e39","xog":"\u0e42\u0e0b\u0e01\u0e32","st":"\u0e42\u0e0b\u0e42\u0e17\u0e43\u0e15\u0e49","nso":"\u0e42\u0e0b\u0e42\u0e17\u0e40\u0e2b\u0e19\u0e37\u0e2d","snk":"\u0e42\u0e0b\u0e19\u0e35\u0e19\u0e40\u0e01","so":"\u0e42\u0e0b\u0e21\u0e32\u0e25\u0e35","szl":"\u0e44\u0e0b\u0e25\u0e35\u0e40\u0e0b\u0e35\u0e22","sli":"\u0e44\u0e0b\u0e25\u0e35\u0e40\u0e0b\u0e35\u0e22\u0e15\u0e2d\u0e19\u0e25\u0e48\u0e32\u0e07","ja":"\u0e0d\u0e35\u0e48\u0e1b\u0e38\u0e48\u0e19","doi":"\u0e42\u0e11\u0e04\u0e23\u0e35","ng":"\u0e14\u0e2d\u0e07\u0e01\u0e32","nl":"\u0e14\u0e31\u0e15\u0e0a\u0e4c","dum":"\u0e14\u0e31\u0e15\u0e0a\u0e4c\u0e01\u0e25\u0e32\u0e07","dua":"\u0e14\u0e31\u0e27\u0e25\u0e32","dak":"\u0e14\u0e32\u0e42\u0e01\u0e17\u0e32","dzg":"\u0e14\u0e32\u0e0b\u0e32\u0e01\u0e32","dar":"\u0e14\u0e32\u0e23\u0e4c\u0e01\u0e34\u0e19","gbz":"\u0e14\u0e32\u0e23\u0e35\u0e42\u0e0b\u0e42\u0e23\u0e2d\u0e31\u0e2a\u0e40\u0e15\u0e2d\u0e23\u0e4c","din":"\u0e14\u0e34\u0e07\u0e01\u0e32","dyu":"\u0e14\u0e34\u0e27\u0e25\u0e32","dtp":"\u0e14\u0e39\u0e0b\u0e38\u0e19\u0e01\u0e25\u0e32\u0e07","da":"\u0e40\u0e14\u0e19\u0e21\u0e32\u0e23\u0e4c\u0e01","del":"\u0e40\u0e14\u0e25\u0e32\u0e41\u0e27\u0e23\u0e4c","dgr":"\u0e42\u0e14\u0e01\u0e23\u0e34\u0e1a","to":"\u0e15\u0e2d\u0e07\u0e01\u0e32","ttt":"\u0e15\u0e31\u0e15\u0e21\u0e38\u0e2a\u0e25\u0e34\u0e21","twq":"\u0e15\u0e31\u0e2a\u0e0b\u0e32\u0e27\u0e31\u0e04","tl":"\u0e15\u0e32\u0e01\u0e32\u0e25\u0e47\u0e2d\u0e01","tt":"\u0e15\u0e32\u0e15\u0e32\u0e23\u0e4c","ty":"\u0e15\u0e32\u0e2e\u0e34\u0e15\u0e35","ti":"\u0e15\u0e34\u0e01\u0e23\u0e34\u0e0d\u0e0d\u0e32","tig":"\u0e15\u0e35\u0e40\u0e01\u0e23","tr":"\u0e15\u0e38\u0e23\u0e01\u0e35","crh":"\u0e15\u0e38\u0e23\u0e01\u0e35\u0e44\u0e04\u0e23\u0e40\u0e21\u0e35\u0e22","ota":"\u0e15\u0e38\u0e23\u0e01\u0e35\u0e2d\u0e2d\u0e15\u0e42\u0e15\u0e21\u0e31\u0e19","tru":"\u0e15\u0e39\u0e42\u0e23\u0e42\u0e22","tcy":"\u0e15\u0e39\u0e25\u0e39","tyv":"\u0e15\u0e39\u0e27\u0e32","tvl":"\u0e15\u0e39\u0e27\u0e32\u0e25\u0e39","teo":"\u0e40\u0e15\u0e42\u0e0b","tet":"\u0e40\u0e15\u0e15\u0e38\u0e21","te":"\u0e40\u0e15\u0e25\u0e39\u0e01\u0e39","tk":"\u0e40\u0e15\u0e34\u0e23\u0e4c\u0e01\u0e40\u0e21\u0e19\u0e34\u0e2a\u0e16\u0e32\u0e19","tkl":"\u0e42\u0e15\u0e40\u0e01\u0e40\u0e25\u0e32","ta":"\u0e17\u0e21\u0e34\u0e2c","tli":"\u0e17\u0e25\u0e34\u0e07\u0e01\u0e34\u0e15","tw":"\u0e17\u0e27\u0e34","tpi":"\u0e17\u0e47\u0e2d\u0e01\u0e1e\u0e34\u0e0b\u0e34\u0e19","tg":"\u0e17\u0e32\u0e08\u0e34\u0e01","shi":"\u0e17\u0e32\u0e40\u0e0a\u0e25\u0e35\u0e2b\u0e4c\u0e17","tmh":"\u0e17\u0e32\u0e21\u0e32\u0e40\u0e0a\u0e01","zgh":"\u0e17\u0e32\u0e21\u0e32\u0e44\u0e0b\u0e15\u0e4c\u0e42\u0e21\u0e23\u0e47\u0e2d\u0e01\u0e42\u0e01\u0e21\u0e32\u0e15\u0e23\u0e10\u0e32\u0e19","tzm":"\u0e17\u0e32\u0e21\u0e32\u0e44\u0e0b\u0e15\u0e4c\u0e41\u0e2d\u0e15\u0e25\u0e32\u0e2a\u0e01\u0e25\u0e32\u0e07","trv":"\u0e17\u0e32\u0e42\u0e23\u0e42\u0e01","tly":"\u0e17\u0e32\u0e25\u0e34\u0e0a","bo":"\u0e17\u0e34\u0e40\u0e1a\u0e15","tiv":"\u0e17\u0e34\u0e1f","tem":"\u0e17\u0e34\u0e21\u0e40\u0e19","kcg":"\u0e17\u0e35\u0e41\u0e22\u0e1b","tum":"\u0e17\u0e38\u0e21\u0e1a\u0e39\u0e01\u0e32","ter":"\u0e40\u0e17\u0e40\u0e23\u0e42\u0e19","dav":"\u0e44\u0e17\u0e17\u0e32","th":"\u0e44\u0e17\u0e22","shn":"\u0e44\u0e17\u0e43\u0e2b\u0e0d\u0e48","dv":"\u0e18\u0e34\u0e40\u0e27\u0e2b\u0e34","nzi":"\u0e19\u0e0b\u0e34\u0e21\u0e32","no":"\u0e19\u0e2d\u0e23\u0e4c\u0e40\u0e27\u0e22\u0e4c","nn":"\u0e19\u0e2d\u0e23\u0e4c\u0e40\u0e27\u0e22\u0e4c\u0e19\u0e35\u0e19\u0e2d\u0e2a\u0e01\u0e4c","nb":"\u0e19\u0e2d\u0e23\u0e4c\u0e40\u0e27\u0e22\u0e4c\u0e1a\u0e38\u0e04\u0e21\u0e2d\u0e25","non":"\u0e19\u0e2d\u0e23\u0e4c\u0e2a\u0e42\u0e1a\u0e23\u0e32\u0e13","nap":"\u0e19\u0e32\u0e42\u0e1b\u0e25\u0e35","naq":"\u0e19\u0e32\u0e21\u0e32","nv":"\u0e19\u0e32\u0e27\u0e32\u0e42\u0e2e","na":"\u0e19\u0e32\u0e2d\u0e39\u0e23\u0e39","nyo":"\u0e19\u0e34\u0e42\u0e2d\u0e42\u0e23","nia":"\u0e19\u0e35\u0e2d\u0e31\u0e2a","niu":"\u0e19\u0e35\u0e2d\u0e39","ne":"\u0e40\u0e19\u0e1b\u0e32\u0e25","new":"\u0e40\u0e19\u0e27\u0e32\u0e23\u0e4c","nwc":"\u0e40\u0e19\u0e27\u0e32\u0e23\u0e4c\u0e14\u0e31\u0e49\u0e07\u0e40\u0e14\u0e34\u0e21","nyn":"\u0e40\u0e19\u0e35\u0e22\u0e19\u0e42\u0e01\u0e40\u0e25","ny":"\u0e40\u0e19\u0e35\u0e22\u0e19\u0e08\u0e32","nym":"\u0e40\u0e19\u0e35\u0e22\u0e21\u0e40\u0e27\u0e0b\u0e35","nus":"\u0e40\u0e19\u0e37\u0e2d\u0e23\u0e4c","nog":"\u0e42\u0e19\u0e44\u0e01","nov":"\u0e42\u0e19\u0e40\u0e27\u0e35\u0e22\u0e25","tog":"\u0e44\u0e19\u0e2d\u0e30\u0e0b\u0e32\u0e15\u0e2d\u0e07\u0e01\u0e32","brh":"\u0e1a\u0e23\u0e32\u0e2e\u0e38\u0e22","byn":"\u0e1a\u0e25\u0e34\u0e19","zbl":"\u0e1a\u0e25\u0e34\u0e2a\u0e0b\u0e34\u0e21\u0e42\u0e1a\u0e25\u0e2a\u0e4c","tn":"\u0e1a\u0e2d\u0e15\u0e2a\u0e27\u0e32\u0e19\u0e32","bs":"\u0e1a\u0e2d\u0e2a\u0e40\u0e19\u0e35\u0e22","bqi":"\u0e1a\u0e31\u0e01\u0e15\u0e34\u0e22\u0e32\u0e23\u0e35","ba":"\u0e1a\u0e31\u0e0a\u0e04\u0e35\u0e23\u0e4c","bjn":"\u0e1a\u0e31\u0e19\u0e08\u0e32\u0e23\u0e4c","bm":"\u0e1a\u0e31\u0e21\u0e1a\u0e32\u0e23\u0e32","bg":"\u0e1a\u0e31\u0e25\u0e41\u0e01\u0e40\u0e23\u0e35\u0e22","eu":"\u0e1a\u0e31\u0e2a\u0e40\u0e01","bbc":"\u0e1a\u0e32\u0e15\u0e31\u0e01\u0e42\u0e17\u0e1a\u0e32","bfd":"\u0e1a\u0e32\u0e1f\u0e31\u0e15","ksf":"\u0e1a\u0e32\u0e40\u0e1f\u0e35\u0e22","bax":"\u0e1a\u0e32\u0e21\u0e31\u0e19","pi":"\u0e1a\u0e32\u0e25\u0e35","bal":"\u0e1a\u0e32\u0e25\u0e39\u0e0a\u0e34","bar":"\u0e1a\u0e32\u0e27\u0e32\u0e40\u0e23\u0e35\u0e22","bas":"\u0e1a\u0e32\u0e2a\u0e32","ban":"\u0e1a\u0e32\u0e2b\u0e25\u0e35","bik":"\u0e1a\u0e34\u0e01\u0e2d\u0e25","bin":"\u0e1a\u0e34\u0e19\u0e35","bi":"\u0e1a\u0e34\u0e2a\u0e25\u0e32\u0e21\u0e32","rn":"\u0e1a\u0e38\u0e23\u0e38\u0e19\u0e14\u0e35","bug":"\u0e1a\u0e39\u0e01\u0e34\u0e2a","bua":"\u0e1a\u0e39\u0e40\u0e23\u0e35\u0e22\u0e15","bum":"\u0e1a\u0e39\u0e25\u0e39","bn":"\u0e40\u0e1a\u0e07\u0e01\u0e32\u0e25\u0e35","bej":"\u0e40\u0e1a\u0e08\u0e32","bew":"\u0e40\u0e1a\u0e15\u0e32\u0e27\u0e35","bez":"\u0e40\u0e1a\u0e19\u0e32","bem":"\u0e40\u0e1a\u0e21\u0e1a\u0e32","br":"\u0e40\u0e1a\u0e23\u0e15\u0e31\u0e19","be":"\u0e40\u0e1a\u0e25\u0e32\u0e23\u0e38\u0e2a","prg":"\u0e1b\u0e23\u0e31\u0e2a\u0e40\u0e0b\u0e35\u0e22","pal":"\u0e1b\u0e30\u0e2b\u0e4c\u0e25\u0e32\u0e27\u0e35","pa":"\u0e1b\u0e31\u0e0d\u0e08\u0e32\u0e1a","pam":"\u0e1b\u0e31\u0e21\u0e1b\u0e32\u0e07\u0e32","pag":"\u0e1b\u0e32\u0e07\u0e32\u0e0b\u0e35\u0e19\u0e31\u0e19","pap":"\u0e1b\u0e32\u0e40\u0e1b\u0e35\u0e22\u0e40\u0e21\u0e19\u0e42\u0e15","pau":"\u0e1b\u0e32\u0e40\u0e25\u0e32","pcd":"\u0e1b\u0e34\u0e01\u0e32\u0e23\u0e4c","fa":"\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e35\u0e22","peo":"\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e35\u0e22\u0e42\u0e1a\u0e23\u0e32\u0e13","pt":"\u0e42\u0e1b\u0e23\u0e15\u0e38\u0e40\u0e01\u0e2a","pt_BR":"\u0e42\u0e1b\u0e23\u0e15\u0e38\u0e40\u0e01\u0e2a - \u0e1a\u0e23\u0e32\u0e0b\u0e34\u0e25","pt_PT":"\u0e42\u0e1b\u0e23\u0e15\u0e38\u0e40\u0e01\u0e2a - \u0e22\u0e38\u0e42\u0e23\u0e1b","pro":"\u0e42\u0e1b\u0e23\u0e27\u0e2d\u0e07\u0e0b\u0e32\u0e25\u0e42\u0e1a\u0e23\u0e32\u0e13","pl":"\u0e42\u0e1b\u0e41\u0e25\u0e19\u0e14\u0e4c","fr":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a","frm":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a\u0e01\u0e25\u0e32\u0e07","frc":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a\u0e01\u0e32\u0e0c\u0e47\u0e2d\u0e07","fro":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a\u0e42\u0e1a\u0e23\u0e32\u0e13","fr_CH":"\u0e1d\u0e23\u0e31\u0e48\u0e07\u0e40\u0e28\u0e2a (\u0e2a\u0e27\u0e34\u0e2a)","bfq":"\u0e1e\u0e17\u0e04\u0e30","my":"\u0e1e\u0e21\u0e48\u0e32","pnt":"\u0e1e\u0e2d\u0e19\u0e15\u0e34\u0e01","pon":"\u0e1e\u0e2d\u0e2b\u0e4c\u0e19\u0e40\u0e1e","bra":"\u0e1e\u0e31\u0e23\u0e0a","ps":"\u0e1e\u0e32\u0e0a\u0e15\u0e39","bpy":"\u0e1e\u0e34\u0e28\u0e19\u0e38\u0e1b\u0e23\u0e34\u0e22\u0e30","pms":"\u0e1e\u0e35\u0e14\u0e21\u0e2d\u0e19\u0e15\u0e4c","pdt":"\u0e40\u0e1e\u0e25\u0e32\u0e17\u0e4c\u0e14\u0e34\u0e0a","brx":"\u0e42\u0e1e\u0e42\u0e11","gur":"\u0e1f\u0e23\u0e32\u0e1f\u0e23\u0e32","fy":"\u0e1f\u0e23\u0e34\u0e40\u0e0b\u0e35\u0e22\u0e19\u0e15\u0e30\u0e27\u0e31\u0e19\u0e15\u0e01","frs":"\u0e1f\u0e23\u0e34\u0e40\u0e0b\u0e35\u0e22\u0e19\u0e15\u0e30\u0e27\u0e31\u0e19\u0e2d\u0e2d\u0e01","frr":"\u0e1f\u0e23\u0e34\u0e40\u0e0b\u0e35\u0e22\u0e19\u0e40\u0e2b\u0e19\u0e37\u0e2d","stq":"\u0e1f\u0e23\u0e35\u0e40\u0e0b\u0e35\u0e22\u0e19\u0e0b\u0e31\u0e17\u0e40\u0e18\u0e2d\u0e23\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","fur":"\u0e1f\u0e23\u0e39\u0e25\u0e35","fan":"\u0e1f\u0e2d\u0e07","fon":"\u0e1f\u0e2d\u0e19","fat":"\u0e1f\u0e31\u0e19\u0e15\u0e34","fj":"\u0e1f\u0e34\u0e08\u0e34","fi":"\u0e1f\u0e34\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c","fit":"\u0e1f\u0e34\u0e19\u0e41\u0e25\u0e19\u0e14\u0e4c\u0e17\u0e2d\u0e23\u0e4c\u0e40\u0e19\u0e14\u0e32\u0e40\u0e25\u0e47\u0e19","phn":"\u0e1f\u0e34\u0e19\u0e34\u0e40\u0e0a\u0e35\u0e22","fil":"\u0e1f\u0e34\u0e25\u0e34\u0e1b\u0e1b\u0e34\u0e19\u0e2a\u0e4c","ff":"\u0e1f\u0e39\u0e25\u0e32\u0e2e\u0e4c","nl_BE":"\u0e40\u0e1f\u0e25\u0e21\u0e34\u0e0a","vls":"\u0e40\u0e1f\u0e25\u0e21\u0e34\u0e0a\u0e15\u0e30\u0e27\u0e31\u0e19\u0e15\u0e01","fo":"\u0e41\u0e1f\u0e42\u0e23","und":"\u0e20\u0e32\u0e29\u0e32\u0e17\u0e35\u0e48\u0e44\u0e21\u0e48\u0e23\u0e39\u0e49\u0e08\u0e31\u0e01","ase":"\u0e20\u0e32\u0e29\u0e32\u0e21\u0e37\u0e2d\u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e31\u0e19","bho":"\u0e42\u0e20\u0e0a\u0e1b\u0e38\u0e23\u0e35","mag":"\u0e21\u0e04\u0e2b\u0e35","hmn":"\u0e21\u0e49\u0e07","mni":"\u0e21\u0e13\u0e35\u0e1b\u0e38\u0e23\u0e30","mye":"\u0e21\u0e22\u0e35\u0e19","mr":"\u0e21\u0e23\u0e32\u0e10\u0e35","mdf":"\u0e21\u0e2d\u0e04\u0e0a\u0e32","lol":"\u0e21\u0e2d\u0e07\u0e42\u0e01","mn":"\u0e21\u0e2d\u0e07\u0e42\u0e01\u0e40\u0e25\u0e35\u0e22","mfe":"\u0e21\u0e2d\u0e23\u0e34\u0e2a\u0e40\u0e22\u0e19","ro_MD":"\u0e21\u0e2d\u0e25\u0e42\u0e14\u0e27\u0e32","mt":"\u0e21\u0e2d\u0e25\u0e15\u0e32","mua":"\u0e21\u0e31\u0e19\u0e14\u0e31\u0e07","man":"\u0e21\u0e31\u0e19\u0e14\u0e34\u0e07\u0e01\u0e32","mgh":"\u0e21\u0e32\u0e01\u0e31\u0e27\u0e27\u0e32-\u0e21\u0e35\u0e17\u0e42\u0e17","mak":"\u0e21\u0e32\u0e01\u0e32\u0e0b\u0e32\u0e23\u0e4c","kde":"\u0e21\u0e32\u0e04\u0e2d\u0e19\u0e40\u0e14","jmc":"\u0e21\u0e32\u0e0a\u0e32\u0e40\u0e21","mzn":"\u0e21\u0e32\u0e0b\u0e31\u0e19\u0e14\u0e32\u0e23\u0e32\u0e19\u0e35","mk":"\u0e21\u0e32\u0e0b\u0e34\u0e42\u0e14\u0e40\u0e19\u0e35\u0e22","mas":"\u0e21\u0e32\u0e44\u0e0b","mad":"\u0e21\u0e32\u0e14\u0e39\u0e23\u0e32","gv":"\u0e21\u0e32\u0e19\u0e0b\u0e4c","mdr":"\u0e21\u0e32\u0e19\u0e14\u0e32\u0e23\u0e4c","mde":"\u0e21\u0e32\u0e1a\u0e32","maf":"\u0e21\u0e32\u0e1f\u0e32","mh":"\u0e21\u0e32\u0e23\u0e4c\u0e41\u0e0a\u0e25\u0e25\u0e34\u0e2a","mwr":"\u0e21\u0e32\u0e23\u0e27\u0e32\u0e11\u0e35","chm":"\u0e21\u0e32\u0e23\u0e35","mrj":"\u0e21\u0e32\u0e23\u0e35\u0e15\u0e30\u0e27\u0e31\u0e19\u0e15\u0e01","mg":"\u0e21\u0e32\u0e25\u0e32\u0e01\u0e32\u0e0b\u0e35","ml":"\u0e21\u0e32\u0e25\u0e32\u0e22\u0e32\u0e25\u0e31\u0e21","ms":"\u0e21\u0e32\u0e40\u0e25\u0e22\u0e4c","mic":"\u0e21\u0e34\u0e01\u0e41\u0e21\u0e01","min":"\u0e21\u0e35\u0e19\u0e31\u0e07\u0e01\u0e32\u0e40\u0e1a\u0e32","mwl":"\u0e21\u0e35\u0e23\u0e31\u0e19\u0e14\u0e32","xmf":"\u0e40\u0e21\u0e40\u0e01\u0e23\u0e40\u0e25\u0e35\u0e22","byv":"\u0e40\u0e21\u0e14\u0e38\u0e21\u0e1a\u0e32","mgo":"\u0e40\u0e21\u0e15\u0e32","men":"\u0e40\u0e21\u0e19\u0e40\u0e14","mwv":"\u0e40\u0e21\u0e47\u0e19\u0e15\u0e32\u0e44\u0e27","vmf":"\u0e40\u0e21\u0e19-\u0e1f\u0e23\u0e32\u0e19\u0e42\u0e01\u0e40\u0e19\u0e35\u0e22","mer":"\u0e40\u0e21\u0e23\u0e39","mi":"\u0e40\u0e21\u0e32\u0e23\u0e35","mnc":"\u0e41\u0e21\u0e19\u0e08\u0e39","mos":"\u0e42\u0e21\u0e0b\u0e35","moh":"\u0e42\u0e21\u0e2e\u0e2d\u0e27\u0e4c\u0e01","mai":"\u0e44\u0e21\u0e16\u0e34\u0e25\u0e35","zxx":"\u0e44\u0e21\u0e48\u0e21\u0e35\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e20\u0e32\u0e29\u0e32","yap":"\u0e22\u0e31\u0e1b","yi":"\u0e22\u0e34\u0e27","jpr":"\u0e22\u0e34\u0e27-\u0e40\u0e1b\u0e2d\u0e23\u0e4c\u0e40\u0e0b\u0e35\u0e22","jrb":"\u0e22\u0e34\u0e27-\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a","lg":"\u0e22\u0e39\u0e01\u0e31\u0e19\u0e14\u0e32","uga":"\u0e22\u0e39\u0e01\u0e32\u0e23\u0e34\u0e15","uk":"\u0e22\u0e39\u0e40\u0e04\u0e23\u0e19","esu":"\u0e22\u0e39\u0e1e\u0e34\u0e01\u0e01\u0e25\u0e32\u0e07","ybb":"\u0e40\u0e22\u0e21\u0e1a\u0e32","de":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19","nds":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e15\u0e48\u0e33 - \u0e41\u0e0b\u0e01\u0e0b\u0e2d\u0e19\u0e15\u0e48\u0e33","pfl":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e1e\u0e32\u0e25\u0e32\u0e17\u0e34\u0e40\u0e19\u0e15","pdc":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e40\u0e1e\u0e19\u0e0b\u0e34\u0e25\u0e40\u0e27\u0e40\u0e19\u0e35\u0e22","gsw":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e2a\u0e27\u0e34\u0e2a","gmh":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e2a\u0e39\u0e07\u0e01\u0e25\u0e32\u0e07","goh":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e2a\u0e39\u0e07\u0e42\u0e1a\u0e23\u0e32\u0e13","de_CH":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19\u0e2a\u0e39\u0e07 (\u0e2a\u0e27\u0e34\u0e2a)","de_AT":"\u0e40\u0e22\u0e2d\u0e23\u0e21\u0e31\u0e19 - \u0e2d\u0e2d\u0e2a\u0e40\u0e15\u0e23\u0e35\u0e22","yao":"\u0e40\u0e22\u0e49\u0e32","yav":"\u0e41\u0e22\u0e07\u0e40\u0e1a\u0e19","yo":"\u0e42\u0e22\u0e23\u0e39\u0e1a\u0e32","rw":"\u0e23\u0e27\u0e31\u0e19\u0e14\u0e32","rwk":"\u0e23\u0e27\u0e32","rof":"\u0e23\u0e2d\u0e21\u0e42\u0e1a","ru":"\u0e23\u0e31\u0e2a\u0e40\u0e0b\u0e35\u0e22","raj":"\u0e23\u0e32\u0e0a\u0e2a\u0e16\u0e32\u0e19","rap":"\u0e23\u0e32\u0e1b\u0e32\u0e19\u0e39","rar":"\u0e23\u0e32\u0e42\u0e23\u0e17\u0e2d\u0e07\u0e01\u0e32","rif":"\u0e23\u0e34\u0e1f\u0e1f\u0e34\u0e2d\u0e31\u0e19","rue":"\u0e23\u0e39\u0e0b\u0e34\u0e19","root":"\u0e23\u0e39\u0e17","rtm":"\u0e42\u0e23\u0e17\u0e39\u0e21\u0e31\u0e19","rgn":"\u0e42\u0e23\u0e21\u0e31\u0e13\u0e42\u0e0d","rom":"\u0e42\u0e23\u0e21\u0e32\u0e19\u0e35","ro":"\u0e42\u0e23\u0e21\u0e32\u0e40\u0e19\u0e35\u0e22","rm":"\u0e42\u0e23\u0e41\u0e21\u0e19\u0e0b\u0e4c","rug":"\u0e42\u0e23\u0e40\u0e27\u0e35\u0e22\u0e19\u0e32","lmo":"\u0e25\u0e2d\u0e21\u0e1a\u0e32\u0e23\u0e4c\u0e14","la":"\u0e25\u0e30\u0e15\u0e34\u0e19","lb":"\u0e25\u0e31\u0e01\u0e40\u0e0b\u0e21\u0e40\u0e1a\u0e34\u0e23\u0e4c\u0e01","ltg":"\u0e25\u0e31\u0e15\u0e40\u0e01\u0e25","lv":"\u0e25\u0e31\u0e15\u0e40\u0e27\u0e35\u0e22","lun":"\u0e25\u0e31\u0e19\u0e14\u0e32","luo":"\u0e25\u0e31\u0e27","lkt":"\u0e25\u0e32\u0e42\u0e01\u0e15\u0e32","lad":"\u0e25\u0e32\u0e14\u0e34\u0e42\u0e19","lo":"\u0e25\u0e32\u0e27","lah":"\u0e25\u0e32\u0e2e\u0e4c\u0e19\u0e14\u0e32","lij":"\u0e25\u0e34\u0e01\u0e39\u0e40\u0e23\u0e35\u0e22","lfn":"\u0e25\u0e34\u0e07\u0e01\u0e31\u0e27\u0e1f\u0e23\u0e31\u0e07\u0e01\u0e32\u0e42\u0e19\u0e27\u0e32","ln":"\u0e25\u0e34\u0e07\u0e01\u0e32\u0e25\u0e32","lt":"\u0e25\u0e34\u0e17\u0e31\u0e27\u0e40\u0e19\u0e35\u0e22","li":"\u0e25\u0e34\u0e21\u0e40\u0e1a\u0e34\u0e23\u0e4c\u0e01","liv":"\u0e25\u0e34\u0e42\u0e27\u0e40\u0e19\u0e35\u0e22","lui":"\u0e25\u0e38\u0e22\u0e40\u0e0b\u0e42\u0e19","lus":"\u0e25\u0e39\u0e44\u0e0a","lu":"\u0e25\u0e39\u0e1a\u0e32-\u0e01\u0e32\u0e15\u0e2d\u0e07\u0e01\u0e32","lua":"\u0e25\u0e39\u0e1a\u0e32-\u0e25\u0e39\u0e25\u0e31\u0e27","luy":"\u0e25\u0e39\u0e40\u0e22\u0e35\u0e22","lez":"\u0e40\u0e25\u0e0b\u0e40\u0e01\u0e35\u0e22\u0e19","lzz":"\u0e41\u0e25\u0e0b","lag":"\u0e41\u0e25\u0e19\u0e08\u0e35","lam":"\u0e41\u0e25\u0e21\u0e1a\u0e32","jbo":"\u0e42\u0e25\u0e0a\u0e1a\u0e31\u0e19","loz":"\u0e42\u0e25\u0e0b\u0e34","wae":"\u0e27\u0e31\u0e25\u0e40\u0e0b\u0e2d\u0e23\u0e4c","was":"\u0e27\u0e32\u0e42\u0e0a","guc":"\u0e27\u0e32\u0e22\u0e39","war":"\u0e27\u0e32\u0e40\u0e23\u0e22\u0e4c","wal":"\u0e27\u0e32\u0e25\u0e32\u0e42\u0e21","wa":"\u0e27\u0e32\u0e42\u0e25\u0e19\u0e35","vun":"\u0e27\u0e38\u0e19\u0e08\u0e39","ve":"\u0e40\u0e27\u0e19\u0e14\u0e32","vec":"\u0e40\u0e27\u0e40\u0e19\u0e42\u0e15\u0e49","vep":"\u0e40\u0e27\u0e1b\u0e2a\u0e4c","cy":"\u0e40\u0e27\u0e25\u0e2a\u0e4c","vi":"\u0e40\u0e27\u0e35\u0e22\u0e14\u0e19\u0e32\u0e21","vot":"\u0e42\u0e27\u0e17\u0e34\u0e01","vro":"\u0e42\u0e27\u0e42\u0e23","wo":"\u0e42\u0e27\u0e25\u0e2d\u0e1f","vo":"\u0e42\u0e27\u0e25\u0e32\u0e1e\u0e36\u0e04","vai":"\u0e44\u0e27","sco":"\u0e2a\u0e01\u0e2d\u0e15\u0e2a\u0e4c","gd":"\u0e2a\u0e01\u0e2d\u0e15\u0e2a\u0e4c\u0e01\u0e32\u0e25\u0e34\u0e01","es":"\u0e2a\u0e40\u0e1b\u0e19","es_ES":"\u0e2a\u0e40\u0e1b\u0e19 (\u0e22\u0e38\u0e42\u0e23\u0e1b)","den":"\u0e2a\u0e40\u0e25\u0e27\u0e35","sk":"\u0e2a\u0e42\u0e25\u0e27\u0e31\u0e01","sl":"\u0e2a\u0e42\u0e25\u0e27\u0e35\u0e40\u0e19\u0e35\u0e22","ss":"\u0e2a\u0e27\u0e32\u0e15\u0e34","sw":"\u0e2a\u0e27\u0e32\u0e2e\u0e35\u0e25\u0e35","swc":"\u0e2a\u0e27\u0e32\u0e2e\u0e35\u0e25\u0e35-\u0e04\u0e2d\u0e07\u0e42\u0e01","sv":"\u0e2a\u0e27\u0e35\u0e40\u0e14\u0e19","sat":"\u0e2a\u0e31\u0e19\u0e15\u0e32\u0e25\u0e35","sa":"\u0e2a\u0e31\u0e19\u0e2a\u0e01\u0e24\u0e15","bla":"\u0e2a\u0e34\u0e01\u0e2a\u0e34\u0e01\u0e32","si":"\u0e2a\u0e34\u0e07\u0e2b\u0e25","sd":"\u0e2a\u0e34\u0e19\u0e18\u0e38","ii":"\u0e40\u0e2a\u0e09\u0e27\u0e19\u0e22\u0e34","saz":"\u0e40\u0e2a\u0e32\u0e23\u0e32\u0e29\u0e0f\u0e23\u0e4c","mul":"\u0e2b\u0e25\u0e32\u0e22\u0e20\u0e32\u0e29\u0e32","yrl":"\u0e40\u0e2b\u0e07\u0e07\u0e01\u0e32\u0e15\u0e38","arc":"\u0e2d\u0e23\u0e32\u0e40\u0e21\u0e2d\u0e34\u0e01","sam":"\u0e2d\u0e23\u0e32\u0e40\u0e21\u0e2d\u0e34\u0e01\u0e0b\u0e32\u0e21\u0e32\u0e40\u0e23\u0e35\u0e22","awa":"\u0e2d\u0e27\u0e18\u0e35","ae":"\u0e2d\u0e40\u0e27\u0e2a\u0e15\u0e30","oc":"\u0e2d\u0e47\u0e2d\u0e01\u0e0b\u0e34\u0e15\u0e31\u0e19","os":"\u0e2d\u0e2d\u0e2a\u0e40\u0e0b\u0e40\u0e15\u0e35\u0e22","ady":"\u0e2d\u0e30\u0e14\u0e37\u0e22\u0e40\u0e01","aa":"\u0e2d\u0e30\u0e1f\u0e32\u0e23\u0e4c","akk":"\u0e2d\u0e31\u0e01\u0e01\u0e32\u0e14","agq":"\u0e2d\u0e31\u0e01\u0e40\u0e2e\u0e21","en":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29","enm":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29\u0e01\u0e25\u0e32\u0e07","jam":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29\u0e04\u0e25\u0e35\u0e42\u0e2d\u0e25\u0e08\u0e32\u0e40\u0e21\u0e01\u0e32","en_CA":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29 - \u0e41\u0e04\u0e19\u0e32\u0e14\u0e32","ang":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29\u0e42\u0e1a\u0e23\u0e32\u0e13","en_GB":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29 - \u0e2a\u0e2b\u0e23\u0e32\u0e0a\u0e2d\u0e32\u0e13\u0e32\u0e08\u0e31\u0e01\u0e23","en_US":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29 - \u0e2d\u0e40\u0e21\u0e23\u0e34\u0e01\u0e31\u0e19","en_AU":"\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29 - \u0e2d\u0e2d\u0e2a\u0e40\u0e15\u0e23\u0e40\u0e25\u0e35\u0e22","anp":"\u0e2d\u0e31\u0e07\u0e04\u0e34\u0e01\u0e32","ab":"\u0e2d\u0e31\u0e1a\u0e04\u0e32\u0e0b","am":"\u0e2d\u0e31\u0e21\u0e2e\u0e32\u0e23\u0e32","alt":"\u0e2d\u0e31\u0e25\u0e44\u0e15\u0e43\u0e15\u0e49","ast":"\u0e2d\u0e31\u0e2a\u0e15\u0e39\u0e40\u0e23\u0e35\u0e22\u0e2a","as":"\u0e2d\u0e31\u0e2a\u0e2a\u0e31\u0e21","ak":"\u0e2d\u0e32\u0e04\u0e31\u0e19","bss":"\u0e2d\u0e32\u0e42\u0e04\u0e0b\u0e35","ach":"\u0e2d\u0e32\u0e42\u0e04\u0e25\u0e34","ace":"\u0e2d\u0e32\u0e40\u0e08\u0e30\u0e2b\u0e4c","asa":"\u0e2d\u0e32\u0e0b\u0e39","az":"\u0e2d\u0e32\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e44\u0e1a\u0e08\u0e32\u0e19","azb":"\u0e2d\u0e32\u0e40\u0e0b\u0e2d\u0e23\u0e4c\u0e44\u0e1a\u0e08\u0e32\u0e19\u0e43\u0e15\u0e49","ada":"\u0e2d\u0e32\u0e41\u0e14\u0e07\u0e21\u0e35","frp":"\u0e2d\u0e32\u0e23\u0e4c\u0e1e\u0e34\u0e15\u0e32","hy":"\u0e2d\u0e32\u0e23\u0e4c\u0e40\u0e21\u0e40\u0e19\u0e35\u0e22","an":"\u0e2d\u0e32\u0e23\u0e32\u0e01\u0e2d\u0e19","arp":"\u0e2d\u0e32\u0e23\u0e32\u0e1b\u0e32\u0e42\u0e2e","arw":"\u0e2d\u0e32\u0e23\u0e32\u0e27\u0e31\u0e01","arn":"\u0e2d\u0e32\u0e40\u0e23\u0e32\u0e04\u0e32\u0e40\u0e19\u0e35\u0e22\u0e19","aro":"\u0e2d\u0e32\u0e40\u0e23\u0e32\u0e19\u0e32","rup":"\u0e2d\u0e32\u0e42\u0e23\u0e21\u0e32\u0e40\u0e19\u0e35\u0e22\u0e19","ale":"\u0e2d\u0e32\u0e25\u0e34\u0e27\u0e15\u0e4c","njo":"\u0e2d\u0e4b\u0e32\u0e27\u0e19\u0e32\u0e01\u0e32","av":"\u0e2d\u0e32\u0e27\u0e32\u0e23\u0e4c","ar":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a","shu":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a-\u0e0a\u0e32\u0e14","aeb":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e15\u0e39\u0e19\u0e34\u0e40\u0e0b\u0e35\u0e22","arz":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e1e\u0e37\u0e49\u0e19\u0e40\u0e21\u0e37\u0e2d\u0e07\u0e2d\u0e35\u0e22\u0e34\u0e1b\u0e15\u0e4c","ar_001":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e21\u0e32\u0e15\u0e23\u0e10\u0e32\u0e19\u0e2a\u0e21\u0e31\u0e22\u0e43\u0e2b\u0e21\u0e48","ary":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e42\u0e21\u0e23\u0e47\u0e2d\u0e01\u0e42\u0e01","arq":"\u0e2d\u0e32\u0e2b\u0e23\u0e31\u0e1a\u0e41\u0e2d\u0e25\u0e08\u0e35\u0e40\u0e23\u0e35\u0e22","ig":"\u0e2d\u0e34\u0e01\u0e42\u0e1a","it":"\u0e2d\u0e34\u0e15\u0e32\u0e25\u0e35","inh":"\u0e2d\u0e34\u0e19\u0e01\u0e38\u0e0a","izh":"\u0e2d\u0e34\u0e19\u0e40\u0e01\u0e23\u0e35\u0e22\u0e19","id":"\u0e2d\u0e34\u0e19\u0e42\u0e14\u0e19\u0e35\u0e40\u0e0a\u0e35\u0e22","ia":"\u0e2d\u0e34\u0e19\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e25\u0e34\u0e07\u0e01\u0e31\u0e27","ie":"\u0e2d\u0e34\u0e19\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e25\u0e34\u0e07\u0e01\u0e34\u0e27","iu":"\u0e2d\u0e34\u0e19\u0e38\u0e01\u0e15\u0e34\u0e15\u0e38\u0e15","iba":"\u0e2d\u0e34\u0e1a\u0e32\u0e19","ibb":"\u0e2d\u0e34\u0e1a\u0e34\u0e1a\u0e34\u0e42\u0e2d","eka":"\u0e2d\u0e35\u0e01\u0e32\u0e08\u0e38\u0e01","io":"\u0e2d\u0e35\u0e42\u0e14","ik":"\u0e2d\u0e35\u0e19\u0e39\u0e40\u0e1b\u0e35\u0e22\u0e01","efi":"\u0e2d\u0e35\u0e1f\u0e34\u0e01","egy":"\u0e2d\u0e35\u0e22\u0e34\u0e1b\u0e15\u0e4c\u0e42\u0e1a\u0e23\u0e32\u0e13","elx":"\u0e2d\u0e35\u0e25\u0e32\u0e44\u0e21\u0e15\u0e4c","ilo":"\u0e2d\u0e35\u0e42\u0e25\u0e42\u0e01","ewo":"\u0e2d\u0e35\u0e27\u0e31\u0e19\u0e42\u0e14","jgo":"\u0e2d\u0e36\u0e19\u0e01\u0e2d\u0e21\u0e1a\u0e32","uz":"\u0e2d\u0e38\u0e0b\u0e40\u0e1a\u0e01","udm":"\u0e2d\u0e38\u0e14\u0e21\u0e39\u0e23\u0e4c\u0e15","umb":"\u0e2d\u0e38\u0e21\u0e1a\u0e38\u0e19\u0e14\u0e39","ug":"\u0e2d\u0e38\u0e22\u0e01\u0e31\u0e27","ur":"\u0e2d\u0e39\u0e23\u0e14\u0e39","ext":"\u0e40\u0e2d\u0e01\u0e0b\u0e4c\u0e40\u0e15\u0e23\u0e21\u0e32\u0e14\u0e39\u0e23\u0e32","nqo":"\u0e40\u0e2d\u0e47\u0e19\u0e42\u0e01","nr":"\u0e40\u0e2d\u0e47\u0e19\u0e40\u0e14\u0e40\u0e1a\u0e40\u0e25\u0e43\u0e15\u0e49","nd":"\u0e40\u0e2d\u0e47\u0e19\u0e40\u0e14\u0e40\u0e1a\u0e40\u0e25\u0e40\u0e2b\u0e19\u0e37\u0e2d","ebu":"\u0e40\u0e2d\u0e47\u0e21\u0e1a\u0e39","egl":"\u0e40\u0e2d\u0e21\u0e35\u0e40\u0e25\u0e35\u0e22","ee":"\u0e40\u0e2d\u0e40\u0e27","et":"\u0e40\u0e2d\u0e2a\u0e42\u0e15\u0e40\u0e19\u0e35\u0e22","eo":"\u0e40\u0e2d\u0e2a\u0e40\u0e1b\u0e2d\u0e23\u0e31\u0e19\u0e42\u0e15","myv":"\u0e40\u0e2d\u0e35\u0e22\u0e23\u0e4c\u0e0b\u0e22\u0e32","cch":"\u0e41\u0e2d\u0e15\u0e41\u0e0b\u0e21","af":"\u0e41\u0e2d\u0e1f\u0e23\u0e34\u0e01\u0e32\u0e19\u0e2a\u0e4c","afh":"\u0e41\u0e2d\u0e1f\u0e23\u0e34\u0e2e\u0e35\u0e25\u0e35","sq":"\u0e41\u0e2d\u0e25\u0e40\u0e1a\u0e40\u0e19\u0e35\u0e22","akz":"\u0e41\u0e2d\u0e25\u0e30\u0e41\u0e1a\u0e21\u0e32","oj":"\u0e42\u0e2d\u0e08\u0e34\u0e1a\u0e27\u0e32","osa":"\u0e42\u0e2d\u0e0b\u0e32\u0e01\u0e35","or":"\u0e42\u0e2d\u0e23\u0e34\u0e22\u0e32","om":"\u0e42\u0e2d\u0e42\u0e23\u0e42\u0e21","is":"\u0e44\u0e2d\u0e0b\u0e4c\u0e41\u0e25\u0e19\u0e14\u0e4c","ain":"\u0e44\u0e2d\u0e19\u0e38","ay":"\u0e44\u0e2d\u0e22\u0e4c\u0e21\u0e32\u0e23\u0e32","ga":"\u0e44\u0e2d\u0e23\u0e34\u0e0a","mga":"\u0e44\u0e2d\u0e23\u0e34\u0e0a\u0e01\u0e25\u0e32\u0e07","sga":"\u0e44\u0e2d\u0e23\u0e34\u0e0a\u0e42\u0e1a\u0e23\u0e32\u0e13","hu":"\u0e2e\u0e31\u0e07\u0e01\u0e32\u0e23\u0e35","haw":"\u0e2e\u0e32\u0e27\u0e32\u0e22","hit":"\u0e2e\u0e34\u0e15\u0e44\u0e15\u0e15\u0e4c","hi":"\u0e2e\u0e34\u0e19\u0e14\u0e35","hif":"\u0e2e\u0e34\u0e19\u0e14\u0e35\u0e1f\u0e34\u0e08\u0e34","he":"\u0e2e\u0e34\u0e1a\u0e23\u0e39","ho":"\u0e2e\u0e35\u0e23\u0e35\u0e42\u0e21\u0e15\u0e39","hil":"\u0e2e\u0e35\u0e25\u0e35\u0e01\u0e31\u0e22\u0e19\u0e19","hup":"\u0e2e\u0e39\u0e1b\u0e32","ht":"\u0e40\u0e2e\u0e15\u0e34","hz":"\u0e40\u0e2e\u0e40\u0e23\u0e42\u0e23","ha":"\u0e40\u0e2e\u0e32\u0e0a\u0e32","hai":"\u0e44\u0e2e\u0e14\u0e32","fr_CA":"Canadian French","es_419":"Latin American Spanish","es_MX":"Mexican Spanish","wbp":"Warlpiri"} \ No newline at end of file diff --git a/public/intl/messages/bn-BD.json b/public/intl/messages/bn-BD.json new file mode 100644 index 00000000..8a91c167 --- /dev/null +++ b/public/intl/messages/bn-BD.json @@ -0,0 +1,832 @@ +{ + "label.accounts": [ + { + "type": 0, + "value": "অ্যাকাউন্ট" + } + ], + "label.add-account": [ + { + "type": 0, + "value": "অ্যাকাউন্ট যুক্ত করুন" + } + ], + "label.add-website": [ + { + "type": 0, + "value": "ওয়েবসাইট যুক্ত করুন" + } + ], + "label.administrator": [ + { + "type": 0, + "value": "অ্যাডমিন" + } + ], + "label.all": [ + { + "type": 0, + "value": "সবগুলো" + } + ], + "label.all-events": [ + { + "type": 0, + "value": "সবগুলো ঘটনা" + } + ], + "label.all-time": [ + { + "type": 0, + "value": "সব সময়" + } + ], + "label.all-websites": [ + { + "type": 0, + "value": "সবগুলো ওয়েবসাইট" + } + ], + "label.back": [ + { + "type": 0, + "value": "পেছনে" + } + ], + "label.cancel": [ + { + "type": 0, + "value": "বাতিল" + } + ], + "label.change-password": [ + { + "type": 0, + "value": "পাসওয়ার্ড পরিবর্তন করুন" + } + ], + "label.confirm-password": [ + { + "type": 0, + "value": "পাসওয়ার্ড নিশ্চিত করুন" + } + ], + "label.copy-to-clipboard": [ + { + "type": 0, + "value": "কপি করুন" + } + ], + "label.current-password": [ + { + "type": 0, + "value": "বর্তমান পাসওয়ার্ড" + } + ], + "label.custom-range": [ + { + "type": 0, + "value": "কাস্টম রেঞ্জ" + } + ], + "label.dashboard": [ + { + "type": 0, + "value": "ড্যাশবোর্ড" + } + ], + "label.date-range": [ + { + "type": 0, + "value": "তারিখের পরিসীমা" + } + ], + "label.default-date-range": [ + { + "type": 0, + "value": "ডিফল্ট তারিখের পরিসীমা" + } + ], + "label.delete": [ + { + "type": 0, + "value": "মুছে ফেলুন" + } + ], + "label.delete-account": [ + { + "type": 0, + "value": "অ্যাকাউন্ট মুছুন" + } + ], + "label.delete-website": [ + { + "type": 0, + "value": "ওয়েবসাইট মুছুন" + } + ], + "label.dismiss": [ + { + "type": 0, + "value": "বাতিল" + } + ], + "label.domain": [ + { + "type": 0, + "value": "ডোমেইন" + } + ], + "label.edit": [ + { + "type": 0, + "value": "সম্পাদনা করুন" + } + ], + "label.edit-account": [ + { + "type": 0, + "value": "অ্যাকাউন্ট সম্পাদনা করুন" + } + ], + "label.edit-website": [ + { + "type": 0, + "value": "ওয়েবসাইট সম্পাদনা করুন" + } + ], + "label.enable-share-url": [ + { + "type": 0, + "value": "শেয়ার ইউআরএল শেয়ার করুন" + } + ], + "label.invalid": [ + { + "type": 0, + "value": "ভুল" + } + ], + "label.invalid-domain": [ + { + "type": 0, + "value": "ভুল ডোমেন" + } + ], + "label.language": [ + { + "type": 0, + "value": "ভাষা" + } + ], + "label.last-days": [ + { + "type": 0, + "value": "শেষ " + }, + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " দিন" + } + ], + "label.last-hours": [ + { + "type": 0, + "value": "শেষ " + }, + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " ঘন্টা" + } + ], + "label.logged-in-as": [ + { + "type": 1, + "value": "username" + }, + { + "type": 0, + "value": " অ্যাকাউন্টে লগ ইন" + } + ], + "label.login": [ + { + "type": 0, + "value": "লগিন" + } + ], + "label.logout": [ + { + "type": 0, + "value": "লগ আউট" + } + ], + "label.more": [ + { + "type": 0, + "value": "আরও" + } + ], + "label.name": [ + { + "type": 0, + "value": "নাম" + } + ], + "label.new-password": [ + { + "type": 0, + "value": "নতুন পাসওয়ার্ড" + } + ], + "label.none": [ + { + "type": 0, + "value": "কিছুই না" + } + ], + "label.owner": [ + { + "type": 0, + "value": "মালিক" + } + ], + "label.password": [ + { + "type": 0, + "value": "পাসওয়ার্ড" + } + ], + "label.passwords-dont-match": [ + { + "type": 0, + "value": "পাসওয়ার্ড মেলে না" + } + ], + "label.profile": [ + { + "type": 0, + "value": "প্রোফাইল" + } + ], + "label.realtime": [ + { + "type": 0, + "value": "সরাসরি" + } + ], + "label.realtime-logs": [ + { + "type": 0, + "value": "সরাসরি লগ" + } + ], + "label.refresh": [ + { + "type": 0, + "value": "রিফ্রেশ" + } + ], + "label.required": [ + { + "type": 0, + "value": "প্রয়োজনীয়" + } + ], + "label.reset": [ + { + "type": 0, + "value": "রিসেট" + } + ], + "label.reset-website": [ + { + "type": 0, + "value": "ওয়েবসাইট রিসেট করুন" + } + ], + "label.save": [ + { + "type": 0, + "value": "সংরক্ষণ" + } + ], + "label.settings": [ + { + "type": 0, + "value": "সেটিংস" + } + ], + "label.share-url": [ + { + "type": 0, + "value": "ইউআরএল শেয়ার করুন" + } + ], + "label.single-day": [ + { + "type": 0, + "value": "একদিন" + } + ], + "label.theme": [ + { + "type": 0, + "value": "থিম" + } + ], + "label.this-month": [ + { + "type": 0, + "value": "এই মাস" + } + ], + "label.this-week": [ + { + "type": 0, + "value": "এই সপ্তাহ" + } + ], + "label.this-year": [ + { + "type": 0, + "value": "এই বছর" + } + ], + "label.timezone": [ + { + "type": 0, + "value": "সময়স্থান" + } + ], + "label.today": [ + { + "type": 0, + "value": "আজ" + } + ], + "label.tracking-code": [ + { + "type": 0, + "value": "ট্র্যাকিং কোড" + } + ], + "label.unknown": [ + { + "type": 0, + "value": "অজানা" + } + ], + "label.username": [ + { + "type": 0, + "value": "ব্যবহারকারীর নাম" + } + ], + "label.view-details": [ + { + "type": 0, + "value": "বিস্তারিত দেখুন" + } + ], + "label.websites": [ + { + "type": 0, + "value": "সবগুলো ওয়েবসাইট" + } + ], + "message.active-users": [ + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " বর্তমান " + }, + { + "offset": 0, + "options": { + "one": { + "value": [ + { + "type": 0, + "value": "visitor" + } + ] + }, + "other": { + "value": [ + { + "type": 0, + "value": "visitors" + } + ] + } + }, + "pluralType": "cardinal", + "type": 6, + "value": "x" + } + ], + "message.confirm-delete": [ + { + "type": 0, + "value": "আপনি কি নিশ্চিত যে আপনি " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " মুছতে চান?" + } + ], + "message.confirm-reset": [ + { + "type": 0, + "value": "আপনি কি নিশ্চিত যে আপনি " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " এর পরিসংখ্যান পুনরায় সেট করতে চান?" + } + ], + "message.copied": [ + { + "type": 0, + "value": "কপি হয়েছে" + } + ], + "message.delete-warning": [ + { + "type": 0, + "value": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।" + } + ], + "message.failure": [ + { + "type": 0, + "value": "কিছু ভুল হয়েছে।" + } + ], + "message.get-share-url": [ + { + "type": 0, + "value": "শেয়ার ইউআরএল" + } + ], + "message.get-tracking-code": [ + { + "type": 0, + "value": "ট্র্যাকিং কোড পান" + } + ], + "message.go-to-settings": [ + { + "type": 0, + "value": "সেটিংস এ যান" + } + ], + "message.incorrect-username-password": [ + { + "type": 0, + "value": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।" + } + ], + "message.log.visitor": [ + { + "type": 1, + "value": "country" + }, + { + "type": 0, + "value": " থেকে একজন ভিসিটর " + }, + { + "type": 1, + "value": "ব্রাউজার" + }, + { + "type": 0, + "value": ", ব্যবহার করছেন " + }, + { + "type": 1, + "value": "os" + }, + { + "type": 0, + "value": " " + }, + { + "type": 1, + "value": "device" + }, + { + "type": 0, + "value": " এর মধ্যে।" + } + ], + "message.new-version-available": [ + { + "type": 0, + "value": "নতুন সংস্করণ " + }, + { + "type": 1, + "value": "version" + }, + { + "type": 0, + "value": " পাওয়া গিয়েছে।" + } + ], + "message.no-data-available": [ + { + "type": 0, + "value": "কোন তথ্য নেই।" + } + ], + "message.no-websites-configured": [ + { + "type": 0, + "value": "কোনও ওয়েবসাইট কনফিগার করা নেই।" + } + ], + "message.page-not-found": [ + { + "type": 0, + "value": "পৃষ্ঠা খুঁজে পাওয়া যায়নি।" + } + ], + "message.powered-by": [ + { + "type": 1, + "value": "name" + }, + { + "type": 0, + "value": " দ্বারা চালিত" + } + ], + "message.reset-warning": [ + { + "type": 0, + "value": "এই ওয়েবসাইটের সমস্ত পরিসংখ্যান মুছে ফেলা হবে, তবে আপনার ট্র্যাকিং কোডটি অক্ষত থাকবে।" + } + ], + "message.save-success": [ + { + "type": 0, + "value": "সংরক্ষিত হয়েছে।" + } + ], + "message.share-url": [ + { + "type": 0, + "value": "এটি " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।" + } + ], + "message.toggle-charts": [ + { + "type": 0, + "value": "চার্ট পরিবর্তন করুন" + } + ], + "message.track-stats": [ + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " এর জন্য পরিসংখ্যানগুলি ট্র্যাক করতে, আপনার ওয়েবসাইটের " + }, + { + "type": 1, + "value": "head" + }, + { + "type": 0, + "value": " বিভাগে নিম্নলিখিত কোডটি রাখুন।" + } + ], + "message.type-delete": [ + { + "type": 0, + "value": "নিশ্চিত করতে নীচের বাক্সে " + }, + { + "type": 1, + "value": "delete" + }, + { + "type": 0, + "value": " টাইপ করুন।" + } + ], + "message.type-reset": [ + { + "type": 0, + "value": "নিশ্চিত করতে নীচের বাক্সে " + }, + { + "type": 1, + "value": "reset" + }, + { + "type": 0, + "value": " টাইপ করুন।" + } + ], + "metrics.actions": [ + { + "type": 0, + "value": "অ্যাকশনস" + } + ], + "metrics.average-visit-time": [ + { + "type": 0, + "value": "গড় পরিদর্শনের সময়" + } + ], + "metrics.bounce-rate": [ + { + "type": 0, + "value": "বহিষ্কারের হার" + } + ], + "metrics.browsers": [ + { + "type": 0, + "value": "ব্রাউজার" + } + ], + "metrics.countries": [ + { + "type": 0, + "value": "দেশ" + } + ], + "metrics.device.desktop": [ + { + "type": 0, + "value": "ডেস্কটপ" + } + ], + "metrics.device.laptop": [ + { + "type": 0, + "value": "ল্যাপটপ" + } + ], + "metrics.device.mobile": [ + { + "type": 0, + "value": "মুঠোফোন" + } + ], + "metrics.device.tablet": [ + { + "type": 0, + "value": "ট্যাবলেট" + } + ], + "metrics.devices": [ + { + "type": 0, + "value": "ডিভাইস গুলো" + } + ], + "metrics.events": [ + { + "type": 0, + "value": "ঘটনা" + } + ], + "metrics.filter.combined": [ + { + "type": 0, + "value": "সম্মিলিত" + } + ], + "metrics.filter.raw": [ + { + "type": 0, + "value": "অপরিশোধিত" + } + ], + "metrics.languages": [ + { + "type": 0, + "value": "ভাষা" + } + ], + "metrics.operating-systems": [ + { + "type": 0, + "value": "অপারেটিং সিস্টেম গুলো" + } + ], + "metrics.page-views": [ + { + "type": 0, + "value": "পৃষ্ঠা পরিদর্শন গুলো" + } + ], + "metrics.pages": [ + { + "type": 0, + "value": "পৃষ্ঠাগুলি" + } + ], + "metrics.referrers": [ + { + "type": 0, + "value": "রেফারার্স" + } + ], + "metrics.screens": [ + { + "type": 0, + "value": "স্ক্রিনগুলি" + } + ], + "metrics.unique-visitors": [ + { + "type": 0, + "value": "অনন্য ভিজিটর" + } + ], + "metrics.utm": [ + { + "type": 0, + "value": "UTM" + } + ], + "metrics.utm_campaign": [ + { + "type": 0, + "value": "UTM প্রচার" + } + ], + "metrics.utm_content": [ + { + "type": 0, + "value": "UTM সামগ্রী" + } + ], + "metrics.utm_medium": [ + { + "type": 0, + "value": "UTM মিডিয়াম" + } + ], + "metrics.utm_source": [ + { + "type": 0, + "value": "UTM উৎস" + } + ], + "metrics.utm_term": [ + { + "type": 0, + "value": "UTM শব্দ" + } + ], + "metrics.views": [ + { + "type": 0, + "value": "ভিউস" + } + ], + "metrics.visitors": [ + { + "type": 0, + "value": "পরিদর্শনার্থী" + } + ] +} \ No newline at end of file diff --git a/public/intl/messages/id-ID.json b/public/intl/messages/id-ID.json index 69ad8e39..3d9d9285 100644 --- a/public/intl/messages/id-ID.json +++ b/public/intl/messages/id-ID.json @@ -38,7 +38,7 @@ "label.all-time": [ { "type": 0, - "value": "All time" + "value": "Semua waktu" } ], "label.all-websites": [ @@ -176,7 +176,7 @@ "label.language": [ { "type": 0, - "value": "Language" + "value": "Bahasa" } ], "label.last-days": [ @@ -248,7 +248,7 @@ "label.owner": [ { "type": 0, - "value": "Owner" + "value": "Pemilik" } ], "label.password": [ @@ -332,7 +332,7 @@ "label.theme": [ { "type": 0, - "value": "Theme" + "value": "Tema" } ], "label.this-month": [ @@ -422,7 +422,7 @@ "message.confirm-reset": [ { "type": 0, - "value": "Are your sure you want to reset " + "value": "Anda yakin ingin mengatur ulang statistik " }, { "type": 1, @@ -430,7 +430,7 @@ }, { "type": 0, - "value": "'s statistics?" + "value": "?" } ], "message.copied": [ @@ -580,7 +580,7 @@ "message.toggle-charts": [ { "type": 0, - "value": "Toggle charts" + "value": "Buka grafik" } ], "message.track-stats": [ @@ -602,7 +602,7 @@ }, { "type": 0, - "value": " situs web anda." + "value": " situs web nda." } ], "message.type-delete": [ @@ -714,7 +714,7 @@ "metrics.languages": [ { "type": 0, - "value": "Languages" + "value": "Bahasa" } ], "metrics.operating-systems": [ @@ -744,7 +744,7 @@ "metrics.screens": [ { "type": 0, - "value": "Screens" + "value": "Layar" } ], "metrics.unique-visitors": [ @@ -762,31 +762,31 @@ "metrics.utm_campaign": [ { "type": 0, - "value": "UTM Campaign" + "value": "Kampanye UTM" } ], "metrics.utm_content": [ { "type": 0, - "value": "UTM Content" + "value": "Konten UTM" } ], "metrics.utm_medium": [ { "type": 0, - "value": "UTM Medium" + "value": "Media UTM" } ], "metrics.utm_source": [ { "type": 0, - "value": "UTM Source" + "value": "Sumber UTM" } ], "metrics.utm_term": [ { "type": 0, - "value": "UTM Term" + "value": "Tampilan UTM" } ], "metrics.views": [ diff --git a/public/intl/messages/pl-PL.json b/public/intl/messages/pl-PL.json index 8d0e72db..b954aa99 100644 --- a/public/intl/messages/pl-PL.json +++ b/public/intl/messages/pl-PL.json @@ -776,7 +776,7 @@ "metrics.screens": [ { "type": 0, - "value": "Screens" + "value": "Ekrany" } ], "metrics.unique-visitors": [ @@ -788,37 +788,37 @@ "metrics.utm": [ { "type": 0, - "value": "UTM" + "value": "Kampanie UTM" } ], "metrics.utm_campaign": [ { "type": 0, - "value": "UTM Campaign" + "value": "Kampania" } ], "metrics.utm_content": [ { "type": 0, - "value": "UTM Content" + "value": "Treść" } ], "metrics.utm_medium": [ { "type": 0, - "value": "UTM Medium" + "value": "Medium" } ], "metrics.utm_source": [ { "type": 0, - "value": "UTM Source" + "value": "Źródło" } ], "metrics.utm_term": [ { "type": 0, - "value": "UTM Term" + "value": "Słowa kluczowe" } ], "metrics.views": [ diff --git a/public/intl/messages/pt-PT.json b/public/intl/messages/pt-PT.json index 919a96d5..1ca21788 100644 --- a/public/intl/messages/pt-PT.json +++ b/public/intl/messages/pt-PT.json @@ -176,7 +176,7 @@ "label.language": [ { "type": 0, - "value": "Language" + "value": "Língua" } ], "label.last-days": [ @@ -340,7 +340,7 @@ "label.theme": [ { "type": 0, - "value": "Theme" + "value": "Tema" } ], "label.this-month": [ diff --git a/public/intl/messages/th-TH.json b/public/intl/messages/th-TH.json new file mode 100644 index 00000000..5240adbe --- /dev/null +++ b/public/intl/messages/th-TH.json @@ -0,0 +1,832 @@ +{ + "label.accounts": [ + { + "type": 0, + "value": "บัญชี" + } + ], + "label.add-account": [ + { + "type": 0, + "value": "เพิ่มบัญชี" + } + ], + "label.add-website": [ + { + "type": 0, + "value": "เพิ่มเว็บไซต์" + } + ], + "label.administrator": [ + { + "type": 0, + "value": "ผู้ดูแลระบบ" + } + ], + "label.all": [ + { + "type": 0, + "value": "ทั้งหมด" + } + ], + "label.all-events": [ + { + "type": 0, + "value": "เหตุการณ์ทั้งหมด" + } + ], + "label.all-time": [ + { + "type": 0, + "value": "ทุกช่วงเวลา" + } + ], + "label.all-websites": [ + { + "type": 0, + "value": "เว็บไซต์ทั้งหมด" + } + ], + "label.back": [ + { + "type": 0, + "value": "ย้อนกลับ" + } + ], + "label.cancel": [ + { + "type": 0, + "value": "ยกเลิก" + } + ], + "label.change-password": [ + { + "type": 0, + "value": "เปลี่ยนรหัสผ่าน" + } + ], + "label.confirm-password": [ + { + "type": 0, + "value": "ยืนยันรหัสผ่าน" + } + ], + "label.copy-to-clipboard": [ + { + "type": 0, + "value": "คัดลอกไปยังคลิปบอร์ด" + } + ], + "label.current-password": [ + { + "type": 0, + "value": "รหัสผ่านปัจจุบัน" + } + ], + "label.custom-range": [ + { + "type": 0, + "value": "กำหนดช่วงเวลา" + } + ], + "label.dashboard": [ + { + "type": 0, + "value": "แดชบอร์ด" + } + ], + "label.date-range": [ + { + "type": 0, + "value": "ตั้งแต่วันที่" + } + ], + "label.default-date-range": [ + { + "type": 0, + "value": "ช่วงเวลา" + } + ], + "label.delete": [ + { + "type": 0, + "value": "ลบ" + } + ], + "label.delete-account": [ + { + "type": 0, + "value": "ลบบัญชี" + } + ], + "label.delete-website": [ + { + "type": 0, + "value": "ลบเว็บไซต์" + } + ], + "label.dismiss": [ + { + "type": 0, + "value": "ยกเลิก" + } + ], + "label.domain": [ + { + "type": 0, + "value": "โดเมน" + } + ], + "label.edit": [ + { + "type": 0, + "value": "แก้ไข" + } + ], + "label.edit-account": [ + { + "type": 0, + "value": "แก้ไขบัญชี" + } + ], + "label.edit-website": [ + { + "type": 0, + "value": "แก้ไขเว็บไซต์" + } + ], + "label.enable-share-url": [ + { + "type": 0, + "value": "เปิดใช้งานการแชร์ลิงก์" + } + ], + "label.invalid": [ + { + "type": 0, + "value": "ไม่ถูกต้อง" + } + ], + "label.invalid-domain": [ + { + "type": 0, + "value": "โดเมนไม่ถูกต้อง" + } + ], + "label.language": [ + { + "type": 0, + "value": "ภาษา" + } + ], + "label.last-days": [ + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " วันที่ผ่านมา" + } + ], + "label.last-hours": [ + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " ชั่วโมงที่ผ่านมา" + } + ], + "label.logged-in-as": [ + { + "type": 0, + "value": "เข้าสู่ระบบโดย " + }, + { + "type": 1, + "value": "username" + } + ], + "label.login": [ + { + "type": 0, + "value": "เข้าสู่ระบบ" + } + ], + "label.logout": [ + { + "type": 0, + "value": "ออกจากระบบ" + } + ], + "label.more": [ + { + "type": 0, + "value": "เพิ่มเติม" + } + ], + "label.name": [ + { + "type": 0, + "value": "ชื่อ" + } + ], + "label.new-password": [ + { + "type": 0, + "value": "รหัสผ่านใหม่" + } + ], + "label.none": [ + { + "type": 0, + "value": "ไม่ได้กำหนด" + } + ], + "label.owner": [ + { + "type": 0, + "value": "เจ้าของ" + } + ], + "label.password": [ + { + "type": 0, + "value": "รหัสผ่าน" + } + ], + "label.passwords-dont-match": [ + { + "type": 0, + "value": "รหัสผ่านไม่ตรงกัน" + } + ], + "label.profile": [ + { + "type": 0, + "value": "โปรไฟล์" + } + ], + "label.realtime": [ + { + "type": 0, + "value": "เรียลไทม์" + } + ], + "label.realtime-logs": [ + { + "type": 0, + "value": "Log แบบเรียลไทม์" + } + ], + "label.refresh": [ + { + "type": 0, + "value": "รีเฟรช" + } + ], + "label.required": [ + { + "type": 0, + "value": "ต้องการ" + } + ], + "label.reset": [ + { + "type": 0, + "value": "รีเซต" + } + ], + "label.reset-website": [ + { + "type": 0, + "value": "รีเซตข้อมูลสถิติ" + } + ], + "label.save": [ + { + "type": 0, + "value": "บันทึก" + } + ], + "label.settings": [ + { + "type": 0, + "value": "ตั้งค่า" + } + ], + "label.share-url": [ + { + "type": 0, + "value": "แชร์ลิงก์" + } + ], + "label.single-day": [ + { + "type": 0, + "value": "วันที่" + } + ], + "label.theme": [ + { + "type": 0, + "value": "ธีม" + } + ], + "label.this-month": [ + { + "type": 0, + "value": "เดือนปัจจุบัน" + } + ], + "label.this-week": [ + { + "type": 0, + "value": "สัปดาห์ปัจจุบัน" + } + ], + "label.this-year": [ + { + "type": 0, + "value": "ปีปัจจุบัน" + } + ], + "label.timezone": [ + { + "type": 0, + "value": "เขตเวลา" + } + ], + "label.today": [ + { + "type": 0, + "value": "วันนี้" + } + ], + "label.tracking-code": [ + { + "type": 0, + "value": "โค้ดสำหรับใช้ติดตาม" + } + ], + "label.unknown": [ + { + "type": 0, + "value": "ไม่รู้จัก" + } + ], + "label.username": [ + { + "type": 0, + "value": "ชื่อผู้ใช้" + } + ], + "label.view-details": [ + { + "type": 0, + "value": "แสดงรายละเอียด" + } + ], + "label.websites": [ + { + "type": 0, + "value": "เว็บไซต์" + } + ], + "message.active-users": [ + { + "type": 0, + "value": "มีผู้ใช้งาน " + }, + { + "type": 1, + "value": "x" + }, + { + "type": 0, + "value": " " + }, + { + "offset": 0, + "options": { + "one": { + "value": [ + { + "type": 0, + "value": "คนในขณะนี้" + } + ] + }, + "other": { + "value": [ + { + "type": 0, + "value": "คนในขณะนี้" + } + ] + } + }, + "pluralType": "cardinal", + "type": 6, + "value": "x" + } + ], + "message.confirm-delete": [ + { + "type": 0, + "value": "คุณแน่ใจหรือไม่ว่าต้องการลบ " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " ?" + } + ], + "message.confirm-reset": [ + { + "type": 0, + "value": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " ?" + } + ], + "message.copied": [ + { + "type": 0, + "value": "คัดลอกแล้ว!" + } + ], + "message.delete-warning": [ + { + "type": 0, + "value": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ." + } + ], + "message.failure": [ + { + "type": 0, + "value": "เกิดข้อผิดพลาด." + } + ], + "message.get-share-url": [ + { + "type": 0, + "value": "รับลิงก์สำหรับแชร์" + } + ], + "message.get-tracking-code": [ + { + "type": 0, + "value": "รับโค้ดสำหรับใช้ติดตาม" + } + ], + "message.go-to-settings": [ + { + "type": 0, + "value": "ไปที่การตั้งค่า" + } + ], + "message.incorrect-username-password": [ + { + "type": 0, + "value": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง." + } + ], + "message.log.visitor": [ + { + "type": 0, + "value": "ผู้เข้าชมจาก " + }, + { + "type": 1, + "value": "country" + }, + { + "type": 0, + "value": " กำลังใช้งานผ่าน " + }, + { + "type": 1, + "value": "browser" + }, + { + "type": 0, + "value": " บน " + }, + { + "type": 1, + "value": "os" + }, + { + "type": 0, + "value": " " + }, + { + "type": 1, + "value": "device" + } + ], + "message.new-version-available": [ + { + "type": 0, + "value": "umami เวอร์ชันใหม่ (" + }, + { + "type": 1, + "value": "version" + }, + { + "type": 0, + "value": ") มาแล้ว!" + } + ], + "message.no-data-available": [ + { + "type": 0, + "value": "ไม่มีข้อมูล." + } + ], + "message.no-websites-configured": [ + { + "type": 0, + "value": "คุณยังไม่ได้ตั้งค่าเว็บไซต์ใด ๆ ไว้." + } + ], + "message.page-not-found": [ + { + "type": 0, + "value": "ไม่พบหน้านี้." + } + ], + "message.powered-by": [ + { + "type": 0, + "value": "ขับเคลื่อนโดย " + }, + { + "type": 1, + "value": "name" + } + ], + "message.reset-warning": [ + { + "type": 0, + "value": "สถิติทั้งหมดสำหรับเว็บไซต์นี้จะถูกลบออก แต่โค้ดสำหรับใช้ติดตามของคุณจะยังคงอยู่เหมือนเดิม." + } + ], + "message.save-success": [ + { + "type": 0, + "value": "บันทึกข้อมูลเรียบร้อย." + } + ], + "message.share-url": [ + { + "type": 0, + "value": "นี่คือลิงก์ที่แชร์แบบสาธารณะสำหรับ " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": "." + } + ], + "message.toggle-charts": [ + { + "type": 0, + "value": "เปิด/ปิดแผนภูมิ" + } + ], + "message.track-stats": [ + { + "type": 0, + "value": "หากต้องการติดตามสถิติสำหรับ " + }, + { + "type": 1, + "value": "target" + }, + { + "type": 0, + "value": " ให้วางโค้ดต่อไปนี้ในส่วน " + }, + { + "type": 1, + "value": "head" + }, + { + "type": 0, + "value": " ของเว็บไซต์ของคุณ." + } + ], + "message.type-delete": [ + { + "type": 0, + "value": "พิมพ์ข้อความ " + }, + { + "type": 1, + "value": "delete" + }, + { + "type": 0, + "value": " ในช่องด้านล่างเพื่อยืนยัน." + } + ], + "message.type-reset": [ + { + "type": 0, + "value": "พิมพ์ข้อความ " + }, + { + "type": 1, + "value": "reset" + }, + { + "type": 0, + "value": " ในช่องด้านล่างเพื่อยืนยัน." + } + ], + "metrics.actions": [ + { + "type": 0, + "value": "การกระทำ" + } + ], + "metrics.average-visit-time": [ + { + "type": 0, + "value": "ระยะเวลาเข้าชมเฉลี่ย" + } + ], + "metrics.bounce-rate": [ + { + "type": 0, + "value": "อัตราตีกลับ" + } + ], + "metrics.browsers": [ + { + "type": 0, + "value": "เบราว์เซอร์" + } + ], + "metrics.countries": [ + { + "type": 0, + "value": "ประเทศ" + } + ], + "metrics.device.desktop": [ + { + "type": 0, + "value": "เดสก์ท็อป" + } + ], + "metrics.device.laptop": [ + { + "type": 0, + "value": "แล็ปท็อป" + } + ], + "metrics.device.mobile": [ + { + "type": 0, + "value": "โทรศัพท์มือถือ" + } + ], + "metrics.device.tablet": [ + { + "type": 0, + "value": "แท็บเล็ต" + } + ], + "metrics.devices": [ + { + "type": 0, + "value": "อุปกรณ์" + } + ], + "metrics.events": [ + { + "type": 0, + "value": "เหตุการณ์" + } + ], + "metrics.filter.combined": [ + { + "type": 0, + "value": "ข้อมูลรวม" + } + ], + "metrics.filter.raw": [ + { + "type": 0, + "value": "ข้อมูลดิบ" + } + ], + "metrics.languages": [ + { + "type": 0, + "value": "ภาษา" + } + ], + "metrics.operating-systems": [ + { + "type": 0, + "value": "ระบบปฏิบัติการ" + } + ], + "metrics.page-views": [ + { + "type": 0, + "value": "การเข้าชม" + } + ], + "metrics.pages": [ + { + "type": 0, + "value": "หน้าเพจ" + } + ], + "metrics.referrers": [ + { + "type": 0, + "value": "แหล่งที่มา" + } + ], + "metrics.screens": [ + { + "type": 0, + "value": "ขนาดหน้าจอ" + } + ], + "metrics.unique-visitors": [ + { + "type": 0, + "value": "ผู้เข้าชม" + } + ], + "metrics.utm": [ + { + "type": 0, + "value": "UTM" + } + ], + "metrics.utm_campaign": [ + { + "type": 0, + "value": "UTM Campaign" + } + ], + "metrics.utm_content": [ + { + "type": 0, + "value": "UTM Content" + } + ], + "metrics.utm_medium": [ + { + "type": 0, + "value": "UTM Medium" + } + ], + "metrics.utm_source": [ + { + "type": 0, + "value": "UTM Source" + } + ], + "metrics.utm_term": [ + { + "type": 0, + "value": "UTM Term" + } + ], + "metrics.views": [ + { + "type": 0, + "value": "การเข้าชม" + } + ], + "metrics.visitors": [ + { + "type": 0, + "value": "ผู้เข้าชม" + } + ] +} \ No newline at end of file diff --git a/public/intl/messages/zh-CN.json b/public/intl/messages/zh-CN.json index dc30074a..fc79e2c0 100644 --- a/public/intl/messages/zh-CN.json +++ b/public/intl/messages/zh-CN.json @@ -776,37 +776,37 @@ "metrics.utm": [ { "type": 0, - "value": "UTM" + "value": "流量渠道标记(UTM)" } ], "metrics.utm_campaign": [ { "type": 0, - "value": "UTM Campaign" + "value": "流量标识" } ], "metrics.utm_content": [ { "type": 0, - "value": "UTM Content" + "value": "搜索关键字" } ], "metrics.utm_medium": [ { "type": 0, - "value": "UTM Medium" + "value": "流量来源类型" } ], "metrics.utm_source": [ { "type": 0, - "value": "UTM Source" + "value": "流量来源" } ], "metrics.utm_term": [ { "type": 0, - "value": "UTM Term" + "value": "流量搜索关键字" } ], "metrics.views": [ diff --git a/public/intl/messages/zh-TW.json b/public/intl/messages/zh-TW.json index c13a31ce..dc78dfc3 100644 --- a/public/intl/messages/zh-TW.json +++ b/public/intl/messages/zh-TW.json @@ -250,13 +250,13 @@ "label.none": [ { "type": 0, - "value": "None" + "value": "無" } ], "label.owner": [ { "type": 0, - "value": "Owner" + "value": "擁有者" } ], "label.password": [ @@ -340,7 +340,7 @@ "label.theme": [ { "type": 0, - "value": "Theme" + "value": "主題" } ], "label.this-month": [ @@ -596,7 +596,7 @@ "message.toggle-charts": [ { "type": 0, - "value": "Toggle charts" + "value": "切換圖表" } ], "message.track-stats": [ @@ -730,13 +730,13 @@ "metrics.languages": [ { "type": 0, - "value": "Languages" + "value": "語言" } ], "metrics.operating-systems": [ { "type": 0, - "value": "操作系统" + "value": "操作系統" } ], "metrics.page-views": [ @@ -760,7 +760,7 @@ "metrics.screens": [ { "type": 0, - "value": "Screens" + "value": "屏幕尺寸" } ], "metrics.unique-visitors": [ @@ -772,37 +772,37 @@ "metrics.utm": [ { "type": 0, - "value": "UTM" + "value": "流量渠道標記" } ], "metrics.utm_campaign": [ { "type": 0, - "value": "UTM Campaign" + "value": "流量標識" } ], "metrics.utm_content": [ { "type": 0, - "value": "UTM Content" + "value": "流量搜索內容" } ], "metrics.utm_medium": [ { "type": 0, - "value": "UTM Medium" + "value": "流量來源類型" } ], "metrics.utm_source": [ { "type": 0, - "value": "UTM Source" + "value": "流量來源" } ], "metrics.utm_term": [ { "type": 0, - "value": "UTM Term" + "value": "流量搜索關鍵字" } ], "metrics.views": [ diff --git a/scripts/format-lang.js b/scripts/format-lang.js index 5d1adb01..bd038081 100644 --- a/scripts/format-lang.js +++ b/scripts/format-lang.js @@ -2,17 +2,12 @@ const fs = require('fs-extra'); const path = require('path'); const del = require('del'); const prettier = require('prettier'); -const chalk = require('chalk'); const src = path.resolve(__dirname, '../lang'); const dest = path.resolve(__dirname, '../build'); const files = fs.readdirSync(src); -const removed = del.sync([path.join(dest, '*.json')]); - -if (removed.length) { - console.log(removed.map(n => `${n} ${chalk.redBright('✗')}`).join('\n')); -} +del.sync([path.join(dest, '*.json')]); async function run() { await fs.ensureDir(dest); @@ -29,8 +24,6 @@ async function run() { const json = prettier.format(JSON.stringify(formatted), { parser: 'json' }); fs.writeFileSync(path.resolve(dest, file), json); - - console.log(path.resolve(src, file), chalk.greenBright('->'), path.resolve(dest, file)); }); } From 68d35c0fc49b013615eee56bb70923e3388e97f8 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 1 Aug 2022 18:42:07 -0700 Subject: [PATCH 23/34] Moved DISABLE_LOGIN check to getServerSideProps. --- next.config.js | 3 --- pages/login.js | 10 ++++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/next.config.js b/next.config.js index b5e4b806..d6a953fc 100644 --- a/next.config.js +++ b/next.config.js @@ -35,9 +35,6 @@ if (process.env.FORCE_SSL) { module.exports = { env: { currentVersion: pkg.version, - loginDisabled: process.env.DISABLE_LOGIN, - updatesDisabled: process.env.DISABLE_UPDATES, - telemetryDisabled: process.env.DISABLE_TELEMETRY, }, basePath: process.env.BASE_PATH, output: 'standalone', diff --git a/pages/login.js b/pages/login.js index 94c0df64..4856a772 100644 --- a/pages/login.js +++ b/pages/login.js @@ -2,8 +2,8 @@ import React from 'react'; import Layout from 'components/layout/Layout'; import LoginForm from 'components/forms/LoginForm'; -export default function LoginPage() { - if (process.env.loginDisabled) { +export default function LoginPage({ loginDisabled }) { + if (loginDisabled) { return null; } @@ -13,3 +13,9 @@ export default function LoginPage() { ); } + +export async function getServerSideProps() { + return { + props: { loginDisabled: !!process.env.DISABLE_LOGIN }, + }; +} From daf3978970d1063c5e6509d8bf8e9da02ccd1b2e Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Mon, 1 Aug 2022 20:50:14 -0700 Subject: [PATCH 24/34] address PR comments. line up PSQL / MYSQL --- .../02_add_event_data/migration.sql | 58 +++++++++---------- db/postgresql/schema.prisma | 10 ++-- pages/api/website/[id]/metrics.js | 1 - queries/analytics/event/saveEvent.js | 4 +- 4 files changed, 33 insertions(+), 40 deletions(-) diff --git a/db/mysql/migrations/02_add_event_data/migration.sql b/db/mysql/migrations/02_add_event_data/migration.sql index 83392fb4..c210895d 100644 --- a/db/mysql/migrations/02_add_event_data/migration.sql +++ b/db/mysql/migrations/02_add_event_data/migration.sql @@ -1,45 +1,39 @@ -- DropForeignKey -alter table `event` drop foreign key `event_ibfk_1`; -alter table `event` drop foreign key `event_ibfk_2`; +ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_1`; +ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_2`; -drop index `event_created_at_idx` on `event`; -drop index `event_session_id_idx` on `event`; -drop index `event_website_id_idx` on `event`; +DROP INDEX `event_created_at_idx` ON `event`; +DROP INDEX `event_session_id_idx` ON `event`; +DROP INDEX `event_website_id_idx` ON `event`; -create index `event_old_created_at_idx` on `event` (created_at); -create index `event_old_session_id_idx` on `event` (session_id); -create index `event_old_website_id_idx` on `event` (website_id); +CREATE INDEX `event_old_created_at_idx` ON `event` (created_at); +CREATE INDEX `event_old_session_id_idx` ON `event` (session_id); +CREATE INDEX `event_old_website_id_idx` ON `event` (website_id); -- RenameTable -rename table `event` to `_event_old`; +RENAME TABLE `event` TO `_event_old`; -- CreateTable -create table `event` +CREATE TABLE `event` ( - event_id int unsigned auto_increment - primary key, - website_id int unsigned not null, - session_id int unsigned not null, - created_at timestamp default CURRENT_TIMESTAMP null, - url varchar(500) not null, - event_name varchar(50) NOT NULL, - constraint event_ibfk_1 - foreign key (website_id) references `website` (website_id) - on delete cascade, - constraint event_ibfk_2 - foreign key (session_id) references `session` (session_id) - on delete cascade -) - collate = utf8mb4_unicode_ci; + `event_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + `website_id` INTEGER UNSIGNED NOT NULL, + `session_id` INTEGER UNSIGNED NOT NULL, + `created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `url` VARCHAR(500) NOT NULL, + `event_name` VARCHAR(50) NOT NULL, -create index `event_created_at_idx` - on `event` (created_at); + INDEX `event_created_at_idx`(`created_at`), + INDEX `event_session_id_idx`(`session_id`), + INDEX `event_website_id_idx`(`website_id`), + PRIMARY KEY (`event_id`) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -create index `event_session_id_idx` - on `event` (session_id); +-- AddForeignKey +ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_2` FOREIGN KEY (`session_id`) REFERENCES `session`(`session_id`) ON DELETE CASCADE ON UPDATE NO ACTION; -create index `event_website_id_idx` - on `event` (website_id); +-- AddForeignKey +ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_1` FOREIGN KEY (`website_id`) REFERENCES `website`(`website_id`) ON DELETE CASCADE ON UPDATE NO ACTION; -- CreateTable @@ -50,7 +44,7 @@ CREATE TABLE `event_data` ( UNIQUE INDEX `event_data_event_id_key`(`event_id`), PRIMARY KEY (`event_data_id`) -) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- AddForeignKey ALTER TABLE `event_data` ADD CONSTRAINT `event_data_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `event`(`event_id`) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index f466300b..880cc27c 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -26,7 +26,7 @@ model event { event_name String @db.VarChar(50) session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade) website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade) - eventData event_data? + event_data event_data? @@index([created_at]) @@index([session_id]) @@ -34,10 +34,10 @@ model event { } model event_data { - id Int @id @default(autoincrement()) - event_id Int @unique - event_data Json - event event @relation(fields: [event_id], references: [event_id]) + event_data_id Int @id @default(autoincrement()) + event_id Int @unique + event_data Json + event event @relation(fields: [event_id], references: [event_id]) } model pageview { diff --git a/pages/api/website/[id]/metrics.js b/pages/api/website/[id]/metrics.js index 50f568d3..78c8a066 100644 --- a/pages/api/website/[id]/metrics.js +++ b/pages/api/website/[id]/metrics.js @@ -22,7 +22,6 @@ function getTable(type) { function getColumn(type) { if (type === 'event') { - //return `concat(event_type, '\t', event_value)`; return `event_name`; } return type; diff --git a/queries/analytics/event/saveEvent.js b/queries/analytics/event/saveEvent.js index 3e71c61c..af1c78ed 100644 --- a/queries/analytics/event/saveEvent.js +++ b/queries/analytics/event/saveEvent.js @@ -23,9 +23,9 @@ async function relationalQuery(website_id, { session_id, url, event_name, event_ }; if (event_data) { - data.eventData = { + data.event_data = { create: { - eventData: event_data, + event_data: event_data, }, }; } From 50e491af06e1451233c4ac9733a32ba9901127cf Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 1 Aug 2022 23:04:47 -0700 Subject: [PATCH 25/34] Added endpoint for fetching server-side variables. --- components/common/UpdateNotice.js | 11 ++++++++--- components/layout/Footer.js | 6 +++--- components/layout/Header.js | 6 +++--- hooks/useApi.js | 10 +++++----- hooks/useConfig.js | 24 ++++++++++++++++++++++++ pages/_app.js | 1 - pages/api/config.js | 14 ++++++++++++++ store/app.js | 5 +++++ 8 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 hooks/useConfig.js create mode 100644 pages/api/config.js diff --git a/components/common/UpdateNotice.js b/components/common/UpdateNotice.js index a5036808..bc27215e 100644 --- a/components/common/UpdateNotice.js +++ b/components/common/UpdateNotice.js @@ -6,10 +6,15 @@ import { setItem } from 'lib/web'; import { REPO_URL, VERSION_CHECK } from 'lib/constants'; import Button from './Button'; import styles from './UpdateNotice.module.css'; +import useUser from 'hooks/useUser'; +import useConfig from 'hooks/useConfig'; export default function UpdateNotice() { + const { user } = useUser(); + const { updatesDisabled } = useConfig(); const { latest, checked, hasUpdate, releaseUrl } = useStore(); const [dismissed, setDismissed] = useState(false); + const allowCheck = user?.is_admin && !updatesDisabled; const updateCheck = useCallback(() => { setItem(VERSION_CHECK, { version: latest, time: Date.now() }); @@ -27,12 +32,12 @@ export default function UpdateNotice() { } useEffect(() => { - if (!checked) { + if (!checked && allowCheck) { checkVersion(); } - }, []); + }, [checked]); - if (!hasUpdate || dismissed) { + if (!hasUpdate || dismissed || !allowCheck) { return null; } diff --git a/components/layout/Footer.js b/components/layout/Footer.js index ff7db96c..e7d0b14f 100644 --- a/components/layout/Footer.js +++ b/components/layout/Footer.js @@ -5,9 +5,11 @@ import Link from 'components/common/Link'; import styles from './Footer.module.css'; import useStore from 'store/version'; import { HOMEPAGE_URL, REPO_URL } from 'lib/constants'; +import useConfig from 'hooks/useConfig'; export default function Footer() { const { current } = useStore(); + const { telemetryDisabled } = useConfig(); return (
@@ -28,9 +30,7 @@ export default function Footer() {
{`v${current}`}
- {!process.env.telemetryDisabled && ( - - )} + {telemetryDisabled && }
); } diff --git a/components/layout/Header.js b/components/layout/Header.js index 5f5a85bc..0d36429d 100644 --- a/components/layout/Header.js +++ b/components/layout/Header.js @@ -8,10 +8,10 @@ import ThemeButton from 'components/settings/ThemeButton'; import HamburgerButton from 'components/common/HamburgerButton'; import UpdateNotice from 'components/common/UpdateNotice'; import UserButton from 'components/settings/UserButton'; -import Logo from 'assets/logo.svg'; -import styles from './Header.module.css'; import useUser from 'hooks/useUser'; import { HOMEPAGE_URL } from 'lib/constants'; +import Logo from 'assets/logo.svg'; +import styles from './Header.module.css'; export default function Header() { const { user } = useUser(); @@ -19,7 +19,7 @@ export default function Header() { return ( <> - {user?.is_admin && !process.env.updatesDisabled && } +
} size="large" className={styles.logo} /> diff --git a/hooks/useApi.js b/hooks/useApi.js index b2e74998..63e88a46 100644 --- a/hooks/useApi.js +++ b/hooks/useApi.js @@ -6,7 +6,7 @@ import useStore from 'store/app'; const selector = state => state.shareToken; -function parseHeaders(headers = {}, { authToken, shareToken }) { +function parseHeaders(headers, { authToken, shareToken }) { if (authToken) { headers.authorization = `Bearer ${authToken}`; } @@ -25,7 +25,7 @@ export default function useApi() { return { get: useCallback( - async (url, params, headers) => { + async (url, params = {}, headers = {}) => { return get( `${basePath}/api${url}`, params, @@ -36,7 +36,7 @@ export default function useApi() { ), post: useCallback( - async (url, params, headers) => { + async (url, params = {}, headers = {}) => { return post( `${basePath}/api${url}`, params, @@ -47,7 +47,7 @@ export default function useApi() { ), put: useCallback( - async (url, params, headers) => { + async (url, params = {}, headers = {}) => { return put( `${basePath}/api${url}`, params, @@ -58,7 +58,7 @@ export default function useApi() { ), del: useCallback( - async (url, params, headers) => { + async (url, params = {}, headers = {}) => { return del( `${basePath}/api${url}`, params, diff --git a/hooks/useConfig.js b/hooks/useConfig.js new file mode 100644 index 00000000..8adedcaf --- /dev/null +++ b/hooks/useConfig.js @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; +import useStore, { setConfig } from 'store/app'; +import useApi from 'hooks/useApi'; + +let fetched = false; + +export default function useConfig() { + const { config } = useStore(); + const { get } = useApi(); + + async function loadConfig() { + const { data } = await get('/config'); + setConfig(data); + } + + useEffect(() => { + if (!config && !fetched) { + fetched = true; + loadConfig(); + } + }, []); + + return config || {}; +} diff --git a/pages/_app.js b/pages/_app.js index 5c83c264..b8653113 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,4 +1,3 @@ -import React from 'react'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { IntlProvider } from 'react-intl'; diff --git a/pages/api/config.js b/pages/api/config.js new file mode 100644 index 00000000..a72eb0ba --- /dev/null +++ b/pages/api/config.js @@ -0,0 +1,14 @@ +import { ok, methodNotAllowed } from 'lib/response'; + +export default async (req, res) => { + if (req.method === 'GET') { + return ok(res, { + basePath: process.env.BASE_PATH || '', + trackerScriptName: process.env.TRACKER_SCRIPT_NAME, + updatesDisabled: !!process.env.DISABLE_UPDATES, + telemetryDisabled: !!process.env.DISABLE_TELEMETRY, + }); + } + + return methodNotAllowed(res); +}; diff --git a/store/app.js b/store/app.js index 65295fd0..ff4a91a4 100644 --- a/store/app.js +++ b/store/app.js @@ -20,6 +20,7 @@ const initialState = { dashboard: getItem(DASHBOARD_CONFIG) || defaultDashboardConfig, shareToken: null, user: null, + config: null, }; const store = create(() => ({ ...initialState })); @@ -45,4 +46,8 @@ export function setDashboard(dashboard) { setItem(DASHBOARD_CONFIG, dashboard); } +export function setConfig(config) { + store.setState({ config }); +} + export default store; From a4a68882483478116d8cef9b7f65c31216704847 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Tue, 2 Aug 2022 00:24:17 -0700 Subject: [PATCH 26/34] Moved telemetry code to script. --- components/layout/Footer.js | 8 ++++---- lib/constants.js | 1 + next.config.js | 13 ++++++------- pages/api/scripts/telemetry.js | 14 ++++++++++++++ 4 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 pages/api/scripts/telemetry.js diff --git a/components/layout/Footer.js b/components/layout/Footer.js index e7d0b14f..f9c2ba87 100644 --- a/components/layout/Footer.js +++ b/components/layout/Footer.js @@ -1,15 +1,15 @@ -import React from 'react'; +import { useRouter } from 'next/router'; +import Script from 'next/script'; import classNames from 'classnames'; import { FormattedMessage } from 'react-intl'; import Link from 'components/common/Link'; import styles from './Footer.module.css'; import useStore from 'store/version'; import { HOMEPAGE_URL, REPO_URL } from 'lib/constants'; -import useConfig from 'hooks/useConfig'; export default function Footer() { const { current } = useStore(); - const { telemetryDisabled } = useConfig(); + const { pathname } = useRouter(); return (
@@ -30,7 +30,7 @@ export default function Footer() {
{`v${current}`}
- {telemetryDisabled && } + {!pathname.includes('/share/') &&