"use strict"; exports.id = 24709; exports.ids = [24709]; exports.modules = { /***/ 24709: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "A3": () => (/* binding */ getOpenGraphLocale), /* harmony export */ "Dl": () => (/* binding */ getLocaleNameByFullName), /* harmony export */ "J_": () => (/* binding */ getLocaleName), /* harmony export */ "K8": () => (/* binding */ toLocalizedDate), /* harmony export */ "Sj": () => (/* binding */ toLocalizedVersesRange), /* harmony export */ "Tj": () => (/* binding */ toLocalizedVerseKey), /* harmony export */ "XP": () => (/* binding */ getDir), /* harmony export */ "iS": () => (/* binding */ isRTLLocale), /* harmony export */ "ic": () => (/* binding */ getLangFullLocale), /* harmony export */ "j2": () => (/* binding */ getLanguageDataById), /* harmony export */ "qc": () => (/* binding */ getLanguageAlternates), /* harmony export */ "rQ": () => (/* binding */ toLocalizedNumber), /* harmony export */ "uP": () => (/* binding */ shouldUseMinimalLayout), /* harmony export */ "zi": () => (/* binding */ findLanguageIdByLocale) /* harmony export */ }); /* unused harmony exports LANG_LOCALE_MAP, Direction, Languages, getLanguageDirectionById, getLanguageFontById, localizeNumericalStringWithSplitter, getOpenGraphAlternateLocales, toLocalizedMonthName */ /* harmony import */ var lodash_findKey__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12372); /* harmony import */ var lodash_findKey__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash_findKey__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _i18n_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50608); /* harmony import */ var _url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69663); /* eslint-disable max-lines */ /* eslint-disable import/prefer-default-export */ const RTL_LOCALES = [ "ar", "fa", "ur" ]; const LOCALE_NAME = { en: "English", ar: "العربية", bn: "বাংলা", fa: "فارسی", fr: "Fran\xe7ais", id: "Indonesia", it: "Italiano", nl: "Dutch", pt: "Portugu\xeas", ru: "русский", sq: "Shqip", th: "ภาษาไทย", tr: "T\xfcrk\xe7e", ur: "اردو", zh: "简体中文", ms: "Melayu", de: "Deutsch", inh: "ʁəlʁɑj mot", ta: "தமிழ்", hi: "हिन्दी", ku: "Kurd\xee" }; const LOCALE_NAME_TO_CODE = { bengali: "bn", english: "en", arabic: "ar", russian: "ru", urdu: "ur", Kurdish: "ku" }; const LANG_LOCALE_MAP = { en: "en-US", ar: "ar-EG", bn: "bn-BD", fa: "fa-IR", fr: "fr-FR", id: "id-ID", it: "it-IT", nl: "nl-NL", pt: "pt-BR", ru: "ru-RU", sq: "sq-AL", th: "th-TH", tr: "tr-TR", ur: "ur-PK", zh: "zh-CN", ms: "ms-MY" }; var Direction; (function(Direction) { Direction["LTR"] = "ltr"; Direction["RTL"] = "rtl"; })(Direction || (Direction = {})); const Languages = { 9: { // Arabic, dir: Direction.RTL, locale: "ar" }, 20: { // Bengali locale: "bn" }, 34: { font: "divehi", locale: "dv", dir: Direction.RTL }, 38: { // English locale: "en" }, 43: { // Persian/Farsi dir: Direction.RTL, locale: "fa" }, 49: { // French locale: "fr" }, 59: { // Hebrew dir: Direction.RTL, locale: "he" }, 67: { // Indonesian locale: "id" }, 74: { // Italian locale: "it" }, 89: { font: "kurdish", locale: "ku", dir: Direction.RTL }, 133: { // Portuguese locale: "pt" }, 118: { // Dutch locale: "nl" }, 138: { // Russian locle: "ru" }, 151: { // Albanian locale: "sq" }, 161: { // Thai locale: "th" }, 172: { // Uyghur/Uighur dir: Direction.RTL, locale: "ug" }, 174: { font: "urdu", dir: Direction.RTL, locale: "ur" }, 185: { // Chinese locale: "zh" } }; /** * Check whether the locale should have a minimalLayout. This will be reflect in * certain components like ChapterHeader or SurahPreviewRow and the reason we need * this is that for Arabic for example, we the transliteratedName and translatedName * have the same value which will result in redundant UI. * * @param {string} lang * @returns {boolean} */ const shouldUseMinimalLayout = (lang)=>{ return lang === "ar"; }; /** * Check whether the current locale is RTL. * * @param {string} locale * @returns {boolean} */ const isRTLLocale = (locale)=>RTL_LOCALES.includes(locale); /** * Gir the dir of the element based on the locale. * * @param {string} locale * @returns {string} */ const getDir = (locale)=>isRTLLocale(locale) ? Direction.RTL : Direction.LTR; /** * Get direction and font name of language by language id * * @param {number} languageId * @returns {LanguageData} */ const getLanguageDataById = (languageId)=>{ const lang = Languages[languageId]; return { font: lang?.font, direction: lang?.dir || Direction.LTR, code: lang?.locale || "en" }; }; /** * Get direction of language by language id * * @param {number} languageId * @returns {string} */ const getLanguageDirectionById = (languageId)=>{ const mapping = Languages[languageId]; return mapping?.dir || Direction.LTR; }; /** * Get font face name of language by language id * * @param {number} languageId * @returns {string} */ const getLanguageFontById = (languageId)=>{ const mapping = Languages[languageId]; return mapping?.font; }; /** * Find language Id by its locale * * @param {string} locale * @returns {number} language id */ const findLanguageIdByLocale = (locale)=>{ return Number(lodash_findKey__WEBPACK_IMPORTED_MODULE_0___default()(Languages, { locale })); }; /** * Generate the language alternates of a given path so that Search Engines can * recommend the alternate page to the users based on their region/locale. * * @see https://developers.google.com/search/docs/advanced/crawling/localized-versions * @param {string} path * @returns {LinkLanguageAlternate[]} */ const getLanguageAlternates = (path)=>{ const { locales } = _i18n_json__WEBPACK_IMPORTED_MODULE_1__; const basePath = (0,_url__WEBPACK_IMPORTED_MODULE_2__/* .getBasePath */ .bv)(); return locales.map((locale)=>({ hrefLang: locale, href: `${basePath}/${locale}${path === "/" ? "" : path}` })).concat({ hrefLang: "x-default", href: `${basePath}${path}` }); }; /** * Get the locale name. * * @param {string} locale * @returns {string} */ const getLocaleName = (locale)=>LOCALE_NAME[locale]; /** * Converts a locale name e.g. 'english' to its code e.g. 'en'. * * @param {string} fullName * @returns {string} */ const getLocaleNameByFullName = (fullName)=>LOCALE_NAME[LOCALE_NAME_TO_CODE[fullName]]; /** * Takes a number and returns a localized string based on the provided locale. * * @param {number} value * @param {string} locale * @param {boolean} showLeadingZero * @param {Intl.NumberFormatOptions} options * @returns {string} */ // Intl.NumberFormat is performance heavy so we are caching the formatter. const numberFormatters = new Map(); let currentLanguageLocale = null; const toLocalizedNumber = (value, locale, showLeadingZero = false, options = undefined)=>{ // we do this because an empty object will result in a new formatter being created everytime since we don't have it's reference. const formatterKey = options ?? "DEFAULT_OPTIONS"; if (numberFormatters.has(formatterKey) && currentLanguageLocale === locale) { return getFormattedNumber(numberFormatters.get(formatterKey), value, showLeadingZero); } currentLanguageLocale = locale; const fullLocale = LANG_LOCALE_MAP[locale]; const newNumberFormatter = new Intl.NumberFormat(fullLocale, options); numberFormatters.set(formatterKey, newNumberFormatter); return getFormattedNumber(newNumberFormatter, value, showLeadingZero); }; /** * Get the formatted localized number. This either returns * the original value or prepends a leading 0 to the beginning * of the string if it's allowed and the value is below 10. * * @param {Intl.NumberFormat} formatter * @param {number} value * @param {boolean} showLeadingZero * @returns {string} */ const getFormattedNumber = (formatter, value, showLeadingZero)=>{ const formattedNumber = formatter.format(value); if (!showLeadingZero || value >= 10) { return formattedNumber; } return `${formatter.format(0)}${formattedNumber}`; }; /** * Get the full locale name with lang + country e.g. ar-SA or en-US. * * @param {string} locale * @returns {string} */ const getLangFullLocale = (locale)=>LANG_LOCALE_MAP[locale]; /** * Takes a date and returns a localized string based on the provided locale and options. * * @param {number} value * @param {string} locale * @param {Intl.DateTimeFormatOptions} options * @returns {string} */ const toLocalizedDate = (value, locale, options = {})=>{ const fullLocale = LANG_LOCALE_MAP[locale]; return new Intl.DateTimeFormat(fullLocale, options).format(value); }; /** * Localize a string that contains 2 numbers with a splitter in between * e.g. "2:55" or "2-5". * * @param {string} string * @param {string} lang * @param {string} splitter * @returns {string} */ const localizeNumericalStringWithSplitter = (string, lang, splitter = ":")=>string.split(splitter).map((value)=>toLocalizedNumber(Number(value), lang)).join(splitter); /** * Get the localized value of the verse key. * * @param {string} verseKey * @param {string} lang * @returns {string} */ const toLocalizedVerseKey = (verseKey, lang)=>localizeNumericalStringWithSplitter(verseKey, lang); /** * Get the localized value of a range e.g. "1-20" * * @param {string} range * @param {string} lang * @returns {string} */ const toLocalizedVersesRange = (range, lang)=>localizeNumericalStringWithSplitter(range, lang, "-"); /** * Generate the locale by mapping the current iso language to * the format that Facebook accepts @see https://developers.facebook.com/docs/javascript/internationalization#locales . * Since LANG_LOCALE_MAP has the following format LL-CC, we need to convert it into LL_CC * be replacing "-" with "_". * * @param {string} currentLocale * @returns {string} */ const getOpenGraphLocale = (currentLocale)=>`${LANG_LOCALE_MAP[currentLocale]}`.replace("-", "_"); /** * Generate the alternate locales that the current content can be served in. * When Facebook needs to render an object in one of the specified locales, * it will make a request to the URL with the fb_locale URL parameter. * * @see https://developers.facebook.com/blog/post/2013/11/11/605/ * * @param {string} currentLocale * @returns {MetaTag[]} */ const getOpenGraphAlternateLocales = (currentLocale)=>{ return Object.keys(LANG_LOCALE_MAP).filter((languageCode)=>languageCode !== currentLocale).map((languageCode)=>({ name: "og:locale:alternate", content: `${LANG_LOCALE_MAP[languageCode]}`.replace("-", "_") })); }; /** * Convert a month number to the corresponding localized month name. * * @param {number} monthNumber * @param {string} locale * @returns {string} */ const toLocalizedMonthName = (monthNumber, locale)=>{ const objDate = new Date(); objDate.setDate(1); objDate.setMonth(monthNumber - 1); return objDate.toLocaleString(locale, { month: "long" }); }; /***/ }), /***/ 69663: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Jz": () => (/* binding */ getCurrentPath), /* harmony export */ "R": () => (/* binding */ navigateToExternalUrl), /* harmony export */ "Yj": () => (/* binding */ getWindowOrigin), /* harmony export */ "bv": () => (/* binding */ getBasePath), /* harmony export */ "vv": () => (/* binding */ getAuthApiPath) /* harmony export */ }); const getLocalePostfix = (locale)=>locale !== "en" ? `/${locale}` : ""; const getCurrentPath = ()=>{ if (false) {} return ""; }; const getWindowOrigin = (locale)=>{ if (false) {} return ""; }; /** * Navigate programmatically to an external url. we will try to open * the url in a new tab and if it doesn't work due to pop-ups being blocked, * we will open the url in the current tab. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open#return_value * * @param {string} url */ const navigateToExternalUrl = (url)=>{ if (false) {} }; /** * Get the base path of the current deployment on Vercel/local machine * e.g. http://localhost * or https://quran-com-ebqc5a2d5-qurancom.vercel.app this is needed * if we want to construct a full path e.g. when we add alternate languages * meta tags. * * @see https://vercel.com/docs/concepts/projects/environment-variables * @returns {string} */ const getBasePath = ()=>`${process.env.NEXT_PUBLIC_VERCEL_ENV === "development" ? "http" : "https"}://${process.env.NEXT_PUBLIC_VERCEL_URL}`; /** * Get the auth api path. * * @param {string} path * @returns {string} */ const getAuthApiPath = (path)=>`${process.env.NEXT_PUBLIC_AUTH_BASE_URL}/${path}`; /***/ }), /***/ 50608: /***/ ((module) => { module.exports = JSON.parse('{"locales":["en","ar","bn","fa","fr","id","it","nl","pt","ru","sq","th","tr","ur","zh","ms"],"defaultLocale":"en","pages":{"*":["common","error","radio","quick-links","onboarding"],"/":["home","radio","collection","reading-goal","reciter"],"/reading-goal":["reading-goal","reciter"],"/my-learning-plans":["learn"],"/learning-plans":["learn"],"/learning-plans/[slug]":["learn"],"/learning-plans/[slug]/lessons/[lessonSlugOrId]":["learn"],"/reading-goal/progress":["reading-goal","reading-progress"],"/[chapterId]":["quran-reader","reading-goal","notes","chapter","surah-info"],"/[chapterId]/reflections":["quran-reader","reading-goal","notes"],"/[chapterId]/[verseId]":["quran-reader","reading-goal","notes"],"/[chapterId]/[verseId]/tafsirs":["quran-reader","reading-goal","notes"],"/page/[pageId]":["quran-reader","reading-goal","notes"],"/juz/[juzId]":["quran-reader","reading-goal","notes"],"/hizb/[hizbId]":["quran-reader","reading-goal","notes"],"/surah/[chapterId]/info":["surah-info"],"/chapter_info/[chapterId]":["surah-info"],"/surah-info/[chapterId]":["surah-info"],"/collections/all":["collection"],"/collections/[collectionId]":["collection"],"/search":["search"],"/about-us":["about"],"/developers":["developers"],"/privacy":["privacy"],"/rub/[rubId]":["quran-reader","reading-goal","notes"],"/support":["support"],"/tajweed-colors":["tajweed"],"/product-updates":["product-updates"],"/product-updates/[id]":["product-updates"],"/apps":["apps"],"/radio":["home","radio"],"/reciters/[reciterId]":["home","radio","reciter"],"/reciters/[reciterId]/[chapterId]":["reciter"],"/reciters":["reciter","home"],"/profile":["home","profile","collection","quran-reader"],"/login":["login"],"/about-the-quran":["about-quran"],"/notes-and-reflections":["notes"],"/ramadan-activities":["ramadan-activities"],"/notification-settings":["notification-settings"],"/calendar":["quranic-calendar"]}}'); /***/ }) }; ; //# sourceMappingURL=24709.js.map