diff --git a/.eslintignore b/.eslintignore index 55ab6121244e7f..b69c5e33fcdce0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,4 +5,6 @@ api-server/src/public/** api-server/lib/** config/i18n.js config/certification-settings.js +config/superblock-order.js web/** +docs/**/*.md diff --git a/.eslintrc.json b/.eslintrc.json index 86091343770854..d0bd51611849c8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -38,7 +38,16 @@ "import/order": "error", "import/no-cycle": [2, { "maxDepth": 2 }], "react/prop-types": "off", - "no-only-tests/no-only-tests": "error" + "no-only-tests/no-only-tests": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ] }, "overrides": [ { diff --git a/.github/labeler.yml b/.github/labeler.yml index bb075a63d75720..cae5f5099b469a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -9,6 +9,7 @@ 'platform: api': - api-server/**/* + - api/**/* 'scope: tools/scripts': - cypress/**/* diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3f1b295d892845..122a159d1b2df3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,8 +32,8 @@ jobs: - name: Checkout repository uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3 - name: Setup CodeQL - uses: github/codeql-action/init@2956c096220fb34b6bf430b4ec7dcff2e77c8084 # tag=v1 + uses: github/codeql-action/init@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2 with: languages: ${{ matrix.language }} - name: Perform Analysis - uses: github/codeql-action/analyze@2956c096220fb34b6bf430b4ec7dcff2e77c8084 # tag=v1 + uses: github/codeql-action/analyze@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2 diff --git a/.github/workflows/codesee-diagram.yml b/.github/workflows/codesee-diagram.yml index f2bf2b4eeb348f..007153cbd5aa81 100644 --- a/.github/workflows/codesee-diagram.yml +++ b/.github/workflows/codesee-diagram.yml @@ -30,7 +30,7 @@ jobs: uses: Codesee-io/codesee-detect-languages-action@latest - name: Configure JDK 16 - uses: actions/setup-java@de1bb2b0c5634f0fc4438d7aa9944e68f9bf86cc # tag=v3 + uses: actions/setup-java@19eeec562b37d29a1ad055b7de9c280bd0906d8d # v3 if: ${{ fromJSON(steps.detect-languages.outputs.languages).java }} with: java-version: '16' diff --git a/.github/workflows/crowdin-download.curriculum.yml b/.github/workflows/crowdin-download.curriculum.yml index d44a55a0deb5e3..5d82cbc62b3eba 100644 --- a/.github/workflows/crowdin-download.curriculum.yml +++ b/.github/workflows/crowdin-download.curriculum.yml @@ -281,7 +281,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Set Environment variables run: | diff --git a/.github/workflows/e2e-mobile.yml b/.github/workflows/e2e-mobile.yml index 611e88c3657941..8e911c44f5528f 100644 --- a/.github/workflows/e2e-mobile.yml +++ b/.github/workflows/e2e-mobile.yml @@ -29,15 +29,14 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: 16.x - cache: 'npm' - - name: Setup Flutter 3.0.x + - name: Setup Flutter 3.3.x uses: subosito/flutter-action@dbf1fa04f4d2e52c33185153d06cdb5443aa189d # tag=v2 with: - flutter-version: '3.0.x' + flutter-version: '3.3.x' channel: 'stable' cache: true - cache-key: flutter-3.0.x + cache-key: flutter-3.3.x cache-path: ${{ runner.tool_cache }}/flutter - name: Set freeCodeCamp Environment Variables @@ -58,7 +57,7 @@ jobs: flutter test test/widget_test.dart - name: Cypress run - uses: cypress-io/github-action@v2 + uses: cypress-io/github-action@v4 with: record: ${{ env.CYPRESS_RECORD_KEY != 0 }} start: npx serve @@ -66,8 +65,7 @@ jobs: wait-on-timeout: 1200 config: retries=1,screenshotOnRunFailure=false,video=false,baseUrl=http://localhost:3000/mobile/mobile-app/generated-tests/ browser: chrome - headless: true - spec: cypress/integration/mobile-learn/test-challenges.js + spec: cypress/e2e/mobile-learn/test-challenges.js env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/e2e-third-party.yml b/.github/workflows/e2e-third-party.yml index 0ba0cdd41fa612..96fce5c650faac 100644 --- a/.github/workflows/e2e-third-party.yml +++ b/.github/workflows/e2e-third-party.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 services: mongodb: - image: mongo:4 + image: mongo:4.4 ports: - 27017:27017 # We need mailhog to catch any emails the api tries to send. @@ -38,7 +38,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: 16.x - cache: 'npm' - name: Set freeCodeCamp Environment Variables run: | @@ -66,5 +65,5 @@ jobs: wait-on-timeout: 1200 config: baseUrl=http://localhost:8000 browser: chrome - headless: true + spec: cypress/e2e/third-party/*.js diff --git a/.github/workflows/e2e-web.yml b/.github/workflows/e2e-web.yml index ded0c51991b6ba..c014b5e96e2375 100644 --- a/.github/workflows/e2e-web.yml +++ b/.github/workflows/e2e-web.yml @@ -5,9 +5,12 @@ on: - 'docs/**' branches-ignore: - 'renovate/**' + - 'next-api' pull_request: paths-ignore: - 'docs/**' + branches-ignore: + - 'next-api' jobs: build-client: @@ -28,7 +31,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: 16.x - cache: 'npm' - name: Set freeCodeCamp Environment Variables run: cp sample.env .env @@ -75,7 +77,7 @@ jobs: spec: cypress/e2e/default/**/*.js services: mongodb: - image: mongo:4 + image: mongo:4.4 ports: - 27017:27017 # We need mailhog to catch any emails the api tries to send. @@ -114,7 +116,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Set freeCodeCamp Environment Variables run: cp sample.env .env @@ -138,5 +139,5 @@ jobs: wait-on-timeout: 1200 config: baseUrl=http://localhost:8000 browser: ${{ matrix.browsers }} - headless: true + spec: ${{ matrix.spec }} diff --git a/.github/workflows/node.js-find-unused.yml b/.github/workflows/node.js-find-unused.yml index 8e22bfc63ef4de..3a70da8646461d 100644 --- a/.github/workflows/node.js-find-unused.yml +++ b/.github/workflows/node.js-find-unused.yml @@ -27,7 +27,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Set Environment variables run: | diff --git a/.github/workflows/node.js-tests-upcoming.yml b/.github/workflows/node.js-tests-upcoming.yml index a123eed45ed451..8baa16f7ad37c0 100644 --- a/.github/workflows/node.js-tests-upcoming.yml +++ b/.github/workflows/node.js-tests-upcoming.yml @@ -33,7 +33,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Set Environment variables run: | diff --git a/.github/workflows/node.js-tests.yml b/.github/workflows/node.js-tests.yml index 7896e1f8345a1f..f6d59c6ec7e439 100644 --- a/.github/workflows/node.js-tests.yml +++ b/.github/workflows/node.js-tests.yml @@ -5,7 +5,10 @@ on: push: branches-ignore: - 'renovate/**' + - 'next-api' pull_request: + branches-ignore: + - 'next-api' permissions: contents: read @@ -36,7 +39,6 @@ jobs: uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # tag=v3 with: node-version: ${{ matrix.node-version }} - cache: 'npm' - name: Set Environment variables run: | diff --git a/.gitignore b/.gitignore index dc84a83671705b..4c468c511bb9ce 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,8 @@ config/client/test-evaluator.json config/curriculum.json config/i18n.js config/certification-settings.js +config/superblock-order.js +config/superblock-order.test.js ### Generated utils files ### utils/block-nameify.js @@ -210,6 +212,7 @@ curriculum/build client/static/_redirects client/static/mobile client/static/curriculum-data +client/i18n/locales/**/trending.json ### UI Components ### tools/ui-components/dist diff --git a/.prettierignore b/.prettierignore index c2f88809e2878a..2d392969792346 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,13 +1,15 @@ **/.cache **/public client/static +client/**/trending.json **/*fixtures* curriculum/challenges/_meta/*/* curriculum/challenges/**/* config/**/*.json config/i18n.js config/certification-settings.js -docs/i18n +config/superblock-order.js +config/superblock-order.test.js utils/block-nameify.js utils/block-nameify.test.js utils/slugs.js @@ -16,3 +18,4 @@ utils/index.js **/package-lock.json web/.next curriculum-server/data/curriculum.json +docs/**/*.md diff --git a/api-server/src/server/middlewares/error-handlers.js b/api-server/src/server/middlewares/error-handlers.js index e78f26a3e29466..52e8cfaee44ff3 100644 --- a/api-server/src/server/middlewares/error-handlers.js +++ b/api-server/src/server/middlewares/error-handlers.js @@ -24,8 +24,7 @@ const isDev = process.env.FREECODECAMP_NODE_ENV !== 'production'; export default function prodErrorHandler() { // error handling in production. - // eslint-disable-next-line no-unused-vars - return function (err, req, res, next) { + return function (err, req, res, _next) { // response for when req.body is bigger than body-parser's size limit if (err?.type === 'entity.too.large') { return res.status('413').send('Request payload is too large'); diff --git a/client/gatsby-config.js b/client/gatsby-config.js index c299b5f2984aec..acc2d255106291 100644 --- a/client/gatsby-config.js +++ b/client/gatsby-config.js @@ -10,10 +10,7 @@ const { clientLocale, curriculumLocale, homeLocation, sentryClientDSN } = envData; const curriculumIntroRoot = path.resolve(__dirname, './src/pages'); -const pathPrefix = - clientLocale === 'english' || clientLocale === 'chinese' - ? '' - : '/' + clientLocale; +const pathPrefix = clientLocale === 'english' ? '' : '/' + clientLocale; module.exports = { flags: { diff --git a/client/i18n/locales.test.ts b/client/i18n/locales.test.ts index 8cc283b715fc52..be59f71b7b724d 100644 --- a/client/i18n/locales.test.ts +++ b/client/i18n/locales.test.ts @@ -11,9 +11,6 @@ const filesThatShouldExist = [ { name: 'motivation.json' }, - { - name: 'trending.json' - }, { name: 'intro.json' }, diff --git a/client/i18n/locales/arabic/translations.json b/client/i18n/locales/arabic/translations.json index 4c4fe2b30bbfa3..8ef010ee660f6c 100644 --- a/client/i18n/locales/arabic/translations.json +++ b/client/i18n/locales/arabic/translations.json @@ -226,7 +226,7 @@ "page-number": "{{pageNumber}} من {{totalPages}}" }, "footer": { - "tax-exempt-status": "منظمة freeCodeCamp هي منظمة خيرية معفاة من الضرائب 501(c)(3) يدعمها المتبرعين (الرقم التعريفي الضريبي الاتحادي للولايات المتحدة: 82-0779546)", + "tax-exempt-status": "تكون مؤسسة freeCodeCamp خيرية معفاة ضريبياً 501(c)(3) يدعمها المتبرعين (الرقم التعريفي الضريبي الاتحادي للولايات المتحدة: 82-0779546)", "mission-statement": "مهمتنا: مساعدة الناس على تعلم البرمجة مجاناً. ونحن نحقق ذلك بإنشاء آلاف الأشرطة من الفيديو والمقالات ودروس البرمجة التفاعلية - وجميعها متاحة مجاناً للجمهور. ولدينا أيضاً الآلاف من المجموعات الدراسية في freeCodeCamp حول العالم.", "donation-initiatives": "التبرعات لـ freeCodeCamp تذهب لمبادراتنا التعليمية، وتساعد في دفع تكاليف الخوادم، والخدمات، والموظفين.", "donate-text": "يمكنك <1>تقديم تبرع قابل للخصم الضريبي هنا .", @@ -264,7 +264,7 @@ "p8": "وهذا المنهج سيعطيك آلاف الساعات من التدريب العملي على البرمجة.", "p9": "وإذا كنت ترغب في تعلم المزيد من نظريات الرياضيات وعلوم الكمبيوتر، لدينا أيضا آلاف الساعات من دورات الفيديو على <0>قناة freeCodeCamp على يوتيوب.", "p10": "إذا كنت ترغب في الحصول على وظيفة مطور أو عملاء مستقلين، فإن مهارات البرمجة ستكون مجرد جزء من اللغز. تحتاج أيضاً إلى بناء شبكتك الشخصية وسمعتك كمطور.", - "p11": "يمكنك فعل ذلك على تويتر و GitHub، وأيضاً على <0>منتدى freeCodeCamp .", + "p11": "يمكنك فعل ذلك على LinkedIn و GitHub، وأيضاً على <0>منتدى freeCodeCamp .", "p12": "برمجة سعيدة!" }, "upcoming-lessons": "الدروس القادمة", @@ -284,7 +284,7 @@ "sign-in-save": "قم بتسجيل الدخول لحفظ تقدّمك", "download-solution": "تنزيل الحل", "percent-complete": "{{percent}}% مكتمل", - "project-complete": "Completed {{completedChallengesInBlock}} of {{totalChallengesInBlock}} certification projects", + "project-complete": "أكملت {{completedChallengesInBlock}} من {{totalChallengesInBlock}} مشروعات الشهادات", "tried-rsa": "إذا كنت قد جربت طريقة <0>اقرأ-ابحث-اسأل، فيمكنك طلب المساعدة في منتدى freeCodeCamp.", "rsa": "اقرأ ، ابحث ، اسأل", "rsa-forum": "قبل إجراء موضوع جديدة يرجى الاطلاع على ما إذا كان سؤالك <0> قد تم الإجابة عليه فعلًا في المنتدى .", @@ -325,7 +325,11 @@ "sorry-getting-there": "عذراً، لم يجتَز كودك. قربت من النجاح.", "sorry-hang-in-there": "عذراً، لم يجتَز كودك. لا تستسلم.", "sorry-dont-giveup": "عذراً، لم يجتَز كودك. لا تفقد الأمل.", - "challenges-completed": "اكتمل {{completedCount}} من {{totalChallenges}} تحديات" + "challenges-completed": "اكتمل {{completedCount}} من {{totalChallenges}} تحديات", + "season-greetings-fcc": "تحيات الموسم من مجتمع freeCodeCamp 🎉", + "if-getting-value": "إذا أفادك freeCodeCamp بشكل مثمر، يمكنك تتبرع دعما لرسالتنا التطوعية حتي يستمر مهمتنا.", + "building-a-university": "نحن نبني برنامَج مجاني لشهادة جامعة علوم الكمبيوتر Computer Science", + "if-help-university": "لقد حققنا قدرا كبيرا من التقدم بالفعل. أدعم منظمتنا الخيرية بالطريق الطويل الذي أمامنا." }, "donate": { "title": "ادعم منظمتنا الخيرية", @@ -350,6 +354,7 @@ "your-donation": "سيوفر تبرعك{{usd}}$ {{hours}} ساعات من التعلم للناس حول العالم.", "your-donation-2": "سيوفر تبرعك {{usd}}$ {{hours}} ساعات من التعلم للناس حول العالم كل شهر.", "your-donation-3": "سيوفر تبرعك {{usd}}$ {{hours}} ساعات من التعلم للناس حول العالم كل عام.", + "become-supporter": "أصبح داعماً", "duration": "كن داعماً لمرة واحدة لمنظمتنا الخيرية.", "duration-2": "كن داعماً شهريا لمنظمتنا الخيرية.", "duration-3": "كن داعماً سنويا لمنظمتنا الخيرية", @@ -402,11 +407,11 @@ "endowment": "هذه ستكون مساعدة هائلة. بما أن هذه عملية يدوية أكثر، يمكن لـ Quincy أن يساعدك فيها شخصيا. يرجى مراسلته مباشرة على Quincy@freecodecamp.org.", "how-legacy": "كيف يمكنني اعداد هدية مستقبلية لـ freeCodeCamp.org؟", "we-honored": "سيشرفنا أن نضع مثل هذه الهدية في الاستخدام الجيد لمساعدة الناس في جميع أنحاء العالم على تعلم البرمجة. وتبعا لمكان سكنك، قد يكون هذا معفيا من الضرائب.", - "legacy-gift-message": "أعطي وأوريث [مبلغ _____ دولار أمريكي (أو عملة أخرى) أو _____ في المائة من الباقي وبقايا تركتي] إلى freeCodeCamp.org (رقم التعريف الضريبي لشركة Free Code Camp، Inc. 82-0779546) ، وهي مؤسسة خيرية منظمة بموجب قوانين ولاية ديلاوير ، الولايات المتحدة ، وتقع حاليًا في 3905 Hedgcoxe Rd، PO Box 250352، Plano، Texas، 75025 United States ، لاستخدامها في أغراضها الخيرية العامة وفقًا لتقديرها.", + "legacy-gift-message": "أعطي وأوريث [مبلغ _____ دولار أمريكي (أو عملة أخرى) أو _____ في المائة من الباقي وبقايا تركتي] إلى freeCodeCamp.org (رقم التعريف الضريبي لشركة Free Code Camp، Inc. 82-0779546) ، وهي مؤسسة خيرية بموجب قوانين ولاية ديلاوير، الولايات المتحدة، وتقع حاليًا في 3905 Hedgcoxe Rd، PO Box 250352، Plano، Texas، 75025 United States، لاستخدامها في أغراضها الخيرية العامة وفقًا لتقديرها.", "thank-wikimedia": "ونود أن نشكر مؤسسة ويكيميديا على توفير هذه اللغة الرسمية لنا لكي نستخدمها.", "legacy-gift-questions": "إذا كان لديك أي أسئلة حول هذه العملية، يرجى إرسال بريد الإلكتروني إلى Quincy@freecodecamp.org.", "how-stock": "كيف يمكنني التبرع بالاسهم لـ freeCodeCamp.org؟", - "welcome-stock": "نحن نرحب بتبرعاتك للاسهم. يرجى إرسال بريد إلكتروني مباشر إلى Quincy ويمكنه مساعدتك في ذلك، ومشاركة تفاصيل حساب الوساطة الخاص بالمنظمة الخيرية: Quincy@freecodecamp.org.", + "welcome-stock": "نحن نرحب بتبرعاتك للأسهم. يرجى إرسال بريد إلكتروني مباشر إلى Quincy ويمكنه مساعدتك في ذلك، ومشاركة تفاصيل حساب الوساطة الخاص بالمؤسسة الخيرية: Quincy@freecodecamp.org.", "how-receipt": "هل يمكنني الحصول على إيصال تبرع حتى يمكنني خصم تبرعي من ضرائبي؟", "just-forward": "بالتأكيد. فقط أرسل الإيصال من معاملتك إلى donors@freecodecamp.org، أخبرنا بأنك تريد إيصال وأي تعليمات خاصة قد تكون لديك، وسنرد مع إيصال لك.", "how-update": "لقد قمت بإعداد تبرع شهري، ولكن أحتاج إلى تحديث أو إيقاف تكرار ذلك شهريا. كيف يمكنني القيام بذلك؟", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "أفتح المعاينة في شاشة جديدة وتركيزها", "step": "الخطوة", "steps": "الخطوات", - "steps-for": "خطوات {{blockTitle}}" + "steps-for": "خطوات {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "للمطالبة بشهادة ، يجب عليك أولاً قبول سياسة الصدق الأكاديمي الخاصة بنا", @@ -716,5 +722,12 @@ "focus-instructions-panel": "ركز على لوحة تعليمات", "navigate-previous": "تنقل إلى التمرين السابق", "navigate-next": "تنقل إلى التمرين التالي" + }, + "signout": { + "heading": "تسجيل الخروج من حسابك", + "p1": "تحذير: إذا تابعت، لن يتم حفظ تقدمك.", + "p2": "سيؤدي هذا الإجراء إلى تسجيل خروجك من حسابك على هذا الجهاز وجلسة المتصفح فقط. الرجاء تأكيد ما إذا كنت ترغب في المتابعة.", + "certain": "نعم، سجل الخروج من حسابي", + "nevermind": "لا أريد تسجيل الخروج" } } diff --git a/client/i18n/locales/arabic/trending.json b/client/i18n/locales/arabic/trending.json deleted file mode 100644 index f62d7eedd4fda7..00000000000000 --- a/client/i18n/locales/arabic/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Learn JavaScript", - "article0link": "https://www.freecodecamp.org/news/learn-javascript-free-js-courses-for-beginners/", - "article1title": "Linux ln Example", - "article1link": "https://www.freecodecamp.org/news/linux-ln-how-to-create-a-symbolic-link-in-linux-example-bash-command", - "article2title": "JS document.ready()", - "article2link": "https://www.freecodecamp.org/news/javascript-document-ready-jquery-example/", - "article3title": "Delete a Row in SQL", - "article3link": "https://www.freecodecamp.org/news/how-to-delete-a-row-in-sql-example-query/", - "article4title": "Python Round to Int", - "article4link": "https://www.freecodecamp.org/news/how-to-round-numbers-up-or-down-in-python/", - "article5title": "What is msmpeng.exe?", - "article5link": "https://www.freecodecamp.org/news/what-is-antimalware-service-executable-why-is-it-high-cpu-disk-usage/", - "article6title": "Queue Data Structure", - "article6link": "https://www.freecodecamp.org/news/queue-data-structure-definition-and-java-example-code/", - "article7title": "Learn Web Development", - "article7link": "https://www.freecodecamp.org/news/learn-web-development-free-full-stack-developer-courses-for-beginners/", - "article8title": "Install Node on Windows", - "article8link": "https://www.freecodecamp.org/news/how-to-install-node-js-and-npm-on-windows-2/", - "article9title": "Remove Char from String", - "article9link": "https://www.freecodecamp.org/news/python-remove-character-from-a-string-how-to-delete-characters-from-strings/", - "article10title": "Rust Lang", - "article10link": "https://www.freecodecamp.org/news/rust-in-replit/", - "article11title": "Python Sets", - "article11link": "https://www.freecodecamp.org/news/python-set-operations-explained-with-examples/", - "article12title": "C++ Strings", - "article12link": "https://www.freecodecamp.org/news/c-string-std-string-example-in-cpp/", - "article13title": "Python map()", - "article13link": "https://www.freecodecamp.org/news/python-map-explained-with-examples/", - "article14title": "Python .pop()", - "article14link": "https://www.freecodecamp.org/news/python-pop-how-to-pop-from-a-list-or-an-array-in-python/", - "article15title": "Python arrays", - "article15link": "https://www.freecodecamp.org/news/python-array-tutorial-define-index-methods/", - "article16title": "npm Uninstall", - "article16link": "https://www.freecodecamp.org/news/npm-uninstall-how-to-remove-a-package/", - "article17title": "Insertion Sort", - "article17link": "https://www.freecodecamp.org/news/insertion-sort-algorithm-example-in-java-and-c/", - "article18title": "Python If-Else", - "article18link": "https://www.freecodecamp.org/news/python-if-else-python-conditional-syntax-example/", - "article19title": "All Caps in CSS", - "article19link": "https://www.freecodecamp.org/news/all-caps-in-css-how-to-uppercase-text-with-style/", - "article20title": "Open Task Manager on Mac", - "article20link": "https://www.freecodecamp.org/news/how-to-open-task-manager-on-mac-apple-shortcut-tutorial/", - "article21title": "parseInt() in JavaScript", - "article21link": "https://www.freecodecamp.org/news/parseint-in-javascript-js-string-to-int-example/", - "article22title": "Print statement in Python", - "article22link": "https://www.freecodecamp.org/news/print-statement-in-python-how-to-print-with-example-syntax-command/", - "article23title": "Remove Directory in Linux", - "article23link": "https://www.freecodecamp.org/news/remove-directory-in-linux-how-to-delete-a-folder-from-the-command-line/", - "article24title": "Python str.lower() Example", - "article24link": "https://www.freecodecamp.org/news/python-to-lowercase-a-string-str-lower-example/", - "article25title": "Second Monitor Not Detected", - "article25link": "https://www.freecodecamp.org/news/second-monitor-not-detected-fixed-windows10/", - "article26title": "How to Declare Strings in C", - "article26link": "https://www.freecodecamp.org/news/c-string-how-to-declare-strings-in-the-c-programming-language/", - "article27title": "How to Use .len() in Python", - "article27link": "https://www.freecodecamp.org/news/what-is-len-in-python-how-to-use-the-len-function-to-find-the-length-of-a-string/", - "article28title": "Python Convert String to Int", - "article28link": "https://www.freecodecamp.org/news/python-convert-string-to-int-how-to-cast-a-string-in-python/", - "article29title": "How to create a free website", - "article29link": "https://www.freecodecamp.org/news/how-to-create-a-website-free-of-cost-website-builder-platform-guide/" -} diff --git a/client/i18n/locales/chinese-traditional/translations.json b/client/i18n/locales/chinese-traditional/translations.json index c8b236203116ff..ae3ed605d182b7 100644 --- a/client/i18n/locales/chinese-traditional/translations.json +++ b/client/i18n/locales/chinese-traditional/translations.json @@ -264,7 +264,7 @@ "p8": "這套課程需要你進行數千個小時的編程練習。", "p9": "如果你想學習更多數學和計算機科學理論,<0>freeCodeCamp 的 \n YouTube channel 還有數千個小時的視頻課程。", "p10": "如果你想獲得開發者工作或者成爲自由職業開發者找到客戶,那麼除了編程技能,你還需要搭建自己的社交網絡,打造自己作爲開發者的影響力。", - "p11": "你可以在 Twitter、GitHub 和 <0>freeCodeCamp 論壇搭建社交網絡和打造影響力。", + "p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum.", "p12": "編程愉快!" }, "upcoming-lessons": "即將上線的課程", @@ -325,7 +325,11 @@ "sorry-getting-there": "抱歉,你的代碼未通過,就快要成功了。", "sorry-hang-in-there": "抱歉,你的代碼未通過,堅持一下。", "sorry-dont-giveup": "抱歉,你的代碼未通過,不要放棄。", - "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}" + "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}", + "season-greetings-fcc": "Season's Greetings from the freeCodeCamp community 🎉", + "if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.", + "building-a-university": "We're Building a Free Computer Science University Degree Program", + "if-help-university": "We've already made a ton of progress. Support our charity with the long road ahead." }, "donate": { "title": "支持我們的非營利組織", @@ -350,6 +354,7 @@ "your-donation": "你的 ${{usd}} 捐款將幫助世界各地的人們學習 {{hours}} 小時。", "your-donation-2": "你的 ${{usd}} 捐款每月將幫助世界各地的人們學習 {{hours}} 小時。", "your-donation-3": "你的 ${{usd}} 捐款每年將幫助世界各地的人們學習 {{hours}} 小時。", + "become-supporter": "Become a Supporter", "duration": "成爲我們非營利組織的一次性支持者", "duration-2": "成爲我們非營利組織的每月定期支持者", "duration-3": "成爲我們非營利組織的每年定期支持者", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "在新窗口中打開預覽並聚焦於它", "step": "步驟", "steps": "步驟", - "steps-for": "{{blockTitle}} 的步驟" + "steps-for": "{{blockTitle}} 的步驟", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "申請認證之前,你必須先接受我們的《學術誠信條例》", @@ -716,5 +722,12 @@ "focus-instructions-panel": "聚焦指示面板", "navigate-previous": "跳轉至上一個練習", "navigate-next": "跳轉至下一個練習" + }, + "signout": { + "heading": "Sign out of your account", + "p1": "Warning: If you continue, your progress will no longer be saved.", + "p2": "This action will sign you out of your account on this device and browser session only. Please confirm if you would like to proceed.", + "certain": "Yes, sign out of my account", + "nevermind": "Nevermind, I don't want to sign out" } } diff --git a/client/i18n/locales/chinese-traditional/trending.json b/client/i18n/locales/chinese-traditional/trending.json deleted file mode 100644 index 933269c03bb67e..00000000000000 --- a/client/i18n/locales/chinese-traditional/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "電腦截屏", - "article0link": "https://chinese.freecodecamp.org/news/how-to-screenshot-on-windows/", - "article1title": "程序員自學", - "article1link": "https://chinese.freecodecamp.org/news/how-i-learn-coding-for-eight-months-and-become-a-developer/", - "article2title": "AppData 文件夾", - "article2link": "https://chinese.freecodecamp.org/news/where-to-find-the-appdata-folder-in-windows-10/", - "article3title": "MongoDB Atlas", - "article3link": "https://chinese.freecodecamp.org/news/get-started-with-mongodb-atlas/", - "article4title": "Git 刪除分支", - "article4link": "https://chinese.freecodecamp.org/news/how-to-delete-a-git-branch-both-locally-and-remotely/", - "article5title": "npm 是什麼意思", - "article5link": "https://chinese.freecodecamp.org/news/what-is-npm-a-node-package-manager-tutorial-for-beginners/", - "article6title": "js 字符串反轉", - "article6link": "https://chinese.freecodecamp.org/news/how-to-reverse-a-string-in-javascript-in-3-different-ways/", - "article7title": "谷歌小恐龍", - "article7link": "https://chinese.freecodecamp.org/news/do-you-know-the-chrome-dino-game-millions-of-people-are-playing/", - "article8title": "自學編程", - "article8link": "https://chinese.freecodecamp.org/news/how-i-went-from-newbie-to-software-engineer-in-9-months-while-working-full-time/", - "article9title": "手機上開發 Web App", - "article9link": "https://chinese.freecodecamp.org/news/how-to-code-on-your-phone-python-pydroid-android-app-tutorial/", - "article10title": "Python 編程", - "article10link": "https://chinese.freecodecamp.org/news/python-code-examples-sample-script-coding-tutorial-for-beginners/", - "article11title": "計算機語言學習順序", - "article11link": "https://chinese.freecodecamp.org/news/what-programming-language-should-i-learn-first/", - "article12title": "什麼是編程", - "article12link": "https://chinese.freecodecamp.org/news/what-is-computer-programming-defining-software-development/", - "article13title": "分佈式 id 號段模式", - "article13link": "https://chinese.freecodecamp.org/news/distributed-id/", - "article14title": "Python 輸出換行符", - "article14link": "https://chinese.freecodecamp.org/news/python-new-line-and-how-to-python-print-without-a-newline/", - "article15title": "GraalVM", - "article15link": "https://chinese.freecodecamp.org/news/graalvm-summary/", - "article16title": "前端後端", - "article16link": "https://chinese.freecodecamp.org/news/front-end-developer-vs-back-end-developer-definition-and-meaning-in-practice/", - "article17title": "json 文件怎麼註釋", - "article17link": "https://chinese.freecodecamp.org/news/json-comment/", - "article18title": "編程學校", - "article18link": "https://chinese.freecodecamp.org/news/how-we-created-a-free-coding-school-with-the-freecodecamp-curriculum/", - "article19title": "UDP 和 TCP 協議區別", - "article19link": "https://chinese.freecodecamp.org/news/tcp-vs-udp-which-is-faster/", - "article20title": "自學編程從哪學起", - "article20link": "https://chinese.freecodecamp.org/news/how-i-went-from-newbie-to-software-engineer-in-9-months-while-working-full-time/", - "article21title": "about:blank 是什麼意思", - "article21link": "https://chinese.freecodecamp.org/news/about-blank-what-does-about-blank-mean-and-why-is-it-blocked-in-chrome-and-firefox/", - "article22title": "配置 VS Code", - "article22link": "https://chinese.freecodecamp.org/news/how-to-set-up-vscode-to-improve-your-productivity/", - "article23title": "cmd 刪除文件", - "article23link": "https://chinese.freecodecamp.org/news/cmd-delete-folder-how-to-remove-files-and-folders-in-windows/", - "article24title": "docker 刪除鏡像", - "article24link": "https://chinese.freecodecamp.org/news/how-to-remove-images-in-docker/", - "article25title": "前端工程化", - "article25link": "https://chinese.freecodecamp.org/news/front-end-engineering-tutorial/", - "article26title": "Golang Benchmark", - "article26link": "https://chinese.freecodecamp.org/news/golang-benchmark/", - "article27title": "樹莓派", - "article27link": "https://chinese.freecodecamp.org/news/build-a-personal-dev-server-on-a-5-dollar-raspberry-pi/", - "article28title": "二八定律", - "article28link": "https://chinese.freecodecamp.org/news/the-80-20-rule-pareto-principle/", - "article29title": "JS 隱式類型轉換", - "article29link": "https://chinese.freecodecamp.org/news/javascript-implicit-type-conversion/" -} diff --git a/client/i18n/locales/chinese/translations.json b/client/i18n/locales/chinese/translations.json index aa3279e846402e..bd6710bf1320bb 100644 --- a/client/i18n/locales/chinese/translations.json +++ b/client/i18n/locales/chinese/translations.json @@ -264,7 +264,7 @@ "p8": "这套课程需要你进行数千个小时的编程练习。", "p9": "如果你想学习更多数学和计算机科学理论,<0>freeCodeCamp 的 \n YouTube channel 还有数千个小时的视频课程。", "p10": "如果你想获得开发者工作或者成为自由职业开发者找到客户,那么除了编程技能,你还需要搭建自己的社交网络,打造自己作为开发者的影响力。", - "p11": "你可以在 Twitter、GitHub 和 <0>freeCodeCamp 论坛搭建社交网络和打造影响力。", + "p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum.", "p12": "编程愉快!" }, "upcoming-lessons": "即将上线的课程", @@ -325,7 +325,11 @@ "sorry-getting-there": "抱歉,你的代码未通过,就快要成功了。", "sorry-hang-in-there": "抱歉,你的代码未通过,坚持一下。", "sorry-dont-giveup": "抱歉,你的代码未通过,不要放弃。", - "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}" + "challenges-completed": "已完成 {{completedCount}}/{{totalChallenges}}", + "season-greetings-fcc": "Season's Greetings from the freeCodeCamp community 🎉", + "if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.", + "building-a-university": "We're Building a Free Computer Science University Degree Program", + "if-help-university": "We've already made a ton of progress. Support our charity with the long road ahead." }, "donate": { "title": "支持我们的非营利组织", @@ -350,6 +354,7 @@ "your-donation": "你的 ${{usd}} 捐款将帮助世界各地的人们学习 {{hours}} 小时。", "your-donation-2": "你的 ${{usd}} 捐款每月将帮助世界各地的人们学习 {{hours}} 小时。", "your-donation-3": "你的 ${{usd}} 捐款每年将帮助世界各地的人们学习 {{hours}} 小时。", + "become-supporter": "Become a Supporter", "duration": "成为我们非营利组织的一次性支持者", "duration-2": "成为我们非营利组织的每月定期支持者", "duration-3": "成为我们非营利组织的每年定期支持者", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "在新窗口中打开预览并聚焦于它", "step": "步骤", "steps": "步骤", - "steps-for": "{{blockTitle}} 的步骤" + "steps-for": "{{blockTitle}} 的步骤", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "申请认证之前,你必须先接受我们的《学术诚信条例》", @@ -716,5 +722,12 @@ "focus-instructions-panel": "聚焦指示面板", "navigate-previous": "跳转至上一个练习", "navigate-next": "跳转至下一个练习" + }, + "signout": { + "heading": "Sign out of your account", + "p1": "Warning: If you continue, your progress will no longer be saved.", + "p2": "This action will sign you out of your account on this device and browser session only. Please confirm if you would like to proceed.", + "certain": "Yes, sign out of my account", + "nevermind": "Nevermind, I don't want to sign out" } } diff --git a/client/i18n/locales/chinese/trending.json b/client/i18n/locales/chinese/trending.json deleted file mode 100644 index 697fdf8aa2fa02..00000000000000 --- a/client/i18n/locales/chinese/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "电脑截屏", - "article0link": "https://chinese.freecodecamp.org/news/how-to-screenshot-on-windows/", - "article1title": "程序员自学", - "article1link": "https://chinese.freecodecamp.org/news/how-i-learn-coding-for-eight-months-and-become-a-developer/", - "article2title": "AppData 文件夹", - "article2link": "https://chinese.freecodecamp.org/news/where-to-find-the-appdata-folder-in-windows-10/", - "article3title": "MongoDB Atlas", - "article3link": "https://chinese.freecodecamp.org/news/get-started-with-mongodb-atlas/", - "article4title": "Git 删除分支", - "article4link": "https://chinese.freecodecamp.org/news/how-to-delete-a-git-branch-both-locally-and-remotely/", - "article5title": "npm 是什么意思", - "article5link": "https://chinese.freecodecamp.org/news/what-is-npm-a-node-package-manager-tutorial-for-beginners/", - "article6title": "js 字符串反转", - "article6link": "https://chinese.freecodecamp.org/news/how-to-reverse-a-string-in-javascript-in-3-different-ways/", - "article7title": "谷歌小恐龙", - "article7link": "https://chinese.freecodecamp.org/news/do-you-know-the-chrome-dino-game-millions-of-people-are-playing/", - "article8title": "自学编程", - "article8link": "https://chinese.freecodecamp.org/news/how-i-went-from-newbie-to-software-engineer-in-9-months-while-working-full-time/", - "article9title": "手机上开发 Web App", - "article9link": "https://chinese.freecodecamp.org/news/how-to-code-on-your-phone-python-pydroid-android-app-tutorial/", - "article10title": "Python 编程", - "article10link": "https://chinese.freecodecamp.org/news/python-code-examples-sample-script-coding-tutorial-for-beginners/", - "article11title": "计算机语言学习顺序", - "article11link": "https://chinese.freecodecamp.org/news/what-programming-language-should-i-learn-first/", - "article12title": "什么是编程", - "article12link": "https://chinese.freecodecamp.org/news/what-is-computer-programming-defining-software-development/", - "article13title": "分布式 id 号段模式", - "article13link": "https://chinese.freecodecamp.org/news/distributed-id/", - "article14title": "Python 输出换行符", - "article14link": "https://chinese.freecodecamp.org/news/python-new-line-and-how-to-python-print-without-a-newline/", - "article15title": "GraalVM", - "article15link": "https://chinese.freecodecamp.org/news/graalvm-summary/", - "article16title": "前端后端", - "article16link": "https://chinese.freecodecamp.org/news/front-end-developer-vs-back-end-developer-definition-and-meaning-in-practice/", - "article17title": "json 文件怎么注释", - "article17link": "https://chinese.freecodecamp.org/news/json-comment/", - "article18title": "编程学校", - "article18link": "https://chinese.freecodecamp.org/news/how-we-created-a-free-coding-school-with-the-freecodecamp-curriculum/", - "article19title": "UDP 和 TCP 协议区别", - "article19link": "https://chinese.freecodecamp.org/news/tcp-vs-udp-which-is-faster/", - "article20title": "自学编程从哪学起", - "article20link": "https://chinese.freecodecamp.org/news/how-i-went-from-newbie-to-software-engineer-in-9-months-while-working-full-time/", - "article21title": "about:blank 是什么意思", - "article21link": "https://chinese.freecodecamp.org/news/about-blank-what-does-about-blank-mean-and-why-is-it-blocked-in-chrome-and-firefox/", - "article22title": "配置 VS Code", - "article22link": "https://chinese.freecodecamp.org/news/how-to-set-up-vscode-to-improve-your-productivity/", - "article23title": "cmd 删除文件", - "article23link": "https://chinese.freecodecamp.org/news/cmd-delete-folder-how-to-remove-files-and-folders-in-windows/", - "article24title": "docker 删除镜像", - "article24link": "https://chinese.freecodecamp.org/news/how-to-remove-images-in-docker/", - "article25title": "前端工程化", - "article25link": "https://chinese.freecodecamp.org/news/front-end-engineering-tutorial/", - "article26title": "Golang Benchmark", - "article26link": "https://chinese.freecodecamp.org/news/golang-benchmark/", - "article27title": "树莓派", - "article27link": "https://chinese.freecodecamp.org/news/build-a-personal-dev-server-on-a-5-dollar-raspberry-pi/", - "article28title": "二八定律", - "article28link": "https://chinese.freecodecamp.org/news/the-80-20-rule-pareto-principle/", - "article29title": "JS 隐式类型转换", - "article29link": "https://chinese.freecodecamp.org/news/javascript-implicit-type-conversion/" -} diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index c7200ce3b5d175..2ece8d81b3ddf1 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -265,7 +265,7 @@ "p8": "And this curriculum will give you thousands of hours of hands-on programming practice.", "p9": "And if you want to learn more math and computer science theory, we also have thousands of hours of video courses on <0>freeCodeCamp's YouTube channel.", "p10": "If you want to get a developer job or freelance clients, programming skills will be just part of the puzzle. You also need to build your personal network and your reputation as a developer.", - "p11": "You can do this on Twitter and GitHub, and also on <0>the freeCodeCamp forum.", + "p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum.", "p12": "Happy coding!" }, "upcoming-lessons": "Upcoming Lessons", @@ -326,7 +326,11 @@ "sorry-getting-there": "Sorry, your code does not pass. You're getting there.", "sorry-hang-in-there": "Sorry, your code does not pass. Hang in there.", "sorry-dont-giveup": "Sorry, your code does not pass. Don't give up.", - "challenges-completed": "{{completedCount}} of {{totalChallenges}} challenges completed" + "challenges-completed": "{{completedCount}} of {{totalChallenges}} challenges completed", + "season-greetings-fcc": "Season's Greetings from the freeCodeCamp community 🎉", + "if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.", + "building-a-university": "We're Building a Free Computer Science University Degree Program", + "if-help-university": "We've already made a ton of progress. Support our charity with the long road ahead." }, "donate": { "title": "Support our nonprofit", @@ -351,6 +355,7 @@ "your-donation": "Your ${{usd}} donation will provide {{hours}} hours of learning to people around the world.", "your-donation-2": "Your ${{usd}} donation will provide {{hours}} hours of learning to people around the world each month.", "your-donation-3": "Your ${{usd}} donation will provide {{hours}} hours of learning to people around the world each year.", + "become-supporter": "Become a Supporter", "duration": "Become a one-time supporter of our nonprofit.", "duration-2": "Become a monthly supporter of our nonprofit.", "duration-3": "Become an annual supporter of our nonprofit", @@ -499,7 +504,8 @@ "open-preview-in-new-window": "Open the preview in a new window and focus it", "step": "Step", "steps": "Steps", - "steps-for": "Steps for {{blockTitle}}" + "steps-for": "Steps for {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "To claim a certification, you must first accept our academic honesty policy", @@ -717,5 +723,12 @@ "focus-instructions-panel": "Focus Instructions Panel", "navigate-previous": "Navigate Previous Exercise", "navigate-next": "Navigate Next Exercise" + }, + "signout": { + "heading": "Sign out of your account", + "p1": "Warning: If you continue, your progress will no longer be saved.", + "p2": "This action will sign you out of your account on this device and browser session only. Please confirm if you would like to proceed.", + "certain": "Yes, sign out of my account", + "nevermind": "Nevermind, I don't want to sign out" } } diff --git a/client/i18n/locales/english/trending.json b/client/i18n/locales/english/trending.json deleted file mode 100644 index f62d7eedd4fda7..00000000000000 --- a/client/i18n/locales/english/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Learn JavaScript", - "article0link": "https://www.freecodecamp.org/news/learn-javascript-free-js-courses-for-beginners/", - "article1title": "Linux ln Example", - "article1link": "https://www.freecodecamp.org/news/linux-ln-how-to-create-a-symbolic-link-in-linux-example-bash-command", - "article2title": "JS document.ready()", - "article2link": "https://www.freecodecamp.org/news/javascript-document-ready-jquery-example/", - "article3title": "Delete a Row in SQL", - "article3link": "https://www.freecodecamp.org/news/how-to-delete-a-row-in-sql-example-query/", - "article4title": "Python Round to Int", - "article4link": "https://www.freecodecamp.org/news/how-to-round-numbers-up-or-down-in-python/", - "article5title": "What is msmpeng.exe?", - "article5link": "https://www.freecodecamp.org/news/what-is-antimalware-service-executable-why-is-it-high-cpu-disk-usage/", - "article6title": "Queue Data Structure", - "article6link": "https://www.freecodecamp.org/news/queue-data-structure-definition-and-java-example-code/", - "article7title": "Learn Web Development", - "article7link": "https://www.freecodecamp.org/news/learn-web-development-free-full-stack-developer-courses-for-beginners/", - "article8title": "Install Node on Windows", - "article8link": "https://www.freecodecamp.org/news/how-to-install-node-js-and-npm-on-windows-2/", - "article9title": "Remove Char from String", - "article9link": "https://www.freecodecamp.org/news/python-remove-character-from-a-string-how-to-delete-characters-from-strings/", - "article10title": "Rust Lang", - "article10link": "https://www.freecodecamp.org/news/rust-in-replit/", - "article11title": "Python Sets", - "article11link": "https://www.freecodecamp.org/news/python-set-operations-explained-with-examples/", - "article12title": "C++ Strings", - "article12link": "https://www.freecodecamp.org/news/c-string-std-string-example-in-cpp/", - "article13title": "Python map()", - "article13link": "https://www.freecodecamp.org/news/python-map-explained-with-examples/", - "article14title": "Python .pop()", - "article14link": "https://www.freecodecamp.org/news/python-pop-how-to-pop-from-a-list-or-an-array-in-python/", - "article15title": "Python arrays", - "article15link": "https://www.freecodecamp.org/news/python-array-tutorial-define-index-methods/", - "article16title": "npm Uninstall", - "article16link": "https://www.freecodecamp.org/news/npm-uninstall-how-to-remove-a-package/", - "article17title": "Insertion Sort", - "article17link": "https://www.freecodecamp.org/news/insertion-sort-algorithm-example-in-java-and-c/", - "article18title": "Python If-Else", - "article18link": "https://www.freecodecamp.org/news/python-if-else-python-conditional-syntax-example/", - "article19title": "All Caps in CSS", - "article19link": "https://www.freecodecamp.org/news/all-caps-in-css-how-to-uppercase-text-with-style/", - "article20title": "Open Task Manager on Mac", - "article20link": "https://www.freecodecamp.org/news/how-to-open-task-manager-on-mac-apple-shortcut-tutorial/", - "article21title": "parseInt() in JavaScript", - "article21link": "https://www.freecodecamp.org/news/parseint-in-javascript-js-string-to-int-example/", - "article22title": "Print statement in Python", - "article22link": "https://www.freecodecamp.org/news/print-statement-in-python-how-to-print-with-example-syntax-command/", - "article23title": "Remove Directory in Linux", - "article23link": "https://www.freecodecamp.org/news/remove-directory-in-linux-how-to-delete-a-folder-from-the-command-line/", - "article24title": "Python str.lower() Example", - "article24link": "https://www.freecodecamp.org/news/python-to-lowercase-a-string-str-lower-example/", - "article25title": "Second Monitor Not Detected", - "article25link": "https://www.freecodecamp.org/news/second-monitor-not-detected-fixed-windows10/", - "article26title": "How to Declare Strings in C", - "article26link": "https://www.freecodecamp.org/news/c-string-how-to-declare-strings-in-the-c-programming-language/", - "article27title": "How to Use .len() in Python", - "article27link": "https://www.freecodecamp.org/news/what-is-len-in-python-how-to-use-the-len-function-to-find-the-length-of-a-string/", - "article28title": "Python Convert String to Int", - "article28link": "https://www.freecodecamp.org/news/python-convert-string-to-int-how-to-cast-a-string-in-python/", - "article29title": "How to create a free website", - "article29link": "https://www.freecodecamp.org/news/how-to-create-a-website-free-of-cost-website-builder-platform-guide/" -} diff --git a/client/i18n/locales/espanol/intro.json b/client/i18n/locales/espanol/intro.json index c96bd49fb5caca..06cd2940c088a6 100644 --- a/client/i18n/locales/espanol/intro.json +++ b/client/i18n/locales/espanol/intro.json @@ -342,7 +342,7 @@ "title": "Librerías de desarrollo de la interfaz", "intro": [ "Ahora que estás familiarizado con HTML, CSS y JavaScript, mejora tus habilidades aprendiendo algunas de las librerías de interfaz más populares en la industria.", - "In the Front End Development Libraries Certification, you'll learn how to style your site quickly with Bootstrap. You'll also learn how to add logic to your CSS styles and extend them with Sass.", + "En la certificación de bibliotecas de desarrollo front-end, aprenderá cómo diseñar su sitio rápidamente con Bootstrap. También aprenderá cómo agregar lógica a sus estilos CSS y extenderlos con Sass.", "Después, construirás un carrito de compras y otras aplicaciones para aprender a crear poderosas aplicaciones de página única (SPAs) con React y Redux." ], "note": "", diff --git a/client/i18n/locales/espanol/translations.json b/client/i18n/locales/espanol/translations.json index 3d6c273abf1110..90596ce7450b85 100644 --- a/client/i18n/locales/espanol/translations.json +++ b/client/i18n/locales/espanol/translations.json @@ -9,8 +9,8 @@ "frontend": "Front End", "backend": "Back End", "view": "Ver", - "view-code": "View Code", - "view-project": "View Project", + "view-code": "Mostrar Código", + "view-project": "Mostrar Proyecto", "show-cert": "Mostrar certificación", "claim-cert": "Solicitar certificación", "save-progress": "Guardar progreso", @@ -112,7 +112,7 @@ "claim-legacy": "Una vez que hayas obtenido las siguientes certificaciones de FreeCodeCamp, podrás reclamar la {{cert}}:", "for": "Ajustes de cuenta de {{username}}", "sound-mode": "Esto agrega un placentero sonido de guitarra acústica en todo el sitio web. Obtendrás reacciones musicales a medida que escribas en el editor, completes desafíos, obtengas certificados y mucho más.", - "sound-volume": "Campfire Volume:", + "sound-volume": "Volumen de fogata:", "username": { "contains invalid characters": "El nombre de usuario \"{{username}}\" contiene caracteres inválidos", "is too short": "El nombre de usuario \"{{username}}\" es demasiado corto", @@ -264,7 +264,7 @@ "p8": "Y este currículo te brindará miles de horas de práctica de programación.", "p9": "Y si deseas aprender más sobre matemáticas y teoría de la informática, también tenemos miles de horas de cursos en video en <0>el canal de YouTube de freeCodeCamp.", "p10": "Si deseas obtener un trabajo de desarrollador o clientes independientes, las habilidades de programación serán solo una parte del rompecabezas. También necesitas construir tu red personal y tu reputación como desarrollador.", - "p11": "Puedes hacer esto en Twitter y GitHub, y también en <0>el foro de freeCodeCamp.", + "p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum.", "p12": "¡Feliz día programando!" }, "upcoming-lessons": "Próximas lecciones", @@ -284,7 +284,7 @@ "sign-in-save": "Inicia sesión para guardar tu progreso", "download-solution": "Descargar mi solución", "percent-complete": "{{percent}}% completo", - "project-complete": "Completed {{completedChallengesInBlock}} of {{totalChallengesInBlock}} certification projects", + "project-complete": "Completado {{completedChallengesInBlock}} de {{totalChallengesInBlock}} proyectos de certificación", "tried-rsa": "Si ya has probado el método <0>Leer-Buscar-Preguntar, entonces puedes pedir ayuda en el foro de freeCodeCamp.", "rsa": "Leer, buscar, preguntar", "rsa-forum": "Antes de hacer una nueva publicación por favor, comprueba si tu pregunta ya ha sido <0>respondida en el foro.", @@ -325,7 +325,11 @@ "sorry-getting-there": "Lo sentimos, tu código no pasa. Casi lo consigues.", "sorry-hang-in-there": "Lo sentimos, su código no pasa. Aguanta ahí.", "sorry-dont-giveup": "Lo sentimos, su código no pasa. No te rindas.", - "challenges-completed": "{{completedCount}} de {{totalChallenges}} desafíos completados" + "challenges-completed": "{{completedCount}} de {{totalChallenges}} desafíos completados", + "season-greetings-fcc": "Season's Greetings from the freeCodeCamp community 🎉", + "if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.", + "building-a-university": "We're Building a Free Computer Science University Degree Program", + "if-help-university": "We've already made a ton of progress. Support our charity with the long road ahead." }, "donate": { "title": "Apoya a nuestra organización sin fines de lucro", @@ -350,6 +354,7 @@ "your-donation": "Tu donación de ${{usd}} proporcionará {{hours}} horas de aprendizaje a personas de todo el mundo.", "your-donation-2": "Tu donación de ${{usd}} proporcionará {{hours}} horas de aprendizaje a personas de todo el mundo cada mes.", "your-donation-3": "Tu donación de ${{usd}} proporcionará {{hours}} horas de aprendizaje a personas de todo el mundo cada año.", + "become-supporter": "Become a Supporter", "duration": "Conviértete en un contribuyente único de nuestra organización sin fines de lucro.", "duration-2": "Conviértete en un contribuyente mensual de nuestra organización sin fines de lucro.", "duration-3": "Conviértete en un contribuyente anual de nuestra organización sin fines de lucro", @@ -431,7 +436,7 @@ }, "search": { "label": "Buscar", - "placeholder": "Search 9,000+ tutorials", + "placeholder": "Encuentra + 9,000 Tutoriales", "see-results": "Ver todos los resultados de {{searchQuery}}", "no-tutorials": "No se encontraron tutoriales", "try": "¿Buscando algo? Prueba la barra de búsqueda en esta página.", @@ -454,7 +459,7 @@ "certification-project": "Proyecto de certificación", "iframe-preview": "{{title}} Vista previa", "iframe-alert": "¡Normalmente este link te llevaría a otro sitio web! Funciona. Este es un enlace a: {{externalLink}}", - "iframe-form-submit-alert": "Normally this form would be submitted! It works. This will be submitted to: {{externalLink}}", + "iframe-form-submit-alert": "¡Normalmente, se enviaría este formulario! Funciona. Esto se enviará a: {{externalLink}}", "document-notfound": "documento no encontrado" }, "icons": { @@ -498,7 +503,8 @@ "open-preview-in-new-window": "Abrir la vista previa en una nueva ventana y enfocarla", "step": "Paso", "steps": "Pasos", - "steps-for": "Pasos para {{blockTitle}}" + "steps-for": "Pasos para {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "Para reclamar una certificación, primero debes aceptar nuestra política de honestidad académica.", @@ -557,7 +563,7 @@ "complete-project-first": "Primero debes completar el proyecto.", "local-code-save-error": "Vaya, tu código no se guardó, el almacenamiento local del navegador puede estar lleno.", "local-code-saved": "¡Guardado! Tu código ha sido guardado en el almacenamiento local de tu navegador.", - "timeline-private": "{{username}} has chosen to make their timeline private. They will need to make their timeline public in order for others to be able to view their certification.", + "timeline-private": "{{username}} has elegido hacer tu ruta de aprendizaje privada. Tendrás que hacer público tu ruta de aprendizaje para que otros puedan ver tu certificación.", "code-saved": "Tu código fue enviado a la base de datos. Estará aquí cuando regreses.", "code-save-error": "Ocurrió un error al intentar guardar tu código.", "code-save-less": "¡Espera! Tu código no fue guardado. Intenta de nuevo más tarde.", @@ -716,5 +722,12 @@ "focus-instructions-panel": "Panel de Instrucciones de enfoque", "navigate-previous": "Navegar al ejercicio anterior", "navigate-next": "Navegar siguiente ejercicio" + }, + "signout": { + "heading": "Salir de tu cuenta", + "p1": "Advertencia: Si continúas, tu progreso ya no se guardará.", + "p2": "Esta acción te hará salir de tu cuenta sólo en este dispositivo y sesión del navegador. Por favor, confirma, si deseas continuar.", + "certain": "Sí, cerrar la sesión de mi cuenta", + "nevermind": "No importa, no quiero cerrar la sesión" } } diff --git a/client/i18n/locales/espanol/trending.json b/client/i18n/locales/espanol/trending.json deleted file mode 100644 index 3ed41f7d48fd7f..00000000000000 --- a/client/i18n/locales/espanol/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Git Clone", - "article0link": "https://www.freecodecamp.org/espanol/news/como-clonar-una-branch-en-git/", - "article1title": "Métodos Agile", - "article1link": "https://www.freecodecamp.org/espanol/news/metodologia-agile/", - "article2title": "Python Main", - "article2link": "https://www.freecodecamp.org/espanol/news/python-if-name-main/", - "article3title": "Callback", - "article3link": "https://www.freecodecamp.org/news/javascript-callback-functions-what-are-callbacks-in-js-and-how-to-use-them/", - "article4title": "Debounce", - "article4link": "https://www.freecodecamp.org/espanol/news/curso-debounce-javascript-como-hacer-que-tu-js-espere/", - "article5title": "URL Encode", - "article5link": "https://www.freecodecamp.org/espanol/news/url-codificacion-como-utilizar-encodeuricomponent-javascript/", - "article6title": "Blink HTML", - "article6link": "https://www.freecodecamp.org/news/make-it-blink-html-tutorial-how-to-use-the-blink-tag-with-code-examples/", - "article7title": "Python Tupla", - "article7link": "https://www.freecodecamp.org/espanol/news/tuplas-listas-python/", - "article8title": "JavaScript Push", - "article8link": "https://www.freecodecamp.org/espanol/news/como-agregar-elementos-a-un-arreglo/", - "article9title": "Java List", - "article9link": "https://www.freecodecamp.org/news/java-list-tutorial-util-list-api-example/", - "article10title": "UX", - "article10link": "https://www.freecodecamp.org/espanol/news/diseno-ux-convertirse-en-un-disenador-de-experiencia-de-usuario/", - "article11title": "Proceso de Diseño", - "article11link": "https://www.freecodecamp.org/espanol/news/pensamiento-de-diseno-emprendedores-desarrolladores/", - "article12title": "Números Primos", - "article12link": "https://www.freecodecamp.org/espanol/news/lista-de-numeros-primos-una-grafica-con-todos-los/", - "article13title": "Diseño de Producto", - "article13link": "https://www.freecodecamp.org/espanol/news/product-design-explicado-en-un-espanol-sencillo/", - "article14title": "Digital Design", - "article14link": "https://www.freecodecamp.org/news/what-is-digital-design-and-why-does-it-matter/", - "article15title": "Juegos de Código", - "article15link": "https://www.freecodecamp.org/espanol/news/los-mejores-juegos-online-para-aprender-programar/", - "article16title": "SVM", - "article16link": "https://www.freecodecamp.org/news/svm-machine-learning-tutorial-what-is-the-support-vector-machine-algorithm-explained-with-code-examples/", - "article17title": "JavaScript forEach", - "article17link": "https://www.freecodecamp.org/news/javascript-foreach-how-to-loop-through-an-array-in-js/", - "article18title": "Google BERT", - "article18link": "https://www.freecodecamp.org/news/google-bert-nlp-machine-learning-tutorial/", - "article19title": "Create Table SQL", - "article19link": "https://www.freecodecamp.org/espanol/news/create-table-sql-server-con-ejemplo/", - "article20title": "Diseño Web Responsive", - "article20link": "https://www.freecodecamp.org/espanol/news/diseno-web-responsive-como-hacer-que-un-sitio-web-se-vea-bien-en-telefonos-y-tabletas/", - "article21title": "¿Qué es un archivo SVG?", - "article21link": "https://www.freecodecamp.org/espanol/news/que-es-svg-explicacion-de-etiquetas-imagenes/", - "article22title": "PDF Password Remover", - "article22link": "https://www.freecodecamp.org/news/pdf-password-remover-guide-how-to-remove-password-protection-from-a-pdf/", - "article23title": "¿Qué es un Archivo PDF?", - "article23link": "https://www.freecodecamp.org/espanol/news/que-es-un-archivo-pdf-como-lo-abres/", - "article24title": "What Is Python?", - "article24link": "https://www.freecodecamp.org/news/what-is-python-used-for-10-coding-uses-for-the-python-programming-language/", - "article25title": "¿Qué es TLS?", - "article25link": "https://www.freecodecamp.org/espanol/news/que-is-tls-explicado-en-espanol-simple/", - "article26title": "¿Qué es una red LAN?", - "article26link": "https://www.freecodecamp.org/espanol/news/que-es-una-red-lan-explicada-en-espanol/", - "article27title": "¿Qué es npm?", - "article27link": "https://www.freecodecamp.org/espanol/news/node-js-npm-tutorial/", - "article28title": "Ejemplos de RSync", - "article28link": "https://www.freecodecamp.org/espanol/news/rsync-ejemplos-opciones-y-copiar-archivos-atraves-ssh/", - "article29title": "Random Forest", - "article29link": "https://www.freecodecamp.org/news/how-to-use-the-tree-based-algorithm-for-machine-learning/" -} diff --git a/client/i18n/locales/german/translations.json b/client/i18n/locales/german/translations.json index 2b2c6ac71b73d7..3b59be781e9e2a 100644 --- a/client/i18n/locales/german/translations.json +++ b/client/i18n/locales/german/translations.json @@ -264,7 +264,7 @@ "p8": "Und dieser Lehrplan wird dir tausende von Stunden praktischer Programmierpraxis geben.", "p9": "Und wenn du mehr Mathematik und Informatik-Theorie lernen möchtest, haben wir auch Tausende von Stunden an Videokursen auf <0>freeCodeCamps YouTube-Kanal.", "p10": "Wenn du einen Entwicklerjob oder Freelance-Kunden bekommen möchtest, werden Programmierkenntnisse nur Teil des Puzzles sein. Du musst auch dein persönliches Netzwerk und deinen Ruf als Entwickler aufbauen.", - "p11": "Du kannst dies auf Twitter und GitHub tun, sowie im <0>freeCodeCamp-Forum.", + "p11": "You can do this on LinkedIn and GitHub, and also on <0>the freeCodeCamp forum.", "p12": "Viel Spaß beim Programmieren!" }, "upcoming-lessons": "Bevorstehende Lektionen", @@ -325,7 +325,11 @@ "sorry-getting-there": "Tut mir leid, dein Code funktioniert nicht. Du bist auf dem Weg dorthin.", "sorry-hang-in-there": "Tut mir leid, dein Code funktioniert nicht. Halte durch.", "sorry-dont-giveup": "Tut mir leid, dein Code funktioniert nicht. Gib nicht auf.", - "challenges-completed": "{{completedCount}} von {{totalChallenges}} Herausforderungen erfüllt" + "challenges-completed": "{{completedCount}} von {{totalChallenges}} Herausforderungen erfüllt", + "season-greetings-fcc": "Season's Greetings from the freeCodeCamp community 🎉", + "if-getting-value": "If you're getting a lot out of freeCodeCamp, now is a great time to donate to support our nonprofit's mission.", + "building-a-university": "We're Building a Free Computer Science University Degree Program", + "if-help-university": "We've already made a ton of progress. Support our charity with the long road ahead." }, "donate": { "title": "Unterstütze unsere Non-Profit-Organisation", @@ -350,6 +354,7 @@ "your-donation": "Deine ${{usd}} Spende ermöglicht {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt.", "your-donation-2": "Deine ${{usd}} Spende wird jeden Monat {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt ermöglichen.", "your-donation-3": "Deine ${{usd}} Spende wird jedes Jahr {{hours}} Stunden des Lernens für Menschen auf der ganzen Welt ermöglichen.", + "become-supporter": "Become a Supporter", "duration": "Werde ein einmaliger Unterstützer für unsere gemeinnützigen Organisation.", "duration-2": "Werde ein monatlicher Unterstützer für unsere gemeinnützigen Organisation.", "duration-3": "Werde ein jährlicher Unterstützer für unsere gemeinnützigen Organisation", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "Öffne die Vorschau in einem neuen Fenster und fokussiere sie", "step": "Schritt", "steps": "Schritte", - "steps-for": "Schritte für {{blockTitle}}" + "steps-for": "Schritte für {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "Um eine Zertifizierung zu erlangen, musst du zunächst unsere Richtlinie zur akademischen Ehrlichkeit akzeptieren", @@ -716,5 +722,12 @@ "focus-instructions-panel": "Fokus-Bedienfeld", "navigate-previous": "Zur vorherigen Übung navigieren", "navigate-next": "Zur nächsten Übung navigieren" + }, + "signout": { + "heading": "Sign out of your account", + "p1": "Warning: If you continue, your progress will no longer be saved.", + "p2": "This action will sign you out of your account on this device and browser session only. Please confirm if you would like to proceed.", + "certain": "Yes, sign out of my account", + "nevermind": "Nevermind, I don't want to sign out" } } diff --git a/client/i18n/locales/german/trending.json b/client/i18n/locales/german/trending.json deleted file mode 100644 index e4950611e1fa52..00000000000000 --- a/client/i18n/locales/german/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Discord Won't Open", - "article0link": "https://www.freecodecamp.org/news/discord-wont-open-on-my-pc-solved-in-windows-10/", - "article1title": "Learn Java Courses", - "article1link": "https://www.freecodecamp.org/news/learn-java-free-java-courses-for-beginners/", - "article2title": "SQL Like Statement", - "article2link": "https://www.freecodecamp.org/news/sql-like-statement-how-to-query-sql-with-wildcard/", - "article3title": "File Explorer Error", - "article3link": "https://www.freecodecamp.org/news/file-explorer-not-responding-fixed-on-windows-10-pc/", - "article4title": "Python Find in List", - "article4link": "https://www.freecodecamp.org/news/python-find-in-list-how-to-find-the-index-of-an-item-or-element-in-a-list/", - "article5title": "Functions in Python", - "article5link": "https://www.freecodecamp.org/news/python-functions-define-and-call-a-function/", - "article6title": "Python Reverse List", - "article6link": "https://www.freecodecamp.org/news/python-reverse-list-how-to-reverse-a-range-or-array/", - "article7title": "Create a Table in SQL", - "article7link": "https://www.freecodecamp.org/news/how-to-create-a-table-in-sql-postgres-and-mysql-example-query/", - "article8title": "List Index Out of Range", - "article8link": "https://www.freecodecamp.org/news/list-index-out-of-range-python-error-message-solved/", - "article9title": "Python String.Replace()", - "article9link": "https://www.freecodecamp.org/news/python-string-replace-function-in-python-for-substring-substitution/", - "article10title": "C vs C++", - "article10link": "https://www.freecodecamp.org/news/c-vs-cpp-whats-the-difference/", - "article11title": "Python JSON", - "article11link": "https://www.freecodecamp.org/news/python-json-how-to-convert-a-string-to-json/", - "article12title": "What is a PC?", - "article12link": "https://www.freecodecamp.org/news/what-is-a-pc-computer-definition-and-computer-basics-for-beginners/", - "article13title": "What is Coding?", - "article13link": "https://www.freecodecamp.org/news/computer-coding-computer-program-definition-and-code-meaning/", - "article14title": "Text Box in HTML", - "article14link": "https://www.freecodecamp.org/news/text-box-in-html-the-input-field-html-tag/", - "article15title": "Meta Tag in HTML", - "article15link": "https://www.freecodecamp.org/news/meta-tag-in-html-what-is-metadata-and-meta-description-example/", - "article16title": "Append in Python", - "article16link": "https://www.freecodecamp.org/news/append-in-python-how-to-append-to-a-list-or-an-array/", - "article17title": "Python Not Equal", - "article17link": "https://www.freecodecamp.org/news/python-not-equal-how-to-use-the-does-not-equal-operator/", - "article18title": "Linux awk Command", - "article18link": "https://www.freecodecamp.org/news/the-linux-awk-command-linux-and-unix-usage-syntax-examples/", - "article19title": "JS String Contains", - "article19link": "https://www.freecodecamp.org/news/javascript-string-contains-how-to-use-js-includes/", - "article20title": "How to Open Task Manager", - "article20link": "https://www.freecodecamp.org/news/how-to-open-task-manager-in-windows-10/", - "article21title": "Design Thinking Explained", - "article21link": "https://www.freecodecamp.org/news/the-design-thinking-process-explained/", - "article22title": "Learn Programming Courses", - "article22link": "https://www.freecodecamp.org/news/learn-programming-free-software-development-courses-for-beginners/", - "article23title": "Make a Transparent Taskbar", - "article23link": "https://www.freecodecamp.org/news/transparent-taskbar-how-to-make-a-task-bar-transparent-in-windows-10-pc-2/", - "article24title": "Install Ethernet Driver PC", - "article24link": "https://www.freecodecamp.org/news/windows-10-network-adapter-missing-how-to-install-ethernet-driver-on-pc/", - "article25title": "Default Constructor in Java", - "article25link": "https://www.freecodecamp.org/news/default-constructor-in-java/", - "article26title": "Stuck Win 10 Hard Drive", - "article26link": "https://www.freecodecamp.org/news/scanning-and-repairing-drive-how-to-fix-stuck-windows-10-pc-hard-drive/", - "article27title": "Color Codes for Grey Palette", - "article27link": "https://www.freecodecamp.org/news/color-shades-hex-code-and-rgb-for-gray-color-palette/", - "article28title": "Binary Search Tree Traversal", - "article28link": "https://www.freecodecamp.org/news/binary-search-tree-traversal-inorder-preorder-post-order-for-bst/", - "article29title": "RTC Connecting Discord Fix", - "article29link": "https://www.freecodecamp.org/news/rtc-connecting-discord-how-to-fix-the-server-error/" -} diff --git a/client/i18n/locales/italian/translations.json b/client/i18n/locales/italian/translations.json index 523227878b5337..b0a17f480911fa 100644 --- a/client/i18n/locales/italian/translations.json +++ b/client/i18n/locales/italian/translations.json @@ -264,7 +264,7 @@ "p8": "E questo curriculum ti darà migliaia di ore di pratica di programmazione.", "p9": "E se vuoi apprendere la matematica e la teoria dell'informatica, abbiamo anche migliaia di ore di corsi video sul canale YouTube di <0>freeCodeCamp.", "p10": "Se desideri trovare un lavoro di sviluppatore o come freelance, le competenze di programmazione saranno solo una parte del puzzle. Dovrai anche costruire la tua rete personale e la tua reputazione come sviluppatore.", - "p11": "Puoi farlo su Twitter e GitHub, e anche sul <0>forum freeCodeCamp.", + "p11": "Puoi farlo su LinkedIn e GitHub, e anche sul <0>forum freeCodeCamp.", "p12": "Happy coding!" }, "upcoming-lessons": "Prossime Lezioni", @@ -284,7 +284,7 @@ "sign-in-save": "Accedi per salvare i tuoi progressi", "download-solution": "Scarica la mia soluzione", "percent-complete": "{{percent}}% completato", - "project-complete": "Completed {{completedChallengesInBlock}} of {{totalChallengesInBlock}} certification projects", + "project-complete": "Completati {{completedChallengesInBlock}} di {{totalChallengesInBlock}} progetti di certificazione", "tried-rsa": "Se hai già provato il metodo <0>Leggi-Cerca-Chiedi, allora puoi chiedere aiuto sul forum freeCodeCamp.", "rsa": "Leggi, cerca, chiedi", "rsa-forum": "Prima di creare un nuovo post per favore, controlla se <0>la tua domanda ha già una risposta sul forum.", @@ -325,7 +325,11 @@ "sorry-getting-there": "Il tuo codice non è corretto. Ci sei quasi.", "sorry-hang-in-there": "Il tuo codice non è corretto. Tieni duro.", "sorry-dont-giveup": "Il tuo codice non è corretto. Non arrenderti.", - "challenges-completed": "{{completedCount}} di {{totalChallenges}} sfide completate" + "challenges-completed": "{{completedCount}} di {{totalChallenges}} sfide completate", + "season-greetings-fcc": "Saluti dalla comunità freeCodeCamp 🎉", + "if-getting-value": "Se stai trovando utile freeCodeCamp, è un ottimo momento per donare e sostenere la missione della nostra nonprofit.", + "building-a-university": "Stiamo creando un corso di laurea gratuito in Scienze Informatiche", + "if-help-university": "Abbiamo già fatto tanti progressi. Sostieni il nostro ente benefico con la lunga strada che ci attende." }, "donate": { "title": "Supporta il nostro no profit", @@ -350,6 +354,7 @@ "your-donation": "La tua donazione di ${{usd}} fornirà {{hours}} ore di apprendimento alle persone di tutto il mondo.", "your-donation-2": "La tua donazione ${{usd}} fornirà {{hours}} ore di apprendimento alle persone di tutto il mondo ogni mese.", "your-donation-3": "La tua donazione di ${{usd}} fornirà {{hours}} ore di apprendimento a persone di tutto il mondo ogni anno.", + "become-supporter": "Diventa sostenitore", "duration": "Diventa un sostenitore una tantum del nostro non-profit.", "duration-2": "Diventa un sostenitore mensile del nostro non-profit.", "duration-3": "Diventa un sostenitore annuale del nostro no profit", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "Apri l'anteprima in una nuova finestra e selezionala", "step": "Step", "steps": "Step", - "steps-for": "Step per {{blockTitle}}" + "steps-for": "Step per {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "Per richiedere una certificazione, è necessario prima accettare la nostra politica di onestà accademica", @@ -716,5 +722,12 @@ "focus-instructions-panel": "Focus sul pannello delle istruzioni", "navigate-previous": "Passa all'esercizio precedente", "navigate-next": "Passa all'esercizio successivo" + }, + "signout": { + "heading": "Esci dal tuo account", + "p1": "Attenzione: Se continui, i tuoi progressi non saranno più salvati.", + "p2": "Questa azione ti farà solo uscire dal tuo account su questo dispositivo e dalla sessione del browser. Per favore, conferma se vuoi procedere.", + "certain": "Sì, esci dal mio account", + "nevermind": "Non importa, non voglio uscire" } } diff --git a/client/i18n/locales/italian/trending.json b/client/i18n/locales/italian/trending.json deleted file mode 100644 index 68cf97c66c734d..00000000000000 --- a/client/i18n/locales/italian/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Unire CSV con Python", - "article0link": "https://www.freecodecamp.org/italian/news/come-combinare-file-multipli-in-formato-csv-con-8-righe-di-codice/", - "article1title": "Il comando Git push", - "article1link": "https://www.freecodecamp.org/italian/news/il-comando-git-push-spiegato/", - "article2title": "Centrare immagini in CSS", - "article2link": "https://www.freecodecamp.org/italian/news/come-centrare-un-immagine-usando/", - "article3title": "I codici Alt", - "article3link": "https://www.freecodecamp.org/italian/news/codici-alt/", - "article4title": "Tenere a bada il footer", - "article4link": "https://www.freecodecamp.org/italian/news/come-mantenere-il-footer-al-suo-posto/", - "article5title": "Cosa è un'API?", - "article5link": "https://www.freecodecamp.org/italian/news/cose-un-api-in-italiano-per-favore/", - "article6title": "Chiave licenza Windows10", - "article6link": "https://www.freecodecamp.org/italian/news/come-trovare-la-tua-chiave-di-licenza-di-windows-10/", - "article7title": "Live Server non funziona", - "article7link": "https://www.freecodecamp.org/italian/news/live-server-di-visual-studio-code-non-funzionante-2/", - "article8title": "Formattare in Markdown", - "article8link": "https://www.freecodecamp.org/italian/news/come-formattare-il-codice-in-markdown/", - "article9title": "Guida allo stile di fCC", - "article9link": "https://www.freecodecamp.org/italian/news/la-guida-allo-stile-di-pubblicazione-di-freecodecamp/", - "article10title": "Valori unici Python", - "article10link": "https://www.freecodecamp.org/italian/news/lista-con-valori-unici-come-ottenere-una-lista-di-valori-unici-in-python/", - "article11title": "Array.find() in JS", - "article11link": "https://www.freecodecamp.org/italian/news/tutorial-array-find-in-javascript/", - "article12title": "position in CSS", - "article12link": "https://www.freecodecamp.org/italian/news/come-usare-la-proprieta-position-in-css-per-allineare-elementi/", - "article13title": "Destrutturazione in JS", - "article13link": "https://www.freecodecamp.org/italian/news/destrutturazione-in-javascript-come-destrutturare-array-e-oggetti/", - "article14title": ".length in JS", - "article14link": "https://www.freecodecamp.org/italian/news/verificare-se-un-array-javascrit-e-vuoto/", - "article15title": "Boilerplate HTML5", - "article15link": "https://www.freecodecamp.org/italian/news/template-base-html5/", - "article16title": "Manuale JS", - "article16link": "https://www.freecodecamp.org/italian/news/manuale-javascript-per-principianti-edizione-2020/", - "article17title": "Git e GitHub", - "article17link": "https://www.freecodecamp.org/italian/news/come-usare-git-e-github-in-un-team-come-un-professionista-con-la-partecipazione-di-harry-e-hermione/", - "article18title": "Cos'è about:blank", - "article18link": "https://www.freecodecamp.org/italian/news/cosa-e-about-blank-e-come-liberartene/", - "article19title": "LS in Linux", - "article19link": "https://www.freecodecamp.org/italian/news/il-comando-ls-in-linux-come-elencare-file-e-cartelle-le-flag-di-opzione/", - "article20title": "Immagine di sfondo REACT", - "article20link": "https://www.freecodecamp.org/italian/news/come-impostare-una-immagine-di-background-in-react-usando-il-css-in-linea/", - "article21title": "Vim su Windows in PowerShell", - "article21link": "https://www.freecodecamp.org/italian/news/vim-guida-di-installazione-su-windows-come-eseguire-leditor-di-testo-vim-in-powershell-sul-tuo-pc/", - "article22title": "Processi Child di Node.js", - "article22link": "https://www.freecodecamp.org/italian/news/processi-child-di-node-js-tutto-cio-che-devi-sapere/", - "article23title": "Algoritmi di forza bruta", - "article23link": "https://www.freecodecamp.org/italian/news/algoritmi-di-forza-bruta/", - "article24title": "@property in Python", - "article24link": "https://www.freecodecamp.org/italian/news/il-decoratore-property-in-python-utilizzo-vantaggi-e-sintassi/", - "article25title": "L'algoritmo di Dijkstra", - "article25link": "https://www.freecodecamp.org/italian/news/lalgoritmo-dei-cammini-minimi-di-dijkstra-una-dettagliata-introduzione-grafica/", - "article26title": "Come annullare un Git Add", - "article26link": "https://www.freecodecamp.org/italian/news/come-annullare-un-git-add/", - "article27title": "Ripristinare schede su Chrome", - "article27link": "https://www.freecodecamp.org/italian/news/come-ripristinare-schede-su-chrome/", - "article28title": "Link nuova scheda in HTML", - "article28link": "https://www.freecodecamp.org/italian/news/html-per-aprire-un-link-in-una-nuova-scheda/", - "article29title": "Eliminare un branch di Git", - "article29link": "https://www.freecodecamp.org/italian/news/eliminare-branch-git-locale-e-remoto/" -} diff --git a/client/i18n/locales/japanese/intro.json b/client/i18n/locales/japanese/intro.json index 4711e6577d82ac..053833b850d001 100644 --- a/client/i18n/locales/japanese/intro.json +++ b/client/i18n/locales/japanese/intro.json @@ -2,7 +2,7 @@ "responsive-web-design": { "title": "(レガシー) レスポンシブウェブデザイン", "intro": [ - "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを構築するために使用する言語について学びます。コンテンツには HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", + "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを実装するために使う言語について学びます。ページの内容には HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", "初めに、HTML と CSS の基礎を学ぶために、猫の写真アプリを作ります。その後、ペンギンの絵を作りながら CSS 変数等のモダンなテクニックを学びます。そしてウェブフォームを作りながらアクセシビリティのベストプラクティスを学びます。", "最後に、Flexbox を使った Twitter カードや CSS グリッドを使った複雑なブログレイアウトの作成を通じて、さまざまな画面サイズに応答するウェブページを作成する方法を学びます。" ], @@ -12,7 +12,7 @@ "title": "HTML と HTML5 の基礎", "intro": [ "HTML は、ウェブページの構造をブラウザに伝えるために特別な構文や記法を使用するマークアップ言語です。HTML 要素は通常、コンテンツに意味を与える開始タグや終了タグを持ちます。例えば、テキストを見出し、段落、リストアイテムとして記述できる各種要素があります。", - "このコースでは、Web ページの構成ブロックとして最も一般的な HTML 要素を学ぶために、猫の写真アプリを構築します。" + "このコースでは、猫の写真アプリを作成しながら、よく使う HTML 要素を学びます。HTML 要素とは、ウェブページを組み立てるために使うブロックのようなものです。" ] }, "basic-css": { @@ -33,7 +33,7 @@ "title": "応用アクセシビリティ", "intro": [ "ウェブ開発におけるアクセシビリティとは、幅広いユーザーが理解し、移動し、対話できるコンテンツや UI (ユーザーインターフェース) のことを指します。これには視覚、聴覚、運動、認知に障害がある人も含みます。", - "このコースでは、誰もがアクセス可能な Web ページを構築するためのベストプラクティスを学びます。" + "このコースでは、誰もがアクセスしやすいウェブページを作成するためのベストプラクティスを学びます。" ] }, "responsive-web-design-principles": { @@ -53,8 +53,8 @@ "css-grid": { "title": "CSS グリッド", "intro": [ - "CSS グリッドは、複雑なレスポンシブレイアウトを簡単に構築できる新しい標準規格です。これは HTML 要素をグリッドに変えることで動作し、子要素を内部のどこにでも配置できるようになります。", - "このコースでは、ブログを含む、多様で複雑なレイアウトを構築することで、CSS グリッドの基礎を学びます。" + "CSS グリッドは、複雑なレスポンシブレイアウトを簡単に構築できる比較的新しい方法です。この方法を使うと、HTML 要素をグリッド (格子) に変換して、その中で子要素をどこにでも配置できます。", + "このコースでは、ブログを含む、多様で複雑なレイアウトを実装することで、CSS グリッドの基礎を学びます。" ] }, "responsive-web-design-projects": { @@ -69,7 +69,7 @@ "2022/responsive-web-design": { "title": "(新) レスポンシブウェブデザイン", "intro": [ - "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを構築するために使用する言語について学びます。コンテンツには HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", + "このレスポンシブウェブデザイン認定講座では、開発者がウェブページを実装するために使う言語について学びます。ページの内容には HTML (Hypertext Markup Language)、デザインには CSS (Cascading Style Sheets) を使用します。", "初めに、HTML と CSS の基礎を学ぶために、猫の写真アプリを作ります。その後、ペンギンの絵を作りながら CSS 変数等のモダンなテクニックを学びます。そしてクイズサイトを作りながらアクセシビリティのベストプラクティスを学びます。", "最後に、フレックスボックスを使ったフォトギャラリーや、CSS グリッドを使った雑誌記事のレイアウトの作成を通じて、さまざまな画面サイズに応じて表示されるウェブページの作成方法を学びます。" ], @@ -78,43 +78,43 @@ "build-a-tribute-page-project": { "title": "トリビュートページ", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", - "このプロジェクトでは、ご自身で選んだ架空または現実の題材に対するトリビュートページを構築します。" + "これは認定証の取得に必須のプロジェクトの 1 つです。", + "このプロジェクトでは、あなたが選んだ題材に関するトリビュートページを作成します。題材は架空のものでも実在のものでも構いません。" ] }, "build-a-personal-portfolio-webpage-project": { "title": "個人ポートフォリオのウェブページ", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", - "このプロジェクトでは、ご自身の個人ポートフォリオページを作成します。" + "これは認定証の取得に必須のプロジェクトの 1 つです。", + "このプロジェクトでは、あなた自身の個人ポートフォリオページを作成します。" ] }, "build-a-product-landing-page-project": { "title": "プロダクトのランディングページ", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", - "このプロジェクトでは、ご自身で選んだプロダクトを売り出すための、プロダクトのランディングページを構築します。" + "これは認定証の取得に必須のプロジェクトの 1 つです。", + "このプロジェクトでは、あなたが選んだプロダクトを売り込むためのランディングページを作成します。" ] }, "build-a-survey-form-project": { "title": "アンケートフォーム", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", - "このプロジェクトでは、ユーザーからのデータを集めるためのアンケートフォームを構築します。" + "これは認定証の取得に必須のプロジェクトの 1 つです。", + "このプロジェクトでは、ユーザーからデータを集めるためのアンケートフォームを作成します。" ] }, "build-a-technical-documentation-page-project": { "title": "技術ドキュメントページ", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", - "このプロジェクトでは、トピックの説明書または参考資料として役に立つ技術ドキュメントページを構築します。" + "これは認定証の取得に必須のプロジェクトの 1 つです。", + "このプロジェクトでは、あるトピックについての説明書または参考資料として機能する技術ドキュメントページを作成します。" ] }, "learn-html-by-building-a-cat-photo-app": { "title": "HTML の学習: 猫の写真アプリを作成する", "intro": [ "HTML タグはウェブページに構造を与えます。HTML タグで写真やボタン、また他の要素をウェブページに加えることができます。", - "このコースでは、あなた自身で猫の写真アプリを構築しながら、最もよく使われる HTML タグを学習します。" + "このコースでは、実際に手を動かして猫の写真アプリを作成しながら、最もよく使う HTML タグを学習します。" ] }, "learn-basic-css-by-building-a-cafe-menu": { @@ -342,7 +342,7 @@ "title": "フロントエンド開発ライブラリ", "intro": [ "今やあなたは HTML、CSS、そして JavaScript に精通しているので、業界内で最も一般的なフロントエンドライブラリのいくつかを学習することで技能を向上させましょう。", - "In the Front End Development Libraries Certification, you'll learn how to style your site quickly with Bootstrap. You'll also learn how to add logic to your CSS styles and extend them with Sass.", + "フロントエンド開発ライブラリ認定講座では、Bootstrap でサイトを手軽に整える方法を学習します。Sass を利用して、CSS スタイルに論理的な処理を加えて拡張する方法についても学習します。", "後ほど、ショッピングカートや他のアプリケーションを構築しながら、強力なシングルページアプリケーション (SPA) を React と Redux で作成する方法を学習します。" ], "note": "", @@ -452,35 +452,35 @@ "build-a-celestial-bodies-database-project": { "title": "天体データベース", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", + "これは認定証の取得に必須のプロジェクトの 1 つです。", "このプロジェクトでは、PostgreSQL を使用して天体のデータベースを構築します。" ] }, "build-a-number-guessing-game-project": { "title": "数当てゲーム", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", + "これは認定証の取得に必須のプロジェクトの 1 つです。", "このプロジェクトでは、Bash のシェルスクリプト、PostgreSQL、Git を使用して、数当てゲームを作成します。ゲームはターミナル内で動作し、ユーザーの情報を保存できるようにします。" ] }, "build-a-periodic-table-database-project": { "title": "周期表データベース", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", + "これは認定証の取得に必須のプロジェクトの 1 つです。", "このプロジェクトでは、周期表データベースから化学元素の情報を取得する、Bash スクリプトを作成します。" ] }, "build-a-salon-appointment-scheduler-project": { "title": "サロン予約スケジューラー", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", + "これは認定証の取得に必須のプロジェクトの 1 つです。", "このプロジェクトでは、PostgreSQL を使用して、サロンの顧客と予約を管理するインタラクティブな Bash プログラムを作成します。" ] }, "build-a-world-cup-database-project": { "title": "ワールドカップデータベース", "intro": [ - "これは認定証を獲得するために必須のプロジェクトの 1 つです。", + "これは認定証の取得に必須のプロジェクトの 1 つです。", "このプロジェクトでは、PostgreSQL データベースにワールドカップの試合情報を入力し、そこから有用な統計情報を取得する Bash スクリプトを作成します。" ] }, diff --git a/client/i18n/locales/japanese/translations.json b/client/i18n/locales/japanese/translations.json index dabe73e80ba5b3..8308831b0769af 100644 --- a/client/i18n/locales/japanese/translations.json +++ b/client/i18n/locales/japanese/translations.json @@ -9,8 +9,8 @@ "frontend": "フロントエンド", "backend": "バックエンド", "view": "表示", - "view-code": "View Code", - "view-project": "View Project", + "view-code": "コードを表示", + "view-project": "プロジェクトを表示", "show-cert": "認定証を表示", "claim-cert": "認定証を取得", "save-progress": "進行状況を保存", @@ -80,7 +80,7 @@ "big-heading-1": "プログラミングを無料で学ぶ。", "big-heading-2": "プロジェクトを完成させる。", "big-heading-3": "認定証を取得する。", - "h2-heading": "2014 年以来、40,000 人以上の freeCodeCamp.org 卒業生が、以下を含むテック企業で仕事を得ています。", + "h2-heading": "2014 年以来、4 万人を超える freeCodeCamp.org 卒業生が、以下をはじめとする IT 企業で仕事を得ています。", "hero-img-description": "韓国のローカル勉強会での freeCodeCamp 受講者", "as-seen-in": "下記で取り上げられました", "testimonials": { @@ -101,7 +101,7 @@ "testimony": "「私はいつも JavaScript を学ぶことに躓いていました。たくさんのコースを受講しましたが、freeCodeCamp に一番のめり込みました。JavaScript だけでなくデータ構造とアルゴリズムも学べることで、ソフトウェアエンジニアとして Spotify という夢の仕事を得るために必要な自信とスキルを freeCodeCamp は私に与えてくれました」" } }, - "certification-heading": "以下の認定証書を無料で取得できます。" + "certification-heading": "以下の検証済み認定証を無料で取得できます。" }, "settings": { "share-projects": "あなたの freeCodeCamp 以外のプロジェクトや記事、承認されたプルリクエストをシェアしましょう。", @@ -165,16 +165,16 @@ "reset": "すべての進行状況をリセット", "delete": "アカウントを削除", "delete-title": "アカウントを削除", - "delete-p1": "これにより、すべての進行状況とアカウント情報を含むすべてのデータが削除されます。", - "delete-p2": "削除後にお問い合わせいただいたとしても、一切のデータを復旧できかねます。", - "delete-p3": "ご意見・ご要望がございましたら、アカウント削除の前にメールにてお問い合わせください: <0>{{email}}", - "nevermind": "やめておきます、アカウントを削除したくありません", - "certain": "100% 間違いありません。このアカウントに関連するすべてのデータを削除します", + "delete-p1": "これにより、進行状況とアカウント情報を含むすべてのデータが削除されます。", + "delete-p2": "削除後にお問い合わせいただいても、一切のデータを復旧できかねます。", + "delete-p3": "ご意見・ご要望がございましたら、アカウント削除の前に <0>{{email}} までメールにてお問い合わせください。", + "nevermind": "やめておきます。アカウントを削除しません。", + "certain": "確認しました。このアカウントに関連するすべてのデータを削除します。", "reset-heading": "進行状況をリセット", "reset-p1": "これにより、あなたの進行状況、ポイント、完了したチャレンジ、プロジェクトの記録、取得した認定証、すべてが削除されます。", - "reset-p2": "削除後にお問い合わせいただいたとしても、一切のデータを復旧できかねます。", - "nevermind-2": "やめておきます、進行状況を削除したくありません", - "reset-confirm": "すべてをリセットして最初から始めます" + "reset-p2": "削除後にお問い合わせいただいても、一切のデータを復旧できかねます。", + "nevermind-2": "やめておきます。進行状況を削除しません。", + "reset-confirm": "すべてをリセットして最初から始めます。" }, "email": { "missing": "このアカウントに関連付けられているメールアドレスがありません。", @@ -187,7 +187,7 @@ "weekly": "Quincy からのメールを毎週受け取る" }, "honesty": { - "p1": "認定証書を取得する前に、以下の学問的誠実性誓約に同意する必要があります:", + "p1": "検証済み認定証を取得する前に、以下の学問的誠実性誓約に同意する必要があります:", "p2": "「私は、盗作とは他人の作品をコピーして、原作者を明示することなくまるで自分の作品であるかのように提示することであると理解しています。」", "p3": "「私は、盗作は知的不正行為であり、発覚した場合、通常は退学または退職などの処分となり得る行為であると理解しています。」", "p4": "「jQuery や Bootstrap などのオープンソースライブラリの使用や、オリジナルの作者を明示した短いコードスニペットの使用を除き、私のプロジェクトのコードの 100% は私が書いたもの、または、リアルタイムでペアプログラミングを行った他の freeCodeCamp のカリキュラム受講者とともに書かれたものです。」", @@ -253,19 +253,19 @@ "welcome-2": "freeCodeCamp.org へようこそ", "start-at-beginning": "コーディングが初めての場合は、<0>最初から開始する ことをお勧めします。", "read-this": { - "heading": "ペースを落として、まずはこちらをお読みください。", - "p1": "freeCodeCamp は、あなたが初めてソフトウェア開発者の仕事を得るための、実績のある道です。", - "p2": "40,000 人以上の人々が、完了後に開発者の仕事に就きました。その中には Google や Microsoft などの大手企業も含まれます。", - "p3": "プログラミングに慣れていないのであれば、最初から始めて、これらの認定証を上から順に獲得することをお勧めします。", - "p4": "それぞれの認定証を獲得するには、各 5 つの必修のプロジェクトを構築し、すべてのテストに合格してください。", - "p5": "獲得した認定証は、履歴書や LinkedIn に加えることができます。しかし認定証よりもさらに重要なことは道中で得る経験です。", - "p6": "圧倒される思いがするとしても、それは正常です。プログラミングは難しいのです。", + "heading": "一度立ち止まって、まずはこちらをお読みください。", + "p1": "freeCodeCamp は、あなたがソフトウェア開発者として初めての仕事を得るための、実績のある道です。", + "p2": "40,000 人以上の人々が、カリキュラム修了後に開発者の仕事に就きました。その中には Google や Microsoft などの大手企業も含まれます。", + "p3": "プログラミングに触れるのが初めてなら、カリキュラムの最初から始めて、以下の認定証を上から順に取得することをおすすめします。", + "p4": "それぞれの認定証を取得するには、必須の認定プロジェクト 5 つを完成させ、すべてのテストが成功する状態にしてください。", + "p5": "取得した認定証は、履歴書や LinkedIn に追加できます。しかし認定証よりも大事なことは、その過程で得る経験です。", + "p6": "圧倒される思いがするとしても当然です。プログラミングは難しいのです。", "p7": "練習こそが鍵になります。練習、練習、練習です。", - "p8": "そしてこのカリキュラムは何千時間もの実践的なプログラミングの経験を提供します。", - "p9": "また、数学とコンピュータサイエンス理論をさらに学びたいなら、<0>freeCodeCamp の YouTube チャンネル にも何千時間もの動画コースがあります。", - "p10": "開発者の仕事やフリーランスの顧客を得たいならば、プログラミングスキルはパズルの一部にすぎません。個人のネットワークと開発者としての名声も構築する必要があります。", - "p11": "そのために Twitter や GitHub、そして <0>freeCodeCamp フォーラム も活用してください。", - "p12": "コーディングを楽しみましょう!" + "p8": "このカリキュラムでは、何千時間もの実践的なプログラミングの経験を積むことができます。", + "p9": "また、数学やコンピュータサイエンス理論をより深く学びたいなら、<0>freeCodeCamp の YouTube チャンネル にも何千時間もの動画コースがあります。", + "p10": "開発の仕事やフリーランスの顧客を得たいなら、プログラミングスキルはパズルの一部にすぎません。人とのつながりや開発者としての評判を得ることも必要です。", + "p11": "そのためには LinkedIn や GitHub、そして <0>freeCodeCamp フォーラム も活用してください。", + "p12": "コーディングを楽しみましょう!Happy coding!" }, "upcoming-lessons": "このコースのレッスン", "learn": "学習", @@ -284,7 +284,7 @@ "sign-in-save": "サインインして進行状況を保存", "download-solution": "回答をダウンロード", "percent-complete": "{{percent}}% 完了", - "project-complete": "Completed {{completedChallengesInBlock}} of {{totalChallengesInBlock}} certification projects", + "project-complete": "{{totalChallengesInBlock}} 件中 {{completedChallengesInBlock}} 件の認定プロジェクトが完了しました", "tried-rsa": "すでに <0>Read-Search-Ask (読む - 検索する - 質問する) メソッドを試したなら、freeCodeCamp フォーラムで助けを求めることができます。", "rsa": "読む (Read)、検索する (Search)、質問する (Ask)", "rsa-forum": "新しい投稿を作成する前に同じ質問が<0>フォーラムで既に回答されていないか確認してください。", @@ -315,7 +315,7 @@ "step-2": "ステップ 2: コードを提出する", "submit-public-url": "プロジェクトが完成したら、必須のファイルをすべてパブリックリポジトリに保存し、リポジトリの URL を以下に提出してください。", "complete-both-steps": "チャレンジを終えるには、以下 2 つのステップを完了させてください。", - "runs-in-vm": "このプロジェクトは仮想マシン内で動作します。ステップ 1 を完了するには、そこで述べられたユーザーストーリーを実装し、すべてのテストに合格してください。", + "runs-in-vm": "このプロジェクトは仮想マシン内で動作します。ステップ 1 を完了するには、そこに書かれたユーザーストーリーを実装し、すべてのテストが成功するようにしてください。", "completed": "完了", "not-started": "未着手", "hint": "ヒント", @@ -325,7 +325,11 @@ "sorry-getting-there": "残念ながら、テストが通りませんでした。もう一息です。", "sorry-hang-in-there": "残念ながら、テストが通りませんでした。がんばりましょう。", "sorry-dont-giveup": "残念ながら、テストが通りませんでした。諦めないでください。", - "challenges-completed": "{{totalChallenges}} 件中 {{completedCount}} 件完了" + "challenges-completed": "{{totalChallenges}} 件中 {{completedCount}} 件完了", + "season-greetings-fcc": "freeCodeCamp コミュニティから季節のご挨拶🎉", + "if-getting-value": "freeCodeCamp が役に立ったと感じていただけたなら、寄付を通して当非営利団体の使命をご支援いただけますと幸いです。", + "building-a-university": "freeCodeCamp では無料のコンピューターサイエンス学位プログラムの設立に取り組んでいます。", + "if-help-university": "すでに順調に進んでいますが、この先更に長い道のりが待っています。ぜひ私たちのチャリティー活動をご支援ください。" }, "donate": { "title": "非営利団体を支援する", @@ -350,6 +354,7 @@ "your-donation": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを提供します。", "your-donation-2": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを毎月提供します。", "your-donation-3": "あなたの {{usd}} ドルのご寄付が、世界中の人々に {{hours}} 時間の学びを毎年提供します。", + "become-supporter": "サポーターになる", "duration": "当非営利団体に一回のご支援をいただけますと幸いです。", "duration-2": "当非営利団体に毎月のご支援をいただけますと幸いです。", "duration-3": "当非営利団体に毎年のご支援をいただけますと幸いです。", @@ -433,7 +438,7 @@ "label": "検索", "placeholder": "投稿を検索", "see-results": "{{searchQuery}} のすべての結果を見る", - "no-tutorials": "チュートリアルは見つかりませんでした", + "no-tutorials": "投稿が見つかりませんでした", "try": "何かお探しですか?このページの検索バーを試してみてください。", "no-results": "<0>{{query}} に関するものは見つかりませんでした" }, @@ -444,7 +449,7 @@ "keep-coding": "どこへ行っても、コーディングを続けてください!", "email-signup": "E メールでサインアップ", "quincy": "- freeCodeCamp.org を設立した教師、Quincy Larson", - "email-blast": "ところで、私は毎週金曜日にプログラミングとコンピュータサイエンスに関する 5 つのリンクを電子メールで送付しています。このメールを約 4 百万人が購読しています。あなたにもお届けしましょうか?", + "email-blast": "毎週金曜日に、プログラミングとコンピュータサイエンスに関する 5 つのリンクをメールで配信しています。このメールを約 4 百万人が購読しています。あなたにもお届けしましょうか?", "update-email-1": "メールアドレスを更新", "update-email-2": "メールアドレスの更新はこちら:", "email": "Eメール", @@ -454,7 +459,7 @@ "certification-project": "認定プロジェクト", "iframe-preview": "{{title}} のプレビュー", "iframe-alert": "このリンクは通常の環境では他のウェブサイトを開きます。正しく動作しています。これは {{externalLink}} へのリンクです。", - "iframe-form-submit-alert": "Normally this form would be submitted! It works. This will be submitted to: {{externalLink}}", + "iframe-form-submit-alert": "通常はこれでフォームが送信されます。正しく動作しています。フォームは {{externalLink}} へ送信されます。", "document-notfound": "ドキュメントが見つかりませんでした" }, "icons": { @@ -498,18 +503,19 @@ "open-preview-in-new-window": "プレビューを新しいウィンドウで開いてフォーカス", "step": "ステップ", "steps": "ステップ一覧", - "steps-for": "「{{blockTitle}}」のステップ一覧" + "steps-for": "「{{blockTitle}}」のステップ一覧", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "認定証を請求するには、まず学問的誠実性ポリシーに同意する必要があります。", - "really-weird": "予期しない問題が発生しました。この問題が再発する場合は、https://github.com/freeCodeCamp/freeCodeCamp/issues/new で Issue を登録することをご検討ください。", - "not-right": "問題が発生しました。レポートが生成され、freeCodeCamp.org チームへ通知されました", + "really-weird": "予期しない問題が発生しました。この問題が何度も発生するようであれば、https://github.com/freeCodeCamp/freeCodeCamp/issues/new への Issue 登録をご検討ください。", + "not-right": "問題が発生しました。レポートが生成され、freeCodeCamp.org チームへ通知されました。", "went-wrong": "問題が発生しました。ご確認の上もう一度お試しください。", "account-deleted": "アカウントが正常に削除されました", "progress-reset": "進行状況がリセットされました", - "not-authorized": "このルートを続行する権限がありません", - "could-not-find": "お探しのものが見つかりませんでした。ご確認の上もう一度お試しください", - "wrong-updating": "アカウントの更新中に問題が発生しました。ご確認の上もう一度お試しください", + "not-authorized": "このルートへのアクセス権限がありません", + "could-not-find": "お探しのページが見つかりませんでした。ご確認の上もう一度お試しください。", + "wrong-updating": "アカウント情報の更新中に問題が発生しました。ご確認の上もう一度お試しください。", "updated-preferences": "設定を更新しました", "email-invalid": "メールアドレスの形式が無効です", "email-valid": "メールアドレスは無事に変更されました。コーディングを楽しみましょう!", @@ -535,19 +541,19 @@ "refresh-needed": "支払いリクエストボタンは一度しか使用できません。ページを更新してやり直してください。", "username-not-found": "ユーザー名 \"{{username}}\" のユーザーが見つかりませんでした", "add-name": "他のユーザーが認定証を閲覧できるようにするには、このユーザーは自分の名前を自分のアカウントに追加する必要があります。", - "not-eligible": "現在、このユーザーは freeCodeCamp.org の認定証を得る資格がありません。", + "not-eligible": "現在、このユーザーは freeCodeCamp.org 認定証に不適格となっています。", "profile-private": "{{username}} さんはプロフィールを非公開に設定しています。他のユーザーが認定証を閲覧できるようにするにはプロフィールを公開する必要があります。", "certs-private": "{{username}} さんは認定証を非公開に設定しています。他のユーザーが認定証を閲覧できるようにするには認定証を公開する必要があります。", "not-honest": "{{username}} さんはまだ学問的誠実性誓約に同意していません。", "user-not-certified": "ユーザー {{username}} さんは {{cert}} の認定を受けていないようです", - "invalid-challenge": "チャレンジの提出が有効ではないようです", + "invalid-challenge": "チャレンジの提出情報が有効でないようです", "no-links-provided": "作品を検査するための有効なリンクが提示されていません。", "no-social": "ソーシャルアカウントは見つかりませんでした", "invalid-social": "無効なソーシャルアカウントです", "no-account": "{{website}} アカウントは関連付けられていません", "unlink-success": "{{website}} のリンクを解除しました", "provide-username": "ユーザー名と報告内容が入力されているか確認してください", - "report-sent": "報告は {{email}} を CC に入れてチームに送信されました", + "report-sent": "報告は {{email}} を CC に入れた状態でチームに送信されました", "certificate-missing": "表示しようとした認定証は存在しません", "create-token-err": "ユーザートークンの作成中にエラーが発生しました", "delete-token-err": "ユーザートークンの削除中にエラーが発生しました", @@ -558,9 +564,9 @@ "local-code-save-error": "コードが保存されませんでした。ブラウザのローカルストレージに空きがない可能性があります。", "local-code-saved": "保存しました!コードはブラウザのローカルストレージに保存されました。", "timeline-private": "{{username}} さんはタイムラインを非公開に設定しています。他のユーザーが認定証を閲覧できるようにするにはタイムラインを公開する必要があります。", - "code-saved": "コードがデータベースに保存されました。この画面に戻ってきた際、再表示されます。", + "code-saved": "コードをデータベースに保存しました。このページを離れても、戻ってきた際に保存したコードが再表示されます。", "code-save-error": "コードの保存中にエラーが発生しました。", - "code-save-less": "コードは保存されませんでした。数秒時間をおいて、もう一度お試しください。", + "code-save-less": "コードの保存に失敗しました。数秒後にもう一度お試しください。", "challenge-save-too-big": "コードを保存できませんでした。あなたのコードは {{user-size}} バイトですが、保存可能なコードは最大 {{max-size}} バイトです。コードを削減してもう一度お試しいただくか、https://forum.freecodecamp.org にてサポートを依頼してください。", "challenge-submit-too-big": "コードを提出できませんでした。あなたのコードは {{user-size}} バイトですが、提出可能なコードは最大 {{max-size}} バイトです。コードを削減してもう一度お試しいただくか、https://forum.freecodecamp.org にてサポートを依頼してください。", "invalid-update-flag": "禁止されたリソースにアクセスしようとしています。正当なリクエストの場合、https://forum.freecodecamp.org でサポートを依頼してください。" @@ -589,7 +595,7 @@ "fulltext": "<0>ここに <1>{{user}} <2>が freeCodeCamp.org の約 {{time}} 時間の課程に相当する <3>{{title}} <4>開発者認定講座を修了したことを証明します。", "project": { "heading-legacy-full-stack": "このレガシーフルスタック認定講座の一環として、{{user}} は以下の認定講座を修了しました:", - "heading": "この認定講座の一環として、{{user}} は以下のプロジェクトを構築し、すべての自動テストスイートに合格しました:", + "heading": "この認定講座の一環として、{{user}} は以下のプロジェクトを完成させ、すべての自動テストスイートに合格しました:", "solution": "解答", "no-solution": "解答の表示中にエラーが発生しました。 support@freeCodeCamp.org までメールにてお問い合わせください。", "source": "ソースコード", @@ -716,5 +722,12 @@ "focus-instructions-panel": "手順書パネルにフォーカス", "navigate-previous": "前の課題へ移動", "navigate-next": "次の課題へ移動" + }, + "signout": { + "heading": "アカウントからサインアウト", + "p1": "注意: サインアウト後は進行状況が保存されません。", + "p2": "この操作では、このデバイスおよびブラウザーセッションのみを対象にサインアウトされます。サインアウトしてよろしいですか?", + "certain": "はい、サインアウトします", + "nevermind": "いいえ、サインアウトしません" } } diff --git a/client/i18n/locales/japanese/trending.json b/client/i18n/locales/japanese/trending.json deleted file mode 100644 index f51bd16da5d541..00000000000000 --- a/client/i18n/locales/japanese/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Google Doodle ゲーム", - "article0link": "https://www.freecodecamp.org/japanese/news/google-doodle-games-baseball-pacman-and-more/", - "article1title": "git ブランチ削除", - "article1link": "https://www.freecodecamp.org/japanese/news/how-to-delete-a-git-branch-both-locally-and-remotely/", - "article2title": "CSS センタリング", - "article2link": "https://www.freecodecamp.org/japanese/news/how-to-center-anything-with-css-align-a-div-text-and-more/", - "article3title": "新しいタブで開く", - "article3link": "https://www.freecodecamp.org/japanese/news/how-to-use-html-to-open-link-in-new-tab/", - "article4title": "Windows フォルダ削除", - "article4link": "https://www.freecodecamp.org/japanese/news/cmd-delete-folder-how-to-remove-files-and-folders-in-windows/", - "article5title": "VSCode で C のコンパイル", - "article5link": "https://www.freecodecamp.org/japanese/news/how-to-compile-your-c-code-in-visual-studio-code/", - "article6title": "Python の改行", - "article6link": "https://www.freecodecamp.org/japanese/news/python-new-line-and-how-to-python-print-without-a-newline/", - "article7title": "Java の文字列と数値", - "article7link": "https://www.freecodecamp.org/japanese/news/java-string-to-int-how-to-convert-a-string-to-an-integer/", - "article8title": "React + Axios", - "article8link": "https://www.freecodecamp.org/japanese/news/how-to-use-axios-with-react/", - "article9title": "Python で SQL DB の操作", - "article9link": "https://www.freecodecamp.org/japanese/news/connect-python-with-sql/", - "article10title": "Node.js インストール", - "article10link": "https://www.freecodecamp.org/japanese/news/how-to-install-node-js-on-ubuntu-and-update-npm-to-the-latest-version/", - "article11title": "about:blank とは", - "article11link": "https://www.freecodecamp.org/japanese/news/about-blank-what-does-about-blank-mean-and-why-is-it-blocked-in-chrome-and-firefox/", - "article12title": "SVG 画像", - "article12link": "https://www.freecodecamp.org/japanese/news/use-svg-images-in-css-html/", - "article13title": "var, let, const", - "article13link": "https://www.freecodecamp.org/japanese/news/var-let-and-const-whats-the-difference/", - "article14title": "サブネットマスク", - "article14link": "https://www.freecodecamp.org/japanese/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/", - "article15title": "JS オブジェクト配列", - "article15link": "https://www.freecodecamp.org/japanese/news/javascript-array-of-objects-tutorial-how-to-create-update-and-loop-through-objects-using-js-array-methods/", - "article16title": "git ブランチの clone", - "article16link": "https://www.freecodecamp.org/japanese/news/git-clone-branch-how-to-clone-a-specific-branch/", - "article17title": "Windows ISO", - "article17link": "https://www.freecodecamp.org/japanese/news/how-make-a-windows-10-usb-using-your-mac-build-a-bootable-iso-from-your-macs-terminal/", - "article18title": "スタートメニュー", - "article18link": "https://www.freecodecamp.org/japanese/news/windows-10-start-menu-not-working-solved/", - "article19title": "C の書式指定子", - "article19link": "https://www.freecodecamp.org/japanese/news/format-specifiers-in-c/", - "article20title": "Python 部分文字列の取得", - "article20link": "https://www.freecodecamp.org/japanese/news/how-to-substring-a-string-in-python/", - "article21title": "Python の空リスト", - "article21link": "https://www.freecodecamp.org/japanese/news/python-empty-list-tutorial-how-to-create-an-empty-list-in-python/", - "article22title": "動画講座: Python 入門", - "article22link": "https://www.freecodecamp.org/japanese/news/learn-python-full-course-for-beginners-japanese/", - "article23title": "React の CRUD 操作", - "article23link": "https://www.freecodecamp.org/japanese/news/how-to-perform-crud-operations-using-react/", - "article24title": "Python の for ループ", - "article24link": "https://www.freecodecamp.org/japanese/news/python-for-loop-for-i-in-range-example/", - "article25title": "git add の取り消し", - "article25link": "https://www.freecodecamp.org/japanese/news/how-to-undo-a-git-add/", - "article26title": "Linux の ls コマンド", - "article26link": "https://www.freecodecamp.org/japanese/news/the-linux-ls-command-how-to-list-files-in-a-directory-with-options/", - "article27title": "freeCodeCamp の翻訳", - "article27link": "https://www.freecodecamp.org/japanese/news/help-translate-freecodecamp-language/", - "article28title": "HTML ボイラープレート", - "article28link": "https://www.freecodecamp.org/japanese/news/basic-html5-template-boilerplate-code-example/", - "article29title": "git ブランチ名変更", - "article29link": "https://www.freecodecamp.org/japanese/news/git-rename-branch-how-to-change-a-local-branch-name/" -} diff --git a/client/i18n/locales/portuguese/translations.json b/client/i18n/locales/portuguese/translations.json index 3ad3a4109c21b8..77041c9b3c0c7e 100644 --- a/client/i18n/locales/portuguese/translations.json +++ b/client/i18n/locales/portuguese/translations.json @@ -264,7 +264,7 @@ "p8": "Este currículo dará a você milhares de horas prática de programação \"mão na massa\".", "p9": "Se você quiser aprender mais matemática e teoria da ciência da computação, também temos milhares de horas de cursos em vídeo no canal do YouTube do <0>freeCodeCamp.", "p10": "Se você quiser conseguir um trabalho como desenvolvedor ou ter clientes como freelance, as habilidades de programação serão apenas parte do desafio. Você também precisa construir sua rede pessoal e sua reputação como desenvolvedor.", - "p11": "Você pode fazer isso no Twitter e GitHub, assim como no <0>fórum do freeCodeCamp .", + "p11": "Você pode fazer isso no LinkedIn e GitHub, assim como no <0>fórum do freeCodeCamp .", "p12": "Boa programação!" }, "upcoming-lessons": "Próximas lições", @@ -325,7 +325,11 @@ "sorry-getting-there": "Desculpe, seu código não passou nos testes. Você está chegando lá.", "sorry-hang-in-there": "Desculpe, seu código não passou nos testes. Você está chegando lá.", "sorry-dont-giveup": "Desculpe, seu código não passou nos testes. Não desista.", - "challenges-completed": "{{completedCount}} de {{totalChallenges}} desafios concluídos" + "challenges-completed": "{{completedCount}} de {{totalChallenges}} desafios concluídos", + "season-greetings-fcc": "Boas festas de fim de ano, da comunidade do freeCodeCamp 🎉", + "if-getting-value": "Se você está conseguindo tirar proveito do conteúdo do freeCodeCamp, agora é um ótimo momento para fazer sua doação e apoiar nossa missão sem fins lucrativos.", + "building-a-university": "Estamos criando um programa gratuito de graduação em Ciência da Computação", + "if-help-university": "Já fizemos um progresso enorme. Apoie nossa organização sem fins lucrativos com o longo caminho que temos pela frente." }, "donate": { "title": "Dê seu apoio à nossa organização sem fins lucrativos", @@ -350,6 +354,7 @@ "your-donation": "Sua doação de US${{usd}} proporcionará {{hours}} horas de aprendizado para pessoas ao redor do mundo.", "your-donation-2": "Sua doação de US${{usd}} proporcionará {{hours}} horas mensais de aprendizado para pessoas ao redor do mundo.", "your-donation-3": "Sua doação de US${{usd}} proporcionará {{hours}} horas anuais de aprendizado para pessoas ao redor do mundo.", + "become-supporter": "Torne-se um apoiador", "duration": "Torne-se um apoiador por doação única da nossa organização sem fins lucrativos.", "duration-2": "Torne-se um apoiador mensal da nossa organização sem fins lucrativos.", "duration-3": "Torne-se um apoiador anual da nossa organização sem fins lucrativos", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "Abrir a visualização em uma nova janela e focá-la", "step": "Passo", "steps": "Passos", - "steps-for": "Passos para {{blockTitle}}" + "steps-for": "Passos para {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "Para solicitar uma certificação, você precisa primeiro aceitar nossa política de honestidade acadêmica", @@ -716,5 +722,12 @@ "focus-instructions-panel": "Foco no painel de instruções", "navigate-previous": "Navegar para o exercício anterior", "navigate-next": "Navegar para o próximo exercício" + }, + "signout": { + "heading": "Sair da sua conta", + "p1": "Aviso: se continuar, seu progresso não será mais salvo.", + "p2": "Esta ação encerrará a sua conta somente neste dispositivo e na sessão do navegador. Confirme se deseja prosseguir.", + "certain": "Sim, sair da minha conta", + "nevermind": "Deixa para lá, eu não quero sair da minha conta" } } diff --git a/client/i18n/locales/portuguese/trending.json b/client/i18n/locales/portuguese/trending.json deleted file mode 100644 index 23c737c42a08f1..00000000000000 --- a/client/i18n/locales/portuguese/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0title": "Nova aba em HTML", - "article0link": "https://www.freecodecamp.org/portuguese/news/como-usar-o-html-para-abrir-um-link-em-uma-nova-aba/", - "article1title": "Máscaras de sub-rede", - "article1link": "https://www.freecodecamp.org/portuguese/news/ficha-informativa-de-sub-redes-mascara-de-sub-rede-24-30-26-27-29/", - "article2title": "40 projetos em JavaScript", - "article2link": "https://www.freecodecamp.org/portuguese/news/40-projetos-em-javascript-para-iniciantes-ideias-simples-para-comecar-a-programar-em-js/", - "article3title": "Tutorial de button onClick", - "article3link": "https://www.freecodecamp.org/portuguese/news/tutorial-sobre-button-onclick-em-html-e-evento-de-clique-em-javascript/", - "article4title": "Bot do Discord", - "article4link": "https://www.freecodecamp.org/portuguese/news/tutorial-de-criacao-de-bot-para-o-discord-em-python/", - "article5title": "Centralizar em CSS", - "article5link": "https://www.freecodecamp.org/portuguese/news/como-centralizar-tudo-com-css/", - "article6title": "Excluir pastas com o cmd", - "article6link": "https://www.freecodecamp.org/portuguese/news/excluir-pastas-no-cmd-como-remover-arquivos-e-pastas-no-windows/", - "article7title": "Imagens em CSS", - "article7link": "https://www.freecodecamp.org/portuguese/news/como-centralizar-uma-imagem-na-vertical-e-na-horizontal-com-css/", - "article8title": "25 projetos em Python", - "article8link": "https://www.freecodecamp.org/portuguese/news/25-projetos-em-python-para-iniciantes-ideias-faceis-para-comecar-a-programar-em-python/", - "article9title": "Excluir branches", - "article9link": "https://www.freecodecamp.org/portuguese/news/como-excluir-branches-locais-e-remotos-do-git/", - "article10title": "Jogo do dinossauro", - "article10link": "https://www.freecodecamp.org/portuguese/news/como-jogar-o-jogo-do-dinossauro-do-google-chrome-sem-internet-on-line-e-off-line/", - "article11title": "Menu iniciar", - "article11link": "https://www.freecodecamp.org/portuguese/news/menu-iniciar-do-windows-10-nao-funciona-resolvido/", - "article12title": "Arrays vazios em JS", - "article12link": "https://www.freecodecamp.org/portuguese/news/como-ver-se-um-array-em-javascript-esta-vazio-ou-sem-length/", - "article13title": "Caracteres especiais", - "article13link": "https://www.freecodecamp.org/portuguese/news/codigos-alt-como-digitar-caracteres-especiais-e-simbolos-do-teclado-no-windows-usando-as-teclas-alt/", - "article14title": "Python para iniciantes", - "article14link": "https://www.freecodecamp.org/portuguese/news/exemplos-de-codigo-em-python-tutorial-de-programacao-com-scripts-de-exemplo-para-iniciantes/", - "article15title": "Provedores de e-mail", - "article15link": "https://www.freecodecamp.org/portuguese/news/os-melhores-provedores-de-email-gratuitos-guia-de-servicos-de-contas-de-email-online/", - "article16title": "15 portfólios", - "article16link": "https://www.freecodecamp.org/portuguese/news/15-portfolios-de-desenvolvimento-para-a-web-inspiradores/", - "article17title": "Node.js no Ubuntu", - "article17link": "https://www.freecodecamp.org/portuguese/news/como-instalar-o-nodejs-no-ubuntu-e-atualizar-o-npm-para-a-versao-mais-recente/", - "article18title": "10 sites de desafios", - "article18link": "https://www.freecodecamp.org/portuguese/news/os-10-sites-da-web-mais-populares-com-desafios-de-programacao/", - "article19title": "Clonar branches", - "article19link": "https://www.freecodecamp.org/portuguese/news/git-clone-branch-como-clonar-um-branch-especifico/", - "article20title": "Date now em JavaScript", - "article20link": "https://www.freecodecamp.org/portuguese/news/date-now-em-javascript-como-obter-a-data-atual-em-javascript/", - "article21title": "Var, let e const em JavaScript", - "article21link": "https://www.freecodecamp.org/portuguese/news/var-let-e-const-qual-e-a-diferenca/", - "article22title": "Axios em React", - "article22link": "https://www.freecodecamp.org/portuguese/news/como-usar-o-axios-com-o-react-o-guia-definitivo-2021/", - "article23title": "ForEach em JavaScript", - "article23link": "https://www.freecodecamp.org/portuguese/news/foreach-em-javascript-como-percorrer-um-array-em-js/", - "article24title": "Fotos do Instagram", - "article24link": "https://www.freecodecamp.org/portuguese/news/como-baixar-fotos-do-instagram-salve-imagens-no-pc-ou-no-mac-a-partir-do-chrome-sem-precisar-de-ferramentas/", - "article25title": "Media queries do CSS", - "article25link": "https://www.freecodecamp.org/portuguese/news/tutorial-de-media-queries-do-css-resolucoes-padrao-breakpoints-do-css-e-tamanhos-de-telefone/", - "article26title": "Fix do Live Server no VS Code", - "article26link": "https://www.freecodecamp.org/portuguese/news/o-que-fazer-quando-o-live-server-do-visual-studio-code-nao-funciona/", - "article27title": "SQL em Python", - "article27link": "https://www.freecodecamp.org/portuguese/news/como-criar-e-manipular-bancos-de-dados-sql-com-python/", - "article28title": "Interpretadas x compiladas", - "article28link": "https://www.freecodecamp.org/portuguese/news/linguagens-de-programacao-interpretadas-x-compiladas-qual-e-a-diferenca/", - "article29title": "Imagens SVG em HTML e CSS", - "article29link": "https://www.freecodecamp.org/portuguese/news/como-usar-imagens-svg-no-css-e-no-html-um-tutorial-for-beginners/" -} diff --git a/client/i18n/locales/ukrainian/intro.json b/client/i18n/locales/ukrainian/intro.json index 3a782ab8464090..b725c1a96c7792 100644 --- a/client/i18n/locales/ukrainian/intro.json +++ b/client/i18n/locales/ukrainian/intro.json @@ -121,7 +121,7 @@ "title": "Вивчіть основи CSS, створивши меню для кафе", "intro": [ "CSS повідомляє браузеру, як зображати вашу вебсторінку. Ви можете використовувати CSS, щоб встановити колір, шрифт, розмір та інші властивості елементів HTML.", - "У цьому курсі ви вивчите CSS, розробивши дизайн меню для веб-сторінки кафе." + "У цьому курсі ви вивчите CSS, розробивши дизайн меню для вебсторінки кафе." ] }, "learn-the-css-box-model-by-building-a-rothko-painting": { @@ -658,7 +658,7 @@ "data-analysis-with-python-course": { "title": "Аналіз даних з Python", "intro": [ - "У цих комплексних відеокурсах, створених Сантьяго Басульто, ви дізнаєтесь про весь процес аналізу даних. Ви будете зчитувати дані з різних джерел (CSV, SQL, Excel), обробляти ці дані за допомогою NumPy та Pandas і візуалізувати їх за допомогою Matplotlib та Seaborn,", + "У цих комплексних відеокурсах, створених Сантьяго Басульто, ви дізнаєтесь про весь процес аналізу даних. Ви будете зчитувати дані з різних джерел (CSV, SQL, Excel), обробляти ці дані за допомогою NumPy та Pandas і візуалізовувати їх за допомогою Matplotlib та Seaborn.", "Крім того, ми включили детальний курс по Jupyter Notebook та короткий довідник з Python, щоб оновити ваші навички програмування." ] }, diff --git a/client/i18n/locales/ukrainian/translations.json b/client/i18n/locales/ukrainian/translations.json index d50ec8abe3262b..c92dcd89329fb3 100644 --- a/client/i18n/locales/ukrainian/translations.json +++ b/client/i18n/locales/ukrainian/translations.json @@ -264,7 +264,7 @@ "p8": "Ця навчальна програма дасть вам тисячі годин практики в програмуванні.", "p9": "А якщо ви бажаєте дізнатися більше про математику та теорію комп'ютерних наук, то у нас також є тисячі годин відеокурсів на <0>YouTube-каналі freeCodeCamp.", "p10": "Якщо ви хочете отримати роботу розробника або знайти клієнтів онлайн, навички програмування будуть лише частиною завдання. Вам також потрібно створити свою мережу контактів і сформувати репутацію розробника.", - "p11": "Ви можете зробити це в Twitter і GitHub, а також на <0>форумі freeCodeCamp.", + "p11": "Це можна зробити на LinkedIn та GitHub, а також на <0>форумі freeCodeCamp.", "p12": "Щасливого кодування!" }, "upcoming-lessons": "Майбутні уроки", @@ -284,7 +284,7 @@ "sign-in-save": "Увійдіть, щоб зберегти свій прогрес", "download-solution": "Завантажити моє рішення", "percent-complete": "виконано {{percent}}%", - "project-complete": "Completed {{completedChallengesInBlock}} of {{totalChallengesInBlock}} certification projects", + "project-complete": "Завершено {{completedChallengesInBlock}} із {{totalChallengesInBlock}} сертифікаційних проєктів", "tried-rsa": "Якщо ви вже спробували метод <0>читати-шукати-питати, то ви можете звернутися за допомогою на форум freeCodeCamp.", "rsa": "Читати, шукати, питати", "rsa-forum": "Перед створенням нового допису, будь ласка, перевірте, чи на ваше запитання <0>ще не відповіли на форумі.", @@ -325,7 +325,11 @@ "sorry-getting-there": "На жаль, ваш код не пройшов. Ви йдете у правильному напрямку.", "sorry-hang-in-there": "На жаль, ваш код не пройшов. Тримайтеся.", "sorry-dont-giveup": "На жаль, ваш код не пройшов. Не здавайтеся.", - "challenges-completed": "{{completedCount}} з {{totalChallenges}} завдань виконано" + "challenges-completed": "{{completedCount}} з {{totalChallenges}} завдань виконано", + "season-greetings-fcc": "Вітання від спільноти freeCodeCamp 🎉", + "if-getting-value": "Якщо ви отримуєте багато інформації завдяки freeCodeCamp, то зараз слушний час зробити внесок на підтримку нашої місії.", + "building-a-university": "Ми розробляємо безоплатну університетську програму «Комп'ютерні науки»", + "if-help-university": "Ми вже зробили багато роботи. Підтримайте довгий шлях нашої благодійної організації." }, "donate": { "title": "Підтримати нашу некомерційну організацію", @@ -350,6 +354,7 @@ "your-donation": "Ваш внесок у розмірі ${{usd}} надаватиме {{hours}} год навчання людям у всьому світі.", "your-donation-2": "Ваш внесок у розмірі ${{usd}} щомісяця надаватиме {{hours}} год навчання людям у всьому світі.", "your-donation-3": "Ваш внесок у розмірі ${{usd}} щороку надаватиме {{hours}} год навчання людям у всьому світі.", + "become-supporter": "Зробити внесок", "duration": "Станьте одноразовим спонсором нашої некомерційної організації.", "duration-2": "Станьте спонсором нашої некомерційної організації (щомісячний внесок).", "duration-3": "Станьте спонсором нашої некомерційної організації (щорічний внесок).", @@ -498,7 +503,8 @@ "open-preview-in-new-window": "Відкрити попередній перегляд у новому вікні та сфокусувати його", "step": "Крок", "steps": "Кроки", - "steps-for": "Кроки для {{blockTitle}}" + "steps-for": "Кроки для {{blockTitle}}", + "code-example": "{{codeName}} code example" }, "flash": { "honest-first": "Щоб отримати сертифікацію, ви повинні спочатку прийняти нашу політику академічної доброчесності", @@ -716,5 +722,12 @@ "focus-instructions-panel": "Панель інструкцій щодо фокусування", "navigate-previous": "Перейти до попередньої вправи", "navigate-next": "Перейти до наступної вправи" + }, + "signout": { + "heading": "Вийти з облікового запису", + "p1": "Увага: якщо ви продовжите, ваш прогрес не буде збережено.", + "p2": "Ця дія призведе до виходу з облікового запису лише на цьому пристрої та в сеансі браузера. Підтвердьте, якщо ви бажаєте продовжити.", + "certain": "Так, вийти з облікового запису", + "nevermind": "Залишитись в обліковому записі" } } diff --git a/client/i18n/locales/ukrainian/trending.json b/client/i18n/locales/ukrainian/trending.json deleted file mode 100644 index 9a9d0b76eaff90..00000000000000 --- a/client/i18n/locales/ukrainian/trending.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "article0link": "https://www.freecodecamp.org/news/what-is-javascript-javascript-code-explained-in-plain-english/", - "article0title": "What is JavaScript?", - "article1link": "https://www.freecodecamp.org/news/linux-list-processes-how-to-check-running-processes/", - "article1title": "Linux List Processes", - "article2link": "https://www.freecodecamp.org/news/web-page-text-editor-how-to-open-html-code-in-mac-textedit/", - "article2title": "Web Page Text Editor", - "article3link": "https://www.freecodecamp.org/news/what-is-open-source-software-explained-in-plain-english/", - "article3title": "What is Open Source?", - "article4link": "https://www.freecodecamp.org/news/protect-yourself-against-sim-swapping-attacks/", - "article4title": "Sim Swapping Attacks", - "article5link": "https://www.freecodecamp.org/news/rng-meaning-what-does-rng-stand-for-in-gaming/", - "article5title": "RNG Meaning in Gaming", - "article6link": "https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/", - "article6title": "Model View Controller", - "article7link": "https://www.freecodecamp.org/news/front-end-developer-what-is-front-end-development-explained-in-plain-english/", - "article7title": "Front End Development", - "article8link": "https://www.freecodecamp.org/news/what-is-a-full-stack-developer-back-end-front-end-full-stack-engineer/", - "article8title": "Full Stack Developer?", - "article9link": "https://www.freecodecamp.org/news/javascript-switch-case-js-switch-statement-example/", - "article9title": "JavaScript Switch Case", - "article10link": "https://www.freecodecamp.org/news/bash-sleep-how-to-make-a-shell-script-wait-n-seconds-example-command/", - "article10title": "Bash Sleep", - "article11link": "https://www.freecodecamp.org/news/bash-array-how-to-declare-an-array-of-strings-in-a-bash-script/", - "article11title": "Bash Array", - "article12link": "https://www.freecodecamp.org/news/what-is-a-cv-and-how-is-it-different-from-a-resume/", - "article12title": "What is a CV?", - "article13link": "https://www.freecodecamp.org/news/coding-programs-101-ways-to-learn-to-code-for-free/", - "article13title": "Coding Programs", - "article14link": "https://www.freecodecamp.org/news/how-to-exit-vim/", - "article14title": "How to Exit Vim", - "article15link": "https://www.freecodecamp.org/news/html-line-break-how-to-break-a-line-with-the-html-br-tag/", - "article15title": "HTML Line Break", - "article16link": "https://www.freecodecamp.org/news/how-to-convert-a-string-to-an-int-in-c-tutorial-with-example-code/", - "article16title": "C# String to Int", - "article17link": "https://www.freecodecamp.org/news/logical-fallacies-definition-fallacy-examples/", - "article17title": "Logical fallacies", - "article18link": "https://www.freecodecamp.org/news/javascript-online-html-css-js-code-editor-list-browser-ide-tools/", - "article18title": "JavaScript Online", - "article19link": "https://www.freecodecamp.org/news/sql-case-statement-tutorial-with-when-then-clause-example-queries/", - "article19title": "SQL Case Statement", - "article20link": "https://www.freecodecamp.org/news/javascript-tolowercase-how-to-convert-a-string-to-lowercase-and-uppercase-in-js/", - "article20title": "JavaScript toLowerCase", - "article21link": "https://www.freecodecamp.org/news/angular-ngclass-example/", - "article21title": "Angular NgClass Example", - "article22link": "https://www.freecodecamp.org/news/sql-aggregate-functions-with-example-data-queries-for-beginners/", - "article22title": "SQL Aggregate Functions", - "article23link": "https://www.freecodecamp.org/news/what-is-web-development-how-to-become-a-web-developer-career-path/", - "article23title": "What is Web Development?", - "article24link": "https://www.freecodecamp.org/news/the-best-way-to-learn-python-python-programming-tutorial-for-beginners/", - "article24title": "Best Way to Learn Python", - "article25link": "https://www.freecodecamp.org/news/word-count-in-google-docs-tutorial-counting-words-and-characters-in-a-google-doc-or-word-file/", - "article25title": "Word Count in Google Docs", - "article26link": "https://www.freecodecamp.org/news/how-to-use-node-environment-variables-with-a-dotenv-file-for-node-js-and-npm/", - "article26title": "Node Environment Variables", - "article27link": "https://www.freecodecamp.org/news/event-viewer-how-to-access-the-windows-10-activity-log/", - "article27title": "Event Viewer in Windows 10", - "article28link": "https://www.freecodecamp.org/news/combine-first-last-names-excel/", - "article28title": "Combine 1st/Last Name Excel", - "article29link": "https://www.freecodecamp.org/news/javascript-if-else-and-if-then-js-conditional-statements/", - "article29title": "JavaScript if-else & if-then" -} diff --git a/client/i18n/schema-validation.ts b/client/i18n/schema-validation.ts index 65ff5eaedb011c..02c0e86a1b6835 100644 --- a/client/i18n/schema-validation.ts +++ b/client/i18n/schema-validation.ts @@ -6,7 +6,6 @@ import linksSchema from './locales/english/links.json'; import metaTagsSchema from './locales/english/meta-tags.json'; import motivationSchema from './locales/english/motivation.json'; import translationsSchema from './locales/english/translations.json'; -import trendingSchema from './locales/english/trending.json'; type MotivationalQuotes = { quote: string; author: string }[]; @@ -113,7 +112,6 @@ const noEmptyObjectValues = ( * fetching within iterative function. */ const translationSchemaKeys = Object.keys(flattenAnObject(translationsSchema)); -const trendingSchemaKeys = Object.keys(flattenAnObject(trendingSchema)); const motivationSchemaKeys = Object.keys(flattenAnObject(motivationSchema)); const introSchemaKeys = Object.keys(flattenAnObject(introSchema)); const metaTagsSchemaKeys = Object.keys(flattenAnObject(metaTagsSchema)); @@ -137,19 +135,6 @@ const translationSchemaValidation = (languages: string[]) => { }); }; -/** - * Function that checks the trending.json file - * for each available client language. - * @param {String[]} languages List of languages to test - */ -const trendingSchemaValidation = (languages: string[]) => { - languages.forEach(language => { - void readJsonFile(language, 'trending').then(fileJson => { - schemaValidation(language, 'trending', fileJson, trendingSchemaKeys); - }); - }); -}; - /** * Function that checks the motivation.json file * for each available client language. @@ -253,7 +238,6 @@ const readJsonFile = async (language: string, fileName: string) => { const translatedLangs = availableLangs.client.filter(x => x !== 'english'); translationSchemaValidation(translatedLangs); -trendingSchemaValidation(translatedLangs); motivationSchemaValidation(translatedLangs); introSchemaValidation(translatedLangs); metaTagsSchemaValidation(translatedLangs); diff --git a/client/i18n/schema/trendingSchema.js b/client/i18n/schema/trendingSchema.js new file mode 100644 index 00000000000000..e9d06c170f3133 --- /dev/null +++ b/client/i18n/schema/trendingSchema.js @@ -0,0 +1,68 @@ +import Joi from 'joi'; + +const schema = Joi.object().keys({ + article0title: Joi.string().required(), + article0link: Joi.string().uri({ scheme: 'https' }).required(), + article1title: Joi.string().required(), + article1link: Joi.string().uri({ scheme: 'https' }).required(), + article2title: Joi.string().required(), + article2link: Joi.string().uri({ scheme: 'https' }).required(), + article3title: Joi.string().required(), + article3link: Joi.string().uri({ scheme: 'https' }).required(), + article4title: Joi.string().required(), + article4link: Joi.string().uri({ scheme: 'https' }).required(), + article5title: Joi.string().required(), + article5link: Joi.string().uri({ scheme: 'https' }).required(), + article6title: Joi.string().required(), + article6link: Joi.string().uri({ scheme: 'https' }).required(), + article7title: Joi.string().required(), + article7link: Joi.string().uri({ scheme: 'https' }).required(), + article8title: Joi.string().required(), + article8link: Joi.string().uri({ scheme: 'https' }).required(), + article9title: Joi.string().required(), + article9link: Joi.string().uri({ scheme: 'https' }).required(), + article10title: Joi.string().required(), + article10link: Joi.string().uri({ scheme: 'https' }).required(), + article11title: Joi.string().required(), + article11link: Joi.string().uri({ scheme: 'https' }).required(), + article12title: Joi.string().required(), + article12link: Joi.string().uri({ scheme: 'https' }).required(), + article13title: Joi.string().required(), + article13link: Joi.string().uri({ scheme: 'https' }).required(), + article14title: Joi.string().required(), + article14link: Joi.string().uri({ scheme: 'https' }).required(), + article15title: Joi.string().required(), + article15link: Joi.string().uri({ scheme: 'https' }).required(), + article16title: Joi.string().required(), + article16link: Joi.string().uri({ scheme: 'https' }).required(), + article17title: Joi.string().required(), + article17link: Joi.string().uri({ scheme: 'https' }).required(), + article18title: Joi.string().required(), + article18link: Joi.string().uri({ scheme: 'https' }).required(), + article19title: Joi.string().required(), + article19link: Joi.string().uri({ scheme: 'https' }).required(), + article20title: Joi.string().required(), + article20link: Joi.string().uri({ scheme: 'https' }).required(), + article21title: Joi.string().required(), + article21link: Joi.string().uri({ scheme: 'https' }).required(), + article22title: Joi.string().required(), + article22link: Joi.string().uri({ scheme: 'https' }).required(), + article23title: Joi.string().required(), + article23link: Joi.string().uri({ scheme: 'https' }).required(), + article24title: Joi.string().required(), + article24link: Joi.string().uri({ scheme: 'https' }).required(), + article25title: Joi.string().required(), + article25link: Joi.string().uri({ scheme: 'https' }).required(), + article26title: Joi.string().required(), + article26link: Joi.string().uri({ scheme: 'https' }).required(), + article27title: Joi.string().required(), + article27link: Joi.string().uri({ scheme: 'https' }).required(), + article28title: Joi.string().required(), + article28link: Joi.string().uri({ scheme: 'https' }).required(), + article29title: Joi.string().required(), + article29link: Joi.string().uri({ scheme: 'https' }).required() +}); + +export const trendingSchemaValidator = trendingObj => { + return schema.validate(trendingObj); +}; diff --git a/client/package.json b/client/package.json index 4506ea02f60723..e9a1870600e159 100644 --- a/client/package.json +++ b/client/package.json @@ -36,24 +36,24 @@ "@babel/plugin-proposal-export-default-from": "7.18.10", "@babel/plugin-proposal-function-bind": "7.18.9", "@babel/polyfill": "7.12.1", - "@babel/preset-env": "7.19.4", + "@babel/preset-env": "7.20.2", "@babel/preset-react": "7.18.6", - "@babel/standalone": "7.19.6", - "@fortawesome/fontawesome-svg-core": "6.2.0", - "@fortawesome/free-brands-svg-icons": "6.2.0", - "@fortawesome/free-solid-svg-icons": "6.2.0", + "@babel/standalone": "7.20.6", + "@fortawesome/fontawesome-svg-core": "6.2.1", + "@fortawesome/free-brands-svg-icons": "6.2.1", + "@fortawesome/free-solid-svg-icons": "6.2.1", "@fortawesome/react-fontawesome": "0.2.0", "@freecodecamp/curriculum-helpers": "1.1.0", "@freecodecamp/loop-protect": "3.0.0", "@freecodecamp/react-bootstrap": "0.32.3", "@freecodecamp/react-calendar-heatmap": "1.0.0", "@freecodecamp/strip-comments": "3.0.1", - "@growthbook/growthbook-react": "0.10.0", + "@growthbook/growthbook-react": "0.10.1", "@loadable/component": "5.15.2", "@reach/router": "1.3.4", "@sentry/gatsby": "6.19.7", - "@stripe/react-stripe-js": "1.14.0", - "@stripe/stripe-js": "1.42.0", + "@stripe/react-stripe-js": "1.16.0", + "@stripe/stripe-js": "1.46.0", "@types/react-scrollable-anchor": "0.6.1", "algoliasearch": "4.14.2", "assert": "2.0.0", @@ -62,11 +62,11 @@ "bezier-easing": "2.1.0", "browser-cookies": "1.2.0", "buffer": "6.0.3", - "chai": "4.3.6", + "chai": "4.3.7", "crypto-browserify": "3.12.0", "date-fns": "2.27.0", "enzyme": "3.11.0", - "enzyme-adapter-react-16": "1.15.6", + "enzyme-adapter-react-16": "1.15.7", "final-form": "4.20.7", "gatsby": "3.14.6", "gatsby-cli": "3.14.2", @@ -87,11 +87,10 @@ "nanoid": "3.3.4", "normalize-url": "4.5.1", "path-browserify": "1.0.1", - "postcss": "8.4.18", + "postcss": "8.4.19", "prismjs": "1.29.0", "process": "0.11.10", "prop-types": "15.8.1", - "psl": "1.9.0", "query-string": "7.0.1", "react": "16.14.0", "react-dom": "16.14.0", @@ -101,7 +100,7 @@ "react-helmet": "6.1.0", "react-hotkeys": "2.0.0", "react-i18next": "11.18.6", - "react-instantsearch-dom": "6.36.0", + "react-instantsearch-dom": "6.38.1", "react-lazy-load": "3.1.14", "react-monaco-editor": "0.40.0", "react-redux": "5.1.2", @@ -109,7 +108,7 @@ "react-responsive": "6.1.2", "react-scrollable-anchor": "0.6.1", "react-spinkit": "3.0.0", - "react-tooltip": "4.4.3", + "react-tooltip": "4.5.1", "react-transition-group": "4.4.5", "react-youtube": "7.14.0", "redux": "4.2.0", @@ -117,26 +116,26 @@ "redux-devtools-extension": "2.13.9", "redux-observable": "1.2.0", "redux-saga": "1.2.1", - "reselect": "4.1.6", + "reselect": "4.1.7", "rxjs": "6.6.7", - "sanitize-html": "2.7.2", + "sanitize-html": "2.7.3", "sass.js": "0.11.1", "sha-1": "1.0.0", "store": "2.0.12", "stream-browserify": "3.0.0", "tone": "14.7.77", - "typescript": "4.8.4", + "typescript": "4.9.3", "util": "0.12.5", "uuid": "8.3.2", "validator": "13.7.0" }, "devDependencies": { - "@babel/types": "7.19.4", - "@codesee/babel-plugin-instrument": "0.410.0", - "@codesee/tracker": "0.410.0", + "@babel/types": "7.20.5", + "@codesee/babel-plugin-instrument": "0.451.0", + "@codesee/tracker": "0.451.0", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "12.1.5", - "autoprefixer": "10.4.12", + "autoprefixer": "10.4.13", "babel-plugin-transform-imports": "2.0.0", "chokidar": "3.5.3", "copy-webpack-plugin": "9.1.0", @@ -149,7 +148,7 @@ "redux-saga-test-plan": "4.0.6", "serve": "13.0.4", "ts-node": "10.9.1", - "webpack": "5.74.0", + "webpack": "5.75.0", "webpack-cli": "4.10.0" } } diff --git a/client/src/__mocks__/gatsby.ts b/client/src/__mocks__/gatsby.ts index 7eee88b22ff6cb..5881cd6ffa61f0 100644 --- a/client/src/__mocks__/gatsby.ts +++ b/client/src/__mocks__/gatsby.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ import React from 'react'; import { GatsbyLinkProps } from 'gatsby'; const gatsby: NodeModule = jest.requireActual('gatsby'); @@ -20,10 +19,7 @@ module.exports = { }) ), withPrefix: jest.fn().mockImplementation((path: string) => { - const pathPrefix = - clientLocale === 'english' || clientLocale === 'chinese' - ? '' - : '/' + clientLocale; + const pathPrefix = clientLocale === 'english' ? '' : '/' + clientLocale; return pathPrefix + path; }), StaticQuery: jest.fn(), diff --git a/client/src/assets/icons/green-not-completed.tsx b/client/src/assets/icons/green-not-completed.tsx index ae4fbb59bcbaed..50cc88e0781978 100644 --- a/client/src/assets/icons/green-not-completed.tsx +++ b/client/src/assets/icons/green-not-completed.tsx @@ -17,9 +17,9 @@ function GreenNotCompleted(props: GreenNotCompletedProps): JSX.Element { )}
  • - {t('buttons.sign-out')} - +
  • )} diff --git a/client/src/components/Header/components/universal-nav.css b/client/src/components/Header/components/universal-nav.css index b7c1aa46d34adf..c8bed3e19d6eaf 100644 --- a/client/src/components/Header/components/universal-nav.css +++ b/client/src/components/Header/components/universal-nav.css @@ -132,7 +132,7 @@ outline: none !important; } -a.nav-link-signout:not([aria-disabled='true']):is(:hover, :focus) { +li > button.nav-link-signout:not([aria-disabled='true']):is(:hover, :focus) { background-color: var(--danger-background); color: var(--danger-color); } @@ -231,7 +231,7 @@ button.nav-link[aria-disabled='true'] { } } -/* main menu must be at least as tall as lang menu (when displayed) +/* main menu must be at least as tall as lang menu (when displayed) unless there isn't enough view port height */ .nav-list.display-lang-menu { min-height: min(var(--lang-menu-height), calc(100vh - var(--header-height))); @@ -457,7 +457,7 @@ button.nav-link[aria-disabled='true'] { left: 0; } -/* In mobile layout, prevent search input from hanging around if the +/* In mobile layout, prevent search input from hanging around if the menu is collapsed. */ .universal-nav-right #toggle-button-nav[aria-expanded='false'] @@ -466,7 +466,7 @@ button.nav-link[aria-disabled='true'] { display: none; } -/* In mobile layout, prevent search results from hanging around if the +/* In mobile layout, prevent search results from hanging around if the menu is collapsed. */ .universal-nav-right #toggle-button-nav[aria-expanded='false'] diff --git a/client/src/components/Intro/index.tsx b/client/src/components/Intro/index.tsx index 22e7bad8425383..5d33fee2f27133 100644 --- a/client/src/components/Intro/index.tsx +++ b/client/src/components/Intro/index.tsx @@ -6,7 +6,7 @@ import { Link, Spacer, Loader } from '../helpers'; import IntroDescription from './components/IntroDescription'; import './intro.css'; -import ResearchBannerx from './research-banner'; +import LearnAlert from './learn-alert'; interface IntroProps { complete?: boolean; @@ -16,6 +16,8 @@ interface IntroProps { pending?: boolean; slug?: string; username?: string; + onDonationAlertClick: () => void; + isDonating: boolean; } const Intro = ({ @@ -24,7 +26,9 @@ const Intro = ({ pending, complete, completedChallengeCount, - slug + slug, + onDonationAlertClick, + isDonating }: IntroProps): JSX.Element => { const { t } = useTranslation(); if (pending && !complete) { @@ -56,7 +60,10 @@ const Intro = ({ - + {completedChallengeCount && slug && completedChallengeCount < 15 ? (
    diff --git a/client/src/components/Intro/intro.test.tsx b/client/src/components/Intro/intro.test.tsx index dd9dbc8a967377..d1000de9fa0364 100644 --- a/client/src/components/Intro/intro.test.tsx +++ b/client/src/components/Intro/intro.test.tsx @@ -60,7 +60,9 @@ const loggedInProps = { navigate: () => jest.fn(), pending: false, slug: '/', - username: 'DevelopmentUser' + username: 'DevelopmentUser', + isDonating: false, + onDonationAlertClick: () => jest.fn() }; const loggedOutProps = { @@ -70,5 +72,7 @@ const loggedOutProps = { navigate: () => jest.fn(), pending: false, slug: '/', - username: '' + username: '', + isDonating: false, + onDonationAlertClick: () => jest.fn() }; diff --git a/client/src/components/Intro/learn-alert.tsx b/client/src/components/Intro/learn-alert.tsx new file mode 100644 index 00000000000000..30b769929bd409 --- /dev/null +++ b/client/src/components/Intro/learn-alert.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import { Alert } from '@freecodecamp/react-bootstrap'; +import { useFeature } from '@growthbook/growthbook-react'; +import { useTranslation } from 'react-i18next'; +import { Link } from '../helpers'; + +interface LearnAlertProps { + onDonationAlertClick: () => void; + isDonating: boolean; +} + +const LearnAlert = ({ + onDonationAlertClick, + isDonating +}: LearnAlertProps): JSX.Element | null => { + const { t } = useTranslation(); + const researchRecruitment = useFeature('show-research-recruitment-alert'); + const universityCreation = useFeature('university-creation-alert'); + const seasonalMessage = useFeature('seasonal-alert'); + + const researchRecruitmentAlert = ( + +

    + Launching Oct 19: freeCodeCamp is teaming up with researchers + from Stanford and UPenn to study how to help people build strong coding + habits. +

    +

    + Would you like to get involved? You’ll get free coaching from our + scientists. +

    +
    + + Learn about HabitLab + +
    +
    + ); + + const seasonalMessageAlert = ( + +

    + {t('learn.season-greetings-fcc')} +

    +

    {t('learn.if-getting-value')}

    +
    +

    + + {t('buttons.donate')} + +

    +
    + ); + + const universityCreationAlert = ( + +

    + {t('learn.building-a-university')} +

    +

    {t('learn.if-help-university')}

    +
    +

    + + {t('donate.become-supporter')} + +

    +
    + ); + + if (researchRecruitment.on) return researchRecruitmentAlert; + if (universityCreation.on && !isDonating) return universityCreationAlert; + if (seasonalMessage.on) return seasonalMessageAlert; + return null; +}; + +LearnAlert.displayName = 'LearnAlert'; + +export default LearnAlert; diff --git a/client/src/components/Intro/research-banner.tsx b/client/src/components/Intro/research-banner.tsx deleted file mode 100644 index 324b146bb4bf3b..00000000000000 --- a/client/src/components/Intro/research-banner.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { Alert, Button } from '@freecodecamp/react-bootstrap'; -import { useFeature } from '@growthbook/growthbook-react'; - -const ResearchBannerx = (): JSX.Element | null => { - const feature = useFeature('show-research-recruitment-alert'); - return feature.on ? ( - -

    - Launching Oct 19: freeCodeCamp is teaming up with researchers - from Stanford and UPenn to study how to help people build strong coding - habits. -

    -

    - Would you like to get involved? You’ll get free coaching from our - scientists. -

    -
    - -
    -
    - ) : null; -}; - -ResearchBannerx.displayName = 'ResearchBannerx'; - -export default ResearchBannerx; diff --git a/client/src/components/Map/__snapshots__/map.test.tsx.snap b/client/src/components/Map/__snapshots__/map.test.tsx.snap deleted file mode 100644 index 078190f95fa774..00000000000000 --- a/client/src/components/Map/__snapshots__/map.test.tsx.snap +++ /dev/null @@ -1,535 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` snapshot: Map 1`] = ` - -`; diff --git a/client/src/components/Map/index.tsx b/client/src/components/Map/index.tsx index 01ea334f727106..a3e0fb8795ae47 100644 --- a/client/src/components/Map/index.tsx +++ b/client/src/components/Map/index.tsx @@ -1,141 +1,121 @@ -import { graphql, useStaticQuery } from 'gatsby'; import i18next from 'i18next'; import React from 'react'; import { SuperBlocks } from '../../../../config/certification-settings'; +import { + CurriculumMaps, + getAuditedSuperBlocks, + getNotAuditedSuperBlocks, + superBlockOrder +} from '../../../../config/superblock-order'; +import { Languages } from '../../../../config/i18n'; import envData from '../../../../config/env.json'; -import { isAuditedCert } from '../../../../utils/is-audited'; import { generateIconComponent } from '../../assets/icons'; import LinkButton from '../../assets/icons/link-button'; -import { ChallengeNode } from '../../redux/prop-types'; import { Link, Spacer } from '../helpers'; +import { getSuperBlockTitleForMap } from '../../utils/superblock-map-titles'; import './map.css'; -const { curriculumLocale } = envData; +const { curriculumLocale, showNewCurriculum, showUpcomingChanges } = envData; interface MapProps { currentSuperBlock?: SuperBlocks | null; forLanding?: boolean; } -interface MapData { - allChallengeNode: { - nodes: ChallengeNode[]; - }; -} - -function createSuperBlockTitle(superBlock: SuperBlocks) { - const superBlockTitle = i18next.t(`intro:${superBlock}.title`); - return superBlock === 'coding-interview-prep' - ? superBlockTitle - : i18next.t('learn.cert-map-estimates.certs', { - title: superBlockTitle - }); -} - const linkSpacingStyle = { display: 'flex', justifyContent: 'space-between', - alignItems: 'center' + alignItems: 'center', + gap: '15px' }; -function renderLandingMap(nodes: ChallengeNode[]) { - nodes = nodes.filter( - ({ challenge }) => challenge.superBlock !== SuperBlocks.CodingInterviewPrep +function MapLi({ + superBlock, + landing = false +}: { + superBlock: SuperBlocks; + landing: boolean; +}) { + return ( +
  • + +
    + {generateIconComponent(superBlock, 'map-icon')} + {getSuperBlockTitleForMap(superBlock)} +
    + {landing && } + +
  • ); +} + +function renderLandingMap() { + const landingSuperOrder = + superBlockOrder[curriculumLocale as Languages][CurriculumMaps.Landing]; + return (
      - {nodes.map(({ challenge }, i) => ( -
    • - -
      - {generateIconComponent(challenge.superBlock, 'map-icon')} - {i18next.t(`intro:${challenge.superBlock}.title`)} -
      - - -
    • + {landingSuperOrder.map((superBlock, i) => ( + ))}
    ); } -function renderLearnMap( - nodes: ChallengeNode[], - currentSuperBlock: MapProps['currentSuperBlock'] -) { - nodes = nodes.filter( - ({ challenge }) => challenge.superBlock !== currentSuperBlock +function renderLearnMap(currentSuperBlock: MapProps['currentSuperBlock']) { + const tempAuditedSuperBlocks = getAuditedSuperBlocks({ + language: curriculumLocale, + showNewCurriculum: showNewCurriculum.toString(), + showUpcomingChanges: showUpcomingChanges.toString() + }); + const tempNotAuditedSuperBlocks = getNotAuditedSuperBlocks({ + language: curriculumLocale, + showNewCurriculum: showNewCurriculum.toString(), + showUpcomingChanges: showUpcomingChanges.toString() + }); + + const auditedSuperBlocks = tempAuditedSuperBlocks.filter( + superBlock => superBlock !== currentSuperBlock + ); + + const notAuditedSuperBlocks = tempNotAuditedSuperBlocks.filter( + superBlock => superBlock !== currentSuperBlock ); - return curriculumLocale === 'english' ? ( + + return (
      - {nodes.map(({ challenge }, i) => ( -
    • - -
      - {generateIconComponent(challenge.superBlock, 'map-icon')} - {createSuperBlockTitle(challenge.superBlock)} -
      - -
    • + {/* audited superblocks */} + {auditedSuperBlocks.map((superBlock, i) => ( + ))} -
    - ) : ( -
      - {nodes - .filter(({ challenge }) => - isAuditedCert(curriculumLocale, challenge.superBlock) - ) - .map(({ challenge }, i) => ( -
    • - -
      - {generateIconComponent(challenge.superBlock, 'map-icon')} - {createSuperBlockTitle(challenge.superBlock)} -
      - -
    • - ))} -
      -
      -

      {i18next.t('learn.help-translate')}

      - - {i18next.t('learn.help-translate-link')} - - -
      - {nodes - .filter( - ({ challenge }) => - !isAuditedCert(curriculumLocale, challenge.superBlock) - ) - .map(({ challenge }, i) => ( -
    • + + {/* has not audited superblocks */} + {notAuditedSuperBlocks.length > 0 && ( + <> + {' '} +
      +
      +

      + {i18next.t('learn.help-translate')}{' '} +

      -
      - {generateIconComponent(challenge.superBlock, 'map-icon')} - {createSuperBlockTitle(challenge.superBlock)} -
      + {i18next.t('learn.help-translate-link')} -
    • - ))} + +
    + + )} + + {/* not audited superblocks */} + {notAuditedSuperBlocks.map((superBlock, i) => ( + + ))} ); } @@ -144,39 +124,9 @@ export function Map({ forLanding = false, currentSuperBlock = null }: MapProps): React.ReactElement { - /* - * this query gets the first challenge from each block and the first block - * from each superblock, leaving you with one challenge from each - * superblock - */ - const data: MapData = useStaticQuery(graphql` - query SuperBlockNodes { - allChallengeNode( - sort: { fields: [challenge___superOrder] } - filter: { challenge: { order: { eq: 0 }, challengeOrder: { eq: 0 } } } - ) { - nodes { - challenge { - superBlock - dashedName - } - } - } - } - `); - - const nodes = data.allChallengeNode.nodes; - const temp = [ - nodes[0], - nodes[12], - ...nodes.filter((_, i) => i !== 0 && i !== 12) - ]; - return (
    - {forLanding - ? renderLandingMap(temp) - : renderLearnMap(temp, currentSuperBlock)} + {forLanding ? renderLandingMap() : renderLearnMap(currentSuperBlock)}
    ); } diff --git a/client/src/components/Map/map.test.tsx b/client/src/components/Map/map.test.tsx deleted file mode 100644 index 336608bdf073d2..00000000000000 --- a/client/src/components/Map/map.test.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { render } from '@testing-library/react'; -import { useStaticQuery } from 'gatsby'; -import React from 'react'; - -import mockChallengeNodes from '../../__mocks__/challenge-nodes'; -import { Map } from '.'; - -beforeEach(() => { - (useStaticQuery as jest.Mock).mockImplementationOnce(() => ({ - allChallengeNode: { - nodes: mockChallengeNodes - } - })); -}); - -// set .scrollTo to avoid errors in default test environment -window.scrollTo = jest.fn(); - -test(' snapshot', () => { - const { container } = render(); - - expect(container).toMatchSnapshot('Map'); -}); - -const props = { - forLanding: true -}; diff --git a/client/src/components/create-language-redirect.test.ts b/client/src/components/create-language-redirect.test.ts index ac4ca35c2ab66f..48c2a7c899b81a 100644 --- a/client/src/components/create-language-redirect.test.ts +++ b/client/src/components/create-language-redirect.test.ts @@ -9,7 +9,7 @@ describe('createLanguageRedirect for clientLocale === english', () => { const currentPageURL = 'https://www.freecodecamp.org/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; const chinesePageURL = - 'https://chinese.freecodecamp.org/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; + 'https://www.freecodecamp.org/chinese/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; const espanolPageURL = 'https://www.freecodecamp.org/espanol/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; const chineseTraditionalPageURL = @@ -54,7 +54,7 @@ describe('createLanguageRedirect for clientLocale === english', () => { describe('settings page', () => { const currentPageURL = 'https://www.freecodecamp.org/settings'; - const chinesePageURL = 'https://chinese.freecodecamp.org/settings'; + const chinesePageURL = 'https://www.freecodecamp.org/chinese/settings'; const espanolPageURL = 'https://www.freecodecamp.org/espanol/settings'; const chineseTraditionalPageURL = 'https://www.freecodecamp.org/chinese-traditional/settings'; @@ -103,7 +103,7 @@ describe('createLanguageRedirect for clientLocale === chinese', () => { describe('challenge page', () => { const currentPageURL = - 'https://chinese.freecodecamp.org/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; + 'https://www.freecodecamp.org/chinese/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; const englishPageURL = 'https://www.freecodecamp.org/learn/responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element'; const espanolPageURL = @@ -149,7 +149,7 @@ describe('createLanguageRedirect for clientLocale === chinese', () => { }); describe('settings page', () => { - const currentPageURL = 'https://chinese.freecodecamp.org/settings'; + const currentPageURL = 'https://www.freecodecamp.org/chinese/settings'; const englishPageURL = 'https://www.freecodecamp.org/settings'; const espanolPageURL = 'https://www.freecodecamp.org/espanol/settings'; const chineseTraditionalPageURL = diff --git a/client/src/components/create-language-redirect.ts b/client/src/components/create-language-redirect.ts index b7a529d03b98e8..b626c9e1c6fa97 100644 --- a/client/src/components/create-language-redirect.ts +++ b/client/src/components/create-language-redirect.ts @@ -13,12 +13,10 @@ const createLanguageRedirect = ({ .filter(item => (item !== clientLocale && item !== lang ? item : '')) .join('/'); - const hostTail = window?.location?.host.split('.').slice(1).join('.'); - const nextClient = lang !== 'chinese' ? 'www' : 'chinese'; - const nextLocation = `${window?.location?.protocol}//${nextClient}.${hostTail}`; + const hostTail = window?.location?.host; + const nextLocation = `${window?.location?.protocol}//${hostTail}`; - if (lang === 'english' || lang === 'chinese') - return `${nextLocation}/${path}`; + if (lang === 'english') return `${nextLocation}/${path}`; return `${nextLocation}/${lang}/${path}`; }; diff --git a/client/src/components/layouts/default.tsx b/client/src/components/layouts/default.tsx index 34d92382647936..f0e7b4ec673861 100644 --- a/client/src/components/layouts/default.tsx +++ b/client/src/components/layouts/default.tsx @@ -30,7 +30,7 @@ import { UserFetchState, User } from '../../redux/prop-types'; import BreadCrumb from '../../templates/Challenges/components/bread-crumb'; import Flash from '../Flash'; import { flashMessageSelector, removeFlashMessage } from '../Flash/redux'; - +import SignoutModal from '../signout-modal'; import Footer from '../Footer'; import Header from '../Header'; import OfflineWarning from '../OfflineWarning'; @@ -219,6 +219,7 @@ class DefaultLayout extends Component { removeFlashMessage={removeFlashMessage} /> ) : null} + {isChallenge && (
    div:only-child { + height: 100%; + overflow: auto; +} + +#content-start { + min-height: 0; + height: 100%; +} + +#content-start > div { + height: 100%; } h1 { @@ -460,7 +477,7 @@ fieldset[disabled] .btn-primary.focus { .map-icon { width: 35px; max-height: 45px; - margin-right: 20px; + margin-inline: 5px; } .cert-header-icon { @@ -775,6 +792,20 @@ blockquote .small { border-color: #31708f; } +.annual-donation-alert { + background: linear-gradient( + -10deg, + rgba(217, 237, 247, 1) 35%, + rgba(237, 202, 216, 0) 75%, + rgb(255 215 224) 100% + ), + radial-gradient( + circle, + rgba(255, 202, 225, 1) 0%, + rgba(218, 234, 252, 1) 100% + ); +} + /* gatsby 404 */ #search { background-color: var(--quaternary-background); diff --git a/client/src/components/layouts/index.ts b/client/src/components/layouts/index.ts deleted file mode 100644 index c97db04f81187a..00000000000000 --- a/client/src/components/layouts/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as CertificationLayout } from './certification'; -export { default as DefaultLayout } from './default'; -export { default as TcIntegrationLayout } from './tc-integration'; -export { default as LearnLayout } from './learn'; diff --git a/client/src/components/layouts/learn.css b/client/src/components/layouts/learn.css index 292b987c9c36fa..0f0a1089c6ae85 100644 --- a/client/src/components/layouts/learn.css +++ b/client/src/components/layouts/learn.css @@ -1,9 +1,17 @@ +#learn-app-wrapper, +#learn-app-wrapper .desktop-layout, +#learn-app-wrapper .reflex-container.vertical { + height: 100%; +} + #learn-app-wrapper .desktop-layout { display: flex; flex-direction: column; - height: calc( - 100vh - var(--header-height, 0px) - var(--flash-message-height, 0px) - ); +} + +#learn-app-wrapper .reflex-container.vertical { + min-height: 0; + flex-grow: 1; } #learn-app-wrapper .reflex-container.vertical > .reflex-splitter, diff --git a/client/src/components/signout-modal/index.tsx b/client/src/components/signout-modal/index.tsx new file mode 100644 index 00000000000000..ec07cf3be54cd1 --- /dev/null +++ b/client/src/components/signout-modal/index.tsx @@ -0,0 +1,100 @@ +import React from 'react'; +import { Button, Modal } from '@freecodecamp/react-bootstrap'; +import { bindActionCreators, Dispatch, AnyAction } from 'redux'; +import { createSelector } from 'reselect'; +import { connect } from 'react-redux'; +import { useTranslation } from 'react-i18next'; + +import { ButtonSpacer } from '../helpers'; +import { hardGoTo as navigate, closeSignoutModal } from '../../redux/actions'; +import { isSignoutModalOpenSelector } from '../../redux/selectors'; +import { apiLocation } from '../../../../config/env.json'; + +import './signout-modal.css'; + +const mapStateToProps = createSelector( + isSignoutModalOpenSelector, + (show: boolean) => ({ + show + }) +); + +const mapDispatchToProps = (dispatch: Dispatch) => + bindActionCreators( + { + navigate, + closeSignoutModal + }, + dispatch + ); + +type SignoutModalProps = { + navigate: (path: string) => void; + closeSignoutModal: () => void; + show: boolean; +}; + +function SignoutModal(props: SignoutModalProps): JSX.Element { + const { show, closeSignoutModal, navigate } = props; + const { t } = useTranslation(); + + const handleModalHide = () => { + closeSignoutModal(); + }; + + const handleSignout = () => { + closeSignoutModal(); + navigate(`${apiLocation}/signout`); + }; + + return ( + + + + {t('signout.heading')} + + + +

    + {t('signout.p1')} +

    +

    {t('signout.p2')}

    +
    + + + +
    +
    + ); +} + +SignoutModal.displayName = 'SignoutModal'; + +export default connect(mapStateToProps, mapDispatchToProps)(SignoutModal); diff --git a/client/src/components/signout-modal/signout-modal.css b/client/src/components/signout-modal/signout-modal.css new file mode 100644 index 00000000000000..11c065b7c0b081 --- /dev/null +++ b/client/src/components/signout-modal/signout-modal.css @@ -0,0 +1,12 @@ +.btn-signout { + background-color: var(--danger-color); + color: var(--danger-background); + border-color: var(--danger-background); +} + +.btn-signout:hover, +.btn-signout:focus { + color: var(--danger-color); + background-color: var(--danger-background); + border-color: var(--danger-background); +} diff --git a/client/src/pages/learn.tsx b/client/src/pages/learn.tsx index 96b1faa7fd8259..b534563989170f 100644 --- a/client/src/pages/learn.tsx +++ b/client/src/pages/learn.tsx @@ -5,6 +5,7 @@ import Helmet from 'react-helmet'; import { useTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; +import { bindActionCreators, Dispatch } from 'redux'; import Intro from '../components/Intro'; import Map from '../components/Map'; @@ -16,6 +17,8 @@ import { userFetchStateSelector } from '../redux/selectors'; +import { executeGA } from '../redux/actions'; + interface FetchState { pending: boolean; complete: boolean; @@ -26,6 +29,7 @@ interface User { name: string; username: string; completedChallengeCount: number; + isDonating: boolean; } const mapStateToProps = createSelector( @@ -48,6 +52,7 @@ interface LearnPageProps { fetchState: FetchState; state: Record; user: User; + executeGA: (payload: Record) => void; data: { challengeNode: { challenge: { @@ -57,10 +62,14 @@ interface LearnPageProps { }; } +const mapDispatchToProps = (dispatch: Dispatch) => + bindActionCreators({ executeGA }, dispatch); + function LearnPage({ isSignedIn, + executeGA, fetchState: { pending, complete }, - user: { name = '', completedChallengeCount = 0 }, + user: { name = '', completedChallengeCount = 0, isDonating = false }, data: { challengeNode: { challenge: { @@ -71,6 +80,15 @@ function LearnPage({ }: LearnPageProps) { const { t } = useTranslation(); + const onDonationAlertClick = () => { + executeGA({ + type: 'event', + data: { + category: 'Donation Related', + action: `learn donation alert click` + } + }); + }; return ( @@ -84,6 +102,8 @@ function LearnPage({ name={name} pending={pending} slug={slug} + onDonationAlertClick={onDonationAlertClick} + isDonating={isDonating} /> @@ -96,7 +116,7 @@ function LearnPage({ LearnPage.displayName = 'LearnPage'; -export default connect(mapStateToProps, null)(LearnPage); +export default connect(mapStateToProps, mapDispatchToProps)(LearnPage); export const query = graphql` query FirstChallenge { diff --git a/client/src/pages/learn/back-end-development-and-apis/basic-node-and-express/index.md b/client/src/pages/learn/back-end-development-and-apis/basic-node-and-express/index.md index 292abe08289e05..31c46e3db7d9bb 100644 --- a/client/src/pages/learn/back-end-development-and-apis/basic-node-and-express/index.md +++ b/client/src/pages/learn/back-end-development-and-apis/basic-node-and-express/index.md @@ -15,6 +15,13 @@ Node.js is a JavaScript runtime that allows developers to write backend (server- Express, while not included with Node.js, is another module often used with it. Express runs between the server created by Node.js and the frontend pages of a web application. Express also handles an application's routing. Routing directs users to the correct page based on their interaction with the application. While there are alternatives to using Express, its simplicity makes it a good place to begin when learning the interaction between a backend powered by Node.js and the frontend. -Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing. +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using this link or clone this repository on GitHub! If you use Replit, remember to save the link to your project somewhere safe! diff --git a/client/src/pages/learn/back-end-development-and-apis/managing-packages-with-npm/index.md b/client/src/pages/learn/back-end-development-and-apis/managing-packages-with-npm/index.md index 38c28434e886a1..43ac12c693f35a 100644 --- a/client/src/pages/learn/back-end-development-and-apis/managing-packages-with-npm/index.md +++ b/client/src/pages/learn/back-end-development-and-apis/managing-packages-with-npm/index.md @@ -14,6 +14,14 @@ npm saves packages in a folder named node_modules. These packages c 2. locally within a project's own node_modules folder, accessible only to that project. Most developers prefer to install packages local to each project to create a separation between the dependencies of different projects. -Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing. + +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using this link or clone this repository on GitHub! If you use Replit, remember to save the link to your project somewhere safe! diff --git a/client/src/pages/learn/back-end-development-and-apis/mongodb-and-mongoose/index.md b/client/src/pages/learn/back-end-development-and-apis/mongodb-and-mongoose/index.md index faae71b2f44683..c4f27f197ad7ee 100644 --- a/client/src/pages/learn/back-end-development-and-apis/mongodb-and-mongoose/index.md +++ b/client/src/pages/learn/back-end-development-and-apis/mongodb-and-mongoose/index.md @@ -16,7 +16,14 @@ While there are many non-relational databases, Mongo's use of JSON as its docume Mongoose.js is an npm module for Node.js that allows you to write objects for Mongo as you would in JavaScript. This can make it easier to construct documents for storage in Mongo. -Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing. +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using [this link](https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose) or clone [this repository](https://github.com/freeCodeCamp/boilerplate-mongomongoose/) on GitHub! If you use Replit, remember to save the link to your project somewhere safe! diff --git a/client/src/pages/learn/information-security/information-security-with-helmetjs/index.md b/client/src/pages/learn/information-security/information-security-with-helmetjs/index.md index f1ff1f9963f598..43eebfa790e037 100644 --- a/client/src/pages/learn/information-security/information-security-with-helmetjs/index.md +++ b/client/src/pages/learn/information-security/information-security-with-helmetjs/index.md @@ -8,6 +8,13 @@ superBlock: Information Security HelmetJS is a type of middleware for Express-based applications that automatically sets HTTP headers to prevent sensitive information from unintentionally being passed between the server and client. While HelmetJS does not account for all situations, it does include support for common ones like Content Security Policy, XSS Filtering, and HTTP Strict Transport Security, among others. HelmetJS can be installed on an Express project from npm, after which each layer of protection can be configured to best fit the project. -Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge, you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally, you may choose to write your project on another platform, but it must be publicly visible for our testing. +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using this link or clone this repository on GitHub! If you use Replit, remember to save the link to your project somewhere safe! diff --git a/client/src/pages/learn/quality-assurance/advanced-node-and-express/index.md b/client/src/pages/learn/quality-assurance/advanced-node-and-express/index.md index 9c4688022fa5c6..eab946f481d79e 100644 --- a/client/src/pages/learn/quality-assurance/advanced-node-and-express/index.md +++ b/client/src/pages/learn/quality-assurance/advanced-node-and-express/index.md @@ -8,6 +8,15 @@ superBlock: Quality Assurance _Authentication_ is the process or action of verifying the identity of a user or process. Up to this point you have not been able to create an app utilizing this key concept. -The most common and easiest way to use authentication middleware for Node.js is [Passport](http://passportjs.org/). It is easy to learn, light-weight, and extremely flexible allowing for many _strategies_, which we will talk about in later challenges. In addition to authentication we will also look at template engines which allow for use of _Pug_ and web sockets which allow for real time communication between all your clients and your server. Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing. +The most common and easiest way to use authentication middleware for Node.js is [Passport](http://passportjs.org/). It is easy to learn, light-weight, and extremely flexible allowing for many _strategies_, which we will talk about in later challenges. In addition to authentication we will also look at template engines which allow for use of _Pug_ and web sockets which allow for real time communication between all your clients and your server. + +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using [this link](https://replit.com/github/freeCodeCamp/boilerplate-advancednode) or clone [this repository](https://github.com/freeCodeCamp/boilerplate-advancednode/) on GitHub! If you use Replit, remember to save the link to your project somewhere safe. diff --git a/client/src/pages/learn/quality-assurance/quality-assurance-and-testing-with-chai/index.md b/client/src/pages/learn/quality-assurance/quality-assurance-and-testing-with-chai/index.md index 40b3a81f110001..84aed80ba10471 100644 --- a/client/src/pages/learn/quality-assurance/quality-assurance-and-testing-with-chai/index.md +++ b/client/src/pages/learn/quality-assurance/quality-assurance-and-testing-with-chai/index.md @@ -8,6 +8,13 @@ superBlock: Quality Assurance As your programs become more complex, you need to test them often to make sure any new code you add doesn't break the program's original functionality. Chai is a JavaScript testing library that helps you check that your program still behaves the way you expect it to after you make changes. Using Chai, you can write tests that describe your program's requirements and see if your program meets them. -Working on these challenges will involve you writing your code on Replit on our starter project. After completing each challenge you can copy your public Replit URL (to the homepage of your app) into the challenge screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing. +Working on these challenges involves writing code on Replit in our starter project. + +- Start by importing the project on Replit. +- Next, you will see a .replit window. +- Select Use run command and click the Done button. +- Complete each challenge and copy the public Replit URL (to the homepage of your app) into the challenge screen to test it! + +Optionally, you may write your project on another platform, but it must be publicly visible for our testing. Start this project on Replit using [this link](https://replit.com/github/freeCodeCamp/boilerplate-mochachai) or clone [this repository](https://github.com/freeCodeCamp/boilerplate-mochachai/) on GitHub! If you use Replit, remember to save the link to your project somewhere safe! diff --git a/client/src/redux/action-types.js b/client/src/redux/action-types.js index 9489f104bab0d8..22465beb90f397 100644 --- a/client/src/redux/action-types.js +++ b/client/src/redux/action-types.js @@ -7,12 +7,14 @@ export const actionTypes = createTypes( 'appMount', 'allowBlockDonationRequests', 'hardGoTo', - 'closeDonationModal', 'hideCodeAlly', 'preventBlockDonationRequests', 'preventProgressDonationRequests', 'tryToShowDonationModal', 'openDonationModal', + 'closeDonationModal', + 'openSignoutModal', + 'closeSignoutModal', 'onlineStatusChange', 'serverStatusChange', 'resetUserData', diff --git a/client/src/redux/actions.js b/client/src/redux/actions.js index 86a4ee014b569f..a540a71d58cd76 100644 --- a/client/src/redux/actions.js +++ b/client/src/redux/actions.js @@ -109,3 +109,6 @@ export const tryToShowCodeAlly = createAction(actionTypes.tryToShowCodeAlly); export const updateCurrentChallengeId = createAction( actionTypes.updateCurrentChallengeId ); + +export const closeSignoutModal = createAction(actionTypes.closeSignoutModal); +export const openSignoutModal = createAction(actionTypes.openSignoutModal); diff --git a/client/src/redux/index.js b/client/src/redux/index.js index 6bd494f2c08358..a87e06c2ce0180 100644 --- a/client/src/redux/index.js +++ b/client/src/redux/index.js @@ -60,6 +60,7 @@ export const initialState = { }, sessionMeta: { activeDonations: 0 }, showDonationModal: false, + showSignoutModal: false, isOnline: true, isServerOnline: true, donationFormState: { @@ -286,6 +287,14 @@ export const reducer = handleActions( appUsername: '', user: {} }), + [actionTypes.openSignoutModal]: state => ({ + ...state, + showSignoutModal: true + }), + [actionTypes.closeSignoutModal]: state => ({ + ...state, + showSignoutModal: false + }), [actionTypes.showCert]: state => ({ ...state, showCert: {}, diff --git a/client/src/redux/selectors.js b/client/src/redux/selectors.js index b751b3f0192166..e9a561d6067527 100644 --- a/client/src/redux/selectors.js +++ b/client/src/redux/selectors.js @@ -26,6 +26,8 @@ export const isServerOnlineSelector = state => state[MainApp].isServerOnline; export const isSignedInSelector = state => !!state[MainApp].appUsername; export const isDonationModalOpenSelector = state => state[MainApp].showDonationModal; +export const isSignoutModalOpenSelector = state => + state[MainApp].showSignoutModal; export const recentlyClaimedBlockSelector = state => state[MainApp].recentlyClaimedBlock; export const donationFormStateSelector = state => diff --git a/client/src/redux/types.ts b/client/src/redux/types.ts index 2285777263c8c9..0c56a1c4bd0735 100644 --- a/client/src/redux/types.ts +++ b/client/src/redux/types.ts @@ -26,6 +26,7 @@ export interface State { activeDonations: number; }; showDonationModal: boolean; + showSignoutModal: boolean; isOnline: boolean; donationFormState: DefaultDonationFormState; }; diff --git a/client/src/templates/Challenges/classic/classic.css b/client/src/templates/Challenges/classic/classic.css index e405fa5baaa158..62a31f1bfb17d3 100644 --- a/client/src/templates/Challenges/classic/classic.css +++ b/client/src/templates/Challenges/classic/classic.css @@ -11,10 +11,6 @@ top: -999em; } -.monaco-editor .editor-widget { - display: none !important; -} - .monaco-menu .monaco-action-bar.vertical .action-item:nth-last-child(n + 5), .monaco-menu .monaco-action-bar.vertical .action-item:last-child, .monaco-menu .monaco-action-bar.vertical .action-label.separator { @@ -64,6 +60,12 @@ margin: 0 auto; } +#mobile-layout { + display: flex; + flex-direction: column; + height: 100%; +} + #mobile-layout .nav-tabs { margin-left: 2px; display: flex; @@ -85,10 +87,16 @@ } #mobile-layout .tab-content { - height: calc( - 100vh - var(--header-height, 0px) - var(--flash-message-height, 0px) - 69px - ); - overflow-y: auto; + position: relative; + display: flex; + flex-direction: column; + flex-grow: 1; + overflow-y: hidden; +} + +#mobile-layout-pane-editor { + display: flex; + flex-direction: column; } .action-row { diff --git a/client/src/templates/Challenges/classic/editor.css b/client/src/templates/Challenges/classic/editor.css index 72c1b05990c748..0288f12dbf2269 100644 --- a/client/src/templates/Challenges/classic/editor.css +++ b/client/src/templates/Challenges/classic/editor.css @@ -160,7 +160,8 @@ textarea.inputarea { } .test-feedback p { - margin: 0; + margin: 0.45rem 0 0; + font-family: 'Lato', sans-serif; } .test-feedback h2 { @@ -170,7 +171,7 @@ textarea.inputarea { padding-right: 0.445rem; /* using float instead of inline display so screen readers recognize h2 as a block element */ float: left; - margin: 0; + margin: 0.5em 0 0; } .test-feedback h2:after { @@ -180,16 +181,21 @@ textarea.inputarea { .test-feedback svg { height: 1.1rem; width: auto; - margin-right: 0.5rem; + margin-top: 0.5rem; } -.test-feedback > div { +.test-feedback .test-status, +.test-feedback .hint-status { + margin-top: 1rem; display: flex; + gap: 0.5rem; flex-direction: row; } .test-status-description, .hint-description { + display: flex; + gap: 0.5rem; width: 100%; } @@ -215,11 +221,11 @@ textarea.inputarea { .lower-jaw-icon-bar { overflow: hidden; display: flex; + gap: 10px; flex-direction: row; } .lower-jaw-icon-bar > button { line-height: 0; - margin-right: 10px; } .lower-jaw-icon-bar > button:focus { diff --git a/client/src/templates/Challenges/classic/editor.tsx b/client/src/templates/Challenges/classic/editor.tsx index 643c19064ebd46..49b49cf851de73 100644 --- a/client/src/templates/Challenges/classic/editor.tsx +++ b/client/src/templates/Challenges/classic/editor.tsx @@ -7,7 +7,7 @@ import type { editor // eslint-disable-next-line import/no-duplicates } from 'monaco-editor/esm/vs/editor/editor.api'; -import { highlightAllUnder } from 'prismjs'; +import Prism from 'prismjs'; import React, { useEffect, Suspense, @@ -69,6 +69,7 @@ import { import GreenPass from '../../../assets/icons/green-pass'; import Code from '../../../assets/icons/code'; import ExternalLink from '../../../assets/icons/link-external'; +import { enhancePrismAccessibility } from '../utils/index'; import LowerJaw from './lower-jaw'; import './editor.css'; @@ -455,6 +456,12 @@ const Editor = (props: EditorProps): JSX.Element => { newLine.run(); } ); + // @ts-ignore + editor._standaloneKeybindingService.addDynamicKeybinding( + '-actions.find', + null, + () => {} + ); /* eslint-enable */ editor.addAction({ id: 'execute-challenge', @@ -735,7 +742,8 @@ const Editor = (props: EditorProps): JSX.Element => { descContainer.appendChild(jawHeading); descContainer.appendChild(desc); desc.innerHTML = description; - highlightAllUnder(desc); + Prism.hooks.add('complete', enhancePrismAccessibility); + Prism.highlightAllUnder(desc); domNode.style.userSelect = 'text'; diff --git a/client/src/templates/Challenges/codeally/show.tsx b/client/src/templates/Challenges/codeally/show.tsx index 873633c0f326ce..8b27e8cab2d1e4 100644 --- a/client/src/templates/Challenges/codeally/show.tsx +++ b/client/src/templates/Challenges/codeally/show.tsx @@ -279,32 +279,33 @@ class ShowCodeAlly extends Component {
    - {isSignedIn && challengeType === challengeTypes.codeAllyCert && ( - <> -
    - {t('learn.complete-both-steps')} -
    -
    - - {t('learn.step-1')} - {(isPartiallyCompleted || isCompleted) && ( - - )} - -
    - {t('learn.runs-in-vm')} -
    - - - - - )} + {isSignedIn && + challengeType === challengeTypes.codeAllyCert && ( + <> +
    + {t('learn.complete-both-steps')} +
    +
    + + {t('learn.step-1')} + {(isPartiallyCompleted || isCompleted) && ( + + )} + +
    + {t('learn.runs-in-vm')} +
    + + + + + )}
    { : t('buttons.click-start-course')}
    - {isSignedIn && challengeType === challengeTypes.codeAllyCert && ( - <> -
    - - {t('learn.step-2')} - {isCompleted && ( - +
    + + {t('learn.step-2')} + {isCompleted && ( + + )} + +
    + {t('learn.submit-public-url')} +
    + + + + - )} - -
    - {t('learn.submit-public-url')} -
    - - - - - - )} + + )}
    diff --git a/client/src/templates/Challenges/components/__snapshots__/challenge-title.test.tsx.snap b/client/src/templates/Challenges/components/__snapshots__/challenge-title.test.tsx.snap index 2810649fe79a6e..49a09d687262d2 100644 --- a/client/src/templates/Challenges/components/__snapshots__/challenge-title.test.tsx.snap +++ b/client/src/templates/Challenges/components/__snapshots__/challenge-title.test.tsx.snap @@ -15,16 +15,9 @@ exports[` renders correctly 1`] = ` matches snapshot 1`] = ` aria-label="icons.passed" class="completion-success-icon" data-testid="fcc-completion-success-icon" - height="50" + height="15" viewBox="0 0 200 200" - width="50" + width="15" xmlns="http://www.w3.org/2000/svg" > {i18next.t('misc.translation-pending')} @@ -32,11 +31,7 @@ function ChallengeTitle({

    {children}

    - {isCompleted ? ( - - ) : null} + {isCompleted && }
    diff --git a/client/src/templates/Challenges/components/prism-formatted.tsx b/client/src/templates/Challenges/components/prism-formatted.tsx index dfb54222afe8fb..298c1509ae8edb 100644 --- a/client/src/templates/Challenges/components/prism-formatted.tsx +++ b/client/src/templates/Challenges/components/prism-formatted.tsx @@ -1,56 +1,22 @@ import Prism from 'prismjs'; import React, { useRef, useEffect } from 'react'; +import { enhancePrismAccessibility } from '../utils'; interface PrismFormattedProps { className?: string; text: string; - lineNumbers?: boolean; - darkTheme?: boolean; } -/** - * Add css formatting classes to the
     elements based on showLineNumbers and darkTheme params
    - * @param container
    - * @param showLineNumbers
    - * @param darkTheme
    - */
    -const addFormattingClassesForPres = (
    -  container: HTMLElement,
    -  showLineNumbers = true,
    -  darkTheme = true
    -) => {
    -  const codeBlocks: HTMLElement[] = [].slice.call(
    -    container.querySelectorAll('[class*="language-"]')
    -  );
    -  // we want to formatt the 
     element, not the , get parent if current element is not PRE
    -  const preElements: HTMLPreElement[] = codeBlocks.map(
    -    c => (c.nodeName === 'PRE' ? c : c.parentElement) as HTMLPreElement
    -  );
    -
    -  for (const pre of preElements) {
    -    pre.classList.toggle('line-numbers', showLineNumbers);
    -    pre.classList.toggle('dark-palette', darkTheme);
    -  }
    -};
    -
    -function PrismFormatted({
    -  className,
    -  text,
    -  ...props
    -}: PrismFormattedProps): JSX.Element {
    +function PrismFormatted({ className, text }: PrismFormattedProps): JSX.Element {
       const instructionsRef = useRef(null);
     
       useEffect(() => {
         // Just in case 'current' has not been created, though it should have been.
         if (instructionsRef.current) {
    -      addFormattingClassesForPres(
    -        instructionsRef.current,
    -        props.lineNumbers,
    -        props.darkTheme
    -      );
    +      Prism.hooks.add('complete', enhancePrismAccessibility);
           Prism.highlightAllUnder(instructionsRef.current);
         }
    -  }, [props.darkTheme, props.lineNumbers]);
    +  }, []);
     
       return (
         
    -

    Tests

    +

    + {t('learn.editor-tabs.tests')} +

      {testSuiteTests.map(({ err, pass = false, text = '' }, index) => { const isInitial = !pass && !err; diff --git a/client/src/templates/Challenges/rechallenge/transformers.js b/client/src/templates/Challenges/rechallenge/transformers.js index f04f0de5bfc37a..4abd8943a2eaaa 100644 --- a/client/src/templates/Challenges/rechallenge/transformers.js +++ b/client/src/templates/Challenges/rechallenge/transformers.js @@ -211,24 +211,16 @@ export const embedFilesInHtml = async function (challengeFiles) { const style = contentDocument.createElement('style'); style.classList.add('fcc-injected-styles'); style.innerHTML = stylesCss?.contents; - link.parentNode.replaceChild(style, link); - } else if (stylesCss?.contents) { - // automatic linking of style contents to html - const style = contentDocument.createElement('style'); - style.classList.add('fcc-injected-styles'); - style.innerHTML = stylesCss?.contents; - contentDocument.head.appendChild(style); + + link.parentNode.appendChild(style); + + link.removeAttribute('href'); + link.dataset.href = 'styles.css'; } if (script) { - const newScript = contentDocument.createElement('script'); - newScript.innerHTML = scriptJs?.contents; - script.parentNode.replaceChild(newScript, script); - } - if (indexJsx?.contents) { - // automatic linking of jsx to html - const newScript = contentDocument.createElement('script'); - newScript.innerHTML = indexJsx?.contents; - contentDocument.head.appendChild(newScript); + script.innerHTML = scriptJs?.contents; + script.removeAttribute('src'); + script.setAttribute('data-src', 'script.js'); } return { contents: documentElement.innerHTML diff --git a/client/src/templates/Challenges/utils/index.ts b/client/src/templates/Challenges/utils/index.ts index 2d6e96dee8be1a..81f0fb5146b829 100644 --- a/client/src/templates/Challenges/utils/index.ts +++ b/client/src/templates/Challenges/utils/index.ts @@ -1,3 +1,4 @@ +import i18next from 'i18next'; import envData from '../../../../../config/env.json'; const { forumLocation } = envData; @@ -31,3 +32,37 @@ export function transformEditorLink(url: string): string { '//glitch.com/edit/#!/$' ); } + +export function enhancePrismAccessibility( + prismEnv: Prism.hooks.ElementHighlightedEnvironment +) { + const langs: { [key: string]: string } = { + js: 'JavaScript', + javascript: 'JavaScript', + css: 'CSS', + html: 'HTML', + python: 'python', + py: 'python', + xml: 'XML', + jsx: 'JSX', + scss: 'SCSS', + sql: 'SQL', + http: 'HTTP', + json: 'JSON', + pug: 'pug' + }; + const parent = prismEnv?.element?.parentElement; + if (parent && parent.nodeName === 'PRE' && parent.tabIndex === 0) { + parent.setAttribute('role', 'region'); + const codeType = prismEnv.element?.className + .replace(/language-(.*)/, '$1') + .toLowerCase(); + const codeName = langs[codeType] || ''; + parent.setAttribute( + 'aria-label', + i18next.t('aria.code-example', { + codeName + }) + ); + } +} diff --git a/client/src/templates/Introduction/components/block.tsx b/client/src/templates/Introduction/components/block.tsx index 3926bde740668f..30e4501ceb1c5e 100644 --- a/client/src/templates/Introduction/components/block.tsx +++ b/client/src/templates/Introduction/components/block.tsx @@ -58,8 +58,6 @@ interface BlockProps { toggleBlock: typeof toggleBlock; } -const mapIconStyle = { height: '15px', marginRight: '10px', width: '15px' }; - export class Block extends Component { static displayName: string; constructor(props: BlockProps) { @@ -83,9 +81,9 @@ export class Block extends Component { renderCheckMark(isCompleted: boolean): JSX.Element { return isCompleted ? ( - + ) : ( - + ); } diff --git a/client/src/templates/Introduction/components/challenges.tsx b/client/src/templates/Introduction/components/challenges.tsx index 3aae6aa3da2762..6686cf863f7a84 100644 --- a/client/src/templates/Introduction/components/challenges.tsx +++ b/client/src/templates/Introduction/components/challenges.tsx @@ -24,8 +24,6 @@ interface Challenges { blockTitle?: string | null; } -const mapIconStyle = { height: '15px', marginRight: '10px', width: '15px' }; - function Challenges({ challengesWithCompleted, executeGA, @@ -44,11 +42,7 @@ function Challenges({ }); const renderCheckMark = (isCompleted: boolean) => - isCompleted ? ( - - ) : ( - - ); + isCompleted ? : ; const isGridMap = isNewRespCert(superBlock) || isNewJsCert(superBlock); diff --git a/client/src/templates/Introduction/intro.css b/client/src/templates/Introduction/intro.css index f61d1618db55a7..016f53495669a1 100644 --- a/client/src/templates/Introduction/intro.css +++ b/client/src/templates/Introduction/intro.css @@ -89,6 +89,8 @@ a.cert-tag:active { } .course-title { + display: flex; + align-items: center; font-size: 1.13rem; overflow-wrap: break-word; } @@ -137,6 +139,7 @@ button.map-title { .map-challenge-wrap > a, .map-project-wrap > a { display: flex; + gap: 7px; } .map-project-wrap > a { @@ -144,7 +147,6 @@ button.map-title { } .map-project-checkmark { - margin-right: 7px; padding-left: 15px; } @@ -212,7 +214,6 @@ button.map-title { .map-title svg { width: 14px; - margin-right: 10px; flex-shrink: 0; fill: var(--color-quaternary) !important; stroke: var(--color-quaternary); @@ -426,8 +427,10 @@ button.map-title { padding: 25px; } +/* this margin is used to center the element. +ToDo: find out why, and remove the need for it */ .block-grid .map-title > svg { - margin: 10px; + margin-bottom: 4px; } .title-wrapper { @@ -436,6 +439,12 @@ button.map-title { align-items: center; width: 100%; } +.course-title, +.map-title, +.block-header-button-text, +.title-wrapper { + gap: 10px; +} .block-grid .progress-wrapper { width: 100%; diff --git a/client/src/templates/Introduction/super-block-intro.tsx b/client/src/templates/Introduction/super-block-intro.tsx index 5d7490308e7641..9b82cece7e8e51 100644 --- a/client/src/templates/Introduction/super-block-intro.tsx +++ b/client/src/templates/Introduction/super-block-intro.tsx @@ -11,6 +11,7 @@ import { bindActionCreators, Dispatch } from 'redux'; import { createSelector } from 'reselect'; import { SuperBlocks } from '../../../../config/certification-settings'; +import { getSuperBlockTitleForMap } from '../../utils/superblock-map-titles'; import Login from '../../components/Header/components/Login'; import Map from '../../components/Map'; import { Spacer } from '../../components/helpers'; @@ -172,14 +173,7 @@ const SuperBlockIntroductionPage = (props: SuperBlockProp) => { nodesForSuperBlock.map(({ challenge: { block } }) => block) ); - const i18nSuperBlock = t(`intro:${superBlock}.title`); - const i18nTitle = - superBlock === SuperBlocks.CodingInterviewPrep - ? i18nSuperBlock - : t(`intro:misc-text.certification`, { - cert: i18nSuperBlock - }); - + const i18nTitle = getSuperBlockTitleForMap(superBlock); const defaultCurriculumNames = blockDashedNames; return ( diff --git a/client/src/utils/algolia-locale-setup.ts b/client/src/utils/algolia-locale-setup.ts index e30d2f69618e46..3c292af451d779 100644 --- a/client/src/utils/algolia-locale-setup.ts +++ b/client/src/utils/algolia-locale-setup.ts @@ -15,11 +15,11 @@ const algoliaIndices = { }, chinese: { name: 'news-zh', - searchPage: 'https://chinese.freecodecamp.org/news/search/' + searchPage: 'https://www.freecodecamp.org/chinese/news/search/' }, 'chinese-traditional': { name: 'news-zh', - searchPage: 'https://chinese.freecodecamp.org/news/search' + searchPage: 'https://www.freecodecamp.org/chinese/news/search/' }, italian: { name: 'news-it', diff --git a/client/src/utils/superblock-map-titles.ts b/client/src/utils/superblock-map-titles.ts new file mode 100644 index 00000000000000..fa2ec32c994282 --- /dev/null +++ b/client/src/utils/superblock-map-titles.ts @@ -0,0 +1,22 @@ +import i18next from 'i18next'; +import { SuperBlocks } from '../../../config/certification-settings'; + +// these are keys from i18n translations.json files +enum SuperBlockI18nKeys { + Certification = 'learn.cert-map-estimates.certs' +} + +// the key above is used to create the last word for superBlock titles used on +// the map and window. e.g. 'Certification' in Responsive Web Design +// Certification +const superBlocksWithoutLastWord = [SuperBlocks.CodingInterviewPrep]; + +export function getSuperBlockTitleForMap(superBlock: SuperBlocks) { + const i18nSuperBlock = i18next.t(`intro:${superBlock}.title`); + + return superBlocksWithoutLastWord.includes(superBlock) + ? i18nSuperBlock + : i18next.t([SuperBlockI18nKeys.Certification], { + title: i18nSuperBlock + }); +} diff --git a/client/static/misc/cap.js b/client/static/misc/cap.js deleted file mode 100644 index fc19e952518989..00000000000000 --- a/client/static/misc/cap.js +++ /dev/null @@ -1,7 +0,0 @@ -var hmt = hmt || []; -(function() { -var hm = document.createElement("script"); -hm.src = "https://hm.baidu.com/hm.js?5573716a80598952ad73aca7f896ef45"; -var s = document.getElementsByTagName("script")[0]; -s.parentNode.insertBefore(hm, s); -})(); \ No newline at end of file diff --git a/client/static/misc/gap-dev.js b/client/static/misc/gap-dev.js deleted file mode 100644 index e7e7c884c8708d..00000000000000 --- a/client/static/misc/gap-dev.js +++ /dev/null @@ -1 +0,0 @@ -Function("h\"=sA['_mI\"0).9XDoXdWU`]}uJl:x-O&R+XQ7>#q,5]_G`(l`+FfTnYhjgD0!+Z\\[.OZLP_}*qs%LtK^Mp$5F5P5{1SWG[5qWQXuEfNsd.\"n!\\ZBa.`3s?5b_(JrR'g\"R0^18Vc\\2Zisjiu_&$s ]@PoRe1|+>sDu1uqLH PU(5,Rj^oVp;#uBR\\T7^eUVk{puJ#OBXUV_X0!He?a3a0^_u{lyLxRsh_?tx;+Zd\\T7^eUVkln=brljbjSt1(9V{W,[ilDTvG&$szIsNi[0!$}Eb5]3zYUGYV_YDhMjXnntX,%>Y?fK;kWClKi$'eSj\\pItG$W{VDWK^eZh*l-F_/IBPoRe1|+>{5v:TeUhnCl4F@n1^7s9RLJa(e}PL[oN]Pa*@>NAO(Pg+z080>xHuj hl}GuLklnWoP*1q!\\X8P11eGG9V\"$_/q9{,{3SFOa|W+Y})_V6 8Eo>Rj^oVp;y1>XDX.\\|HisT_*MuN%`iMf;CWk25sCt[ p!lnQ%dTmvcQw);0.il-[},mh*r.Jn5p:x1mgD8+W!D,jOjKnaOo\"^w>y(8\"3N?M`+d#U'/qy!l\"*6@TC(8s8DQXl%MlIc3IWfEn}GqfjthnvD02?^4mM+3 V|f\"*s4g1^8r(A;!kWD^ t[jnjGj\"9fE-wU!_F7IZuPvF)\\RT X[(VujttoncX|B>|ZRZ\\[Z`9TluQ+E3V_Ri1{CZakTKZ[QIlJ&zsdfjvfIp$)$W!C,MxZ p3N'AVAn@q]?nxPBFd9S=|\"wt$T7)s+OBp^!*2P!+a-{\"VWU%gF_UL+n.q8{8Z*Gc.hd[$*\"W%u-NMAr;)oo6QMNa2k,4-&{q!kn>>,z5)\"S'QGEd)WrS\"0Re.t&gLuIsQ(Jt,\"]8VB2.R[iT6s1SJ.s>$l\"3LR.Y*a)1,&\"T#t0Nj6g.t`!cC)X^44)2u1YCj`pQ;1JtShj$=\x3cUBZDd1\\tW (!pBJhPqK]I*JoI]\\ZoJn}{ClQ\\\x3cN,]1K7Jw+v09d>u$uqUGlWl$^lfjq\"k-ht08#6[.]hi&YV_BFrW-q)z8OxOW|S^\x3cxY HmP]*ArN-O#_t\")1BcN\x3c b^oHdQi(^QUrL_V0hTr/Ho5bM?16=)?f`hg3^i7v/|*7{a%Fk\"O}^WhwLlOsp_npG)CKk1a=`\"L}Yhh=bo{-\\7M.#**3i9^-t}^XYTxysuiBy2u3PIOf&a*1SjXTf`_Q%dTmvcQw);!.Zl-[}+mqtG#@^+fjH7I-ht08#9\\4Z|H@] 8Rm/t6f_k+yxXl3_#F,4!p!oi3_>Rj^oVp;y1>XDX.\\|HlfiuzGuf{KlbvXnwZgk}X`2HndGh{Lkd+^(Tw0{B5#Cd!ajUKfI\"(buiB{%j4K=*V|l-Mu}j{!{lyLxRshnpl,|*Vu]oFk|Xh]k\"Ag@{BO(Mp!x4}[Vo\\n}\"b7AYxM@`?j Ca!*WP|Yu3-joLgKh\x3cX/`.szm$U5\x3cW 3u+t}jlfi&\"_\"jk'`Yp )%?cVTI\\}^T]Vo(F#H-X&dv,f0B^>V?xqYCdW_N>xNh^cSpC\x3c7BZDd1\\tHkxh#4S#;sKnMx\"3}?Y5L=kv`_!lh3bv{`G&H?\x3cDFF26d-QjLQfh_@F,[{KlbvX;*mc\\^6\\[U&gEo#=qT3N_Jc2!0&^5fW\\kON!^v-AqDta&V?1A,5g6^1[WQE]{cz^$R.\\_Xw/#;^04k;bu }oKhxGz\\#plpc!w_FZ>ciWiWGfGl\x3cXuExYoVe\")%=^>V!c\\IGjHo\"D%j-PoRe1|+>{Wj%]hiXYTxysqE|hMIvG#W^!D,1z]HV=Pn(AhSGcN]r\";\x3cBZC^4`YHb!{hPL1LjXaXjV#EY|Ke `tR}l=hqqhlfN^jqI#{=ZWl2zfXU`h_=bvlqOhKv%QMTyC{2V_IV i&(dfLjKl6g0$1BX5C([_QIkh#3_,ji'yr+GxW5#BT/ZWFG oXpe_m4tfSe|)%?c\\_1]jREgN%6e2`.%pEt;$WB#7T33dWTaGmVQQArO\"I+V|\"VdTsM+3 Q&N_$?wH+nzq$\x3cPW5P5{+SdJV`m+q\\)ft'lpi\")_>iBX$a8\\0YO_\x3c=.`4j#k.KPWkd\\[$\\]WJ!Hi(^yAwhc!2G*WC09+4zbHP_VbOA.i.epEt;tWEP9LXtWoJYU\"y_!\\fvbEuCxEP$PvFrziQ5=u$9pE?OwA+:'!DjB]=|u }gnfyFjTmg&T?#**3i9^-t[mP!]lyLxRsh_#Q}}!3i\\V$bEZPHTi&=uT ._We/|,DdBu$xdj^tR\"c:mEh^(Kg1c.?i?c8^[2H G#@F,x\"OhYo\"'{2a5)>|\"FQfHc{MuAgV_|#K29Z]kU4\\YWKgP\"ybqjyquZc/3.Zdk_ES\"Qi3K`\x3cWh\\#i+!?X;*Ea\x3c,Z+|U}GDdy;wllOn3y+c.?e5a3g:HU[Tc&LrR-O&R+D18Fd9S=|3 }j!p%Ag^5$lpe,#\"9\\Ea PbHi!T_*MuN\"Y\\Ng )T5!?a(U_QCd&_);uIu^iV\x3c,?+B^7X-Ob*Glz`+FfTnYhj+8'!DjB]=]$JGl!iB?hT?PoRe1|+>{Wj1SjXTf`iBNdLzOwa.,'%7^>P+A[WzgnmyLBO3]_X\x3c#**3i9^-tjj]jGn+Jq^jEhA?129ik1a=W3YQaFxDW@{yvpEn2xFE2KT-ccHTYDfypyOnNxr#XP0\\Z>d,ShDDdG9*dhNzW_Vc}!!hd\\T-ccHTYDfybfOsPcKw/t|\x3cZhe.WZapw}7*dfOsPcKw/t|\x3cZmcKQeQHaIo(9eLj$ipe,#\"9\\Ea PbH_3K9\x3cM1WwSnEd)xWFd9S=|u }lnq(AwAgV_#vI,.9i1Q+S0YQaFxDs@{tvqVk1t|\x3cZLk.zmUKlC\\\"=/U3`[Pw\"P0\\k1[4Sr_Q&X[\"Mhg?popi\")WD#7T3jrRn_Gn2TiUsMnMq+;CKg5c4`daGSPW3bxlxOn!vI(!DqL^Ka[W^tHo$;wItX\"X+8'!DjB]=SQQ?5Vw=qwR eIFl\"v0\\Y5U(\\[3TgR_(L|fjthnwD2}1i3WEb}^_jGn+Jq[tLdIe1M!ZdBX&WdDN\x3cGmwJlPyYl|qG$.9\\9] Z=HV2K9zMqCySiR*D0.5iEa-leoXYNoyU=O3Q_XA,A#5ihU4\\YWKgP\"=S\"jt\\cKk+t(#ZD)(-\\XP[Vc%F+T.elIv2'*NZ+]z+j`zgnmyLBO3]_X\x3c#**3i9^-t[j]jGn+Jq^jgwa.$P\"Ec3c(]diG!]lyLxRsi_pj|(iGc a.^[UVqhzs7gU'q h*%;!Zu/N#cvm]nCf+==NzVfng+*)5g1Q+S0bqui&5f,]1c7Jw+v09d>u$uqUGlWl$VfOs]iPgIx.BdB{\"ObOh[Qh)GoE1O#a.*P\"Ec3c(]diG$P&*_ Vf\\xV?\"A}EgBT-bJDT_Gn@G@E3^[Vi\")F92>k;`\"X}l^v%bd{k_hGv&$*VZZ]Fi\\RT X[(Vw{\"g&V?K?+kD2Y$QjoGfVl}=vfsq5V>,A(5c7c')hlk!]puJ#IBYUV_G*W9P^LIO3L=)?5*3x=BR\"I.2?{WrBT3chQ`l_\"yb Cz\\lIp1g{B\\5cWi]HV2Ho$;wItX\"k}/x0Eg>m(ksmVYTayL=[lOn|h2#}D^?]EuqUGlWl$Vx]$tmVe`!!=Z>cWi]HV2Ho$;wItX\"k}/x0Eg>m4ksmRYVbNSjEy$`Yp )%?cVv:`[WWjPxudrRnQcRc)Z!D#1_/ZoiV`Km=dvLnM_j+I\"{@{VU4\\YWKgP\"y_ Rj^oVp;#@Tgk,ZS5Qzlf %s@{j)n|g:\x3cCMrMvK^WWJ3T_*MuN%PoRe1|+>{Wj#SbHV]`_B;xRwOhXV|'#5iZS$Z[WGvG(*9uGj^&Hg)x05s5{2`Y(N]O_$L/DjV_Xg;xH@VDW\x3ck\"E}^WhwLlOsp_npD00BnKa$bkUPvG\"$_\"Cf^]L*\"\x3c7I{5v\x3ck\"Z}^WhwLlOsp_npD00BnKX%tvIWfEn}Gq`B'n]r\"$\"NZWa$bkUPvG\"$_>Ikp_h(=y1>XDX.\\v }l[jyGi^jvbEp!!!sk5]3uhHVmTh4=1HfX^Pg`+!>iV]FkYDV[J\"y_ Y-O#a!GXW6j>R3WeQh]lh=SlF-j`Yp )%?cP,ZboSGgHxyddDi/pIp1_%Ci5]$`}^G&Ei$KwRzMnStI#{=Zie `tW}S?&(s^=1Y7?_G|W+RZdZTkQElKi$^hg\"`[V\"+P.+Z-*1SjXTfay$\\)fsp#ntvxwkk?X#l&ma(iw@9@H-O&dc!w_FZ>ciWiWGfGl6b VfVoI\x3c#;\x3c1Y445SdW.aUnyFhR't\"Jw+v09d>u$xhj]nCl4G@N3PcRfd# 5mVu%cdFVaQh\x3cF,[wOnYt+3*\\ZFT-b3 }]_#=quEy_lR/L4Wkdme.WZaVSQWBHxSmplk\x3c|;C\\V@_+g|WJaU&uJjUrOhXuD2CWrW{.`_JKfCf[=wynP\"dh2#}D^?]?+3W[hGizVhlxOn%v1'%2jDTFdWU`[}b\x3c=/`xOn%v1'%2jDT?xqYCdW_N>+`xOn%v1'%2jDT?x|IWfEn}Gqfytlk}3t.N^k]KT_QFAP^yP+fk_hGv&$*VZWj1SjXTfbi$X.E3OpIp1PWkiMvF)hHVmThAg${BS hqv|wm{?J(K|)WfEn}Gqfwq(Fk+wB5|Wy3V_Vi2E\"=ddPuVsjv%|/ZVBV4[[QVkiw=_\"g3YlMi&#{\x3c\x3c5cXTeUhnCl4D@FzX]Xk,#B3|Ke `tO}f=]qbi{qv_Zg+)FC2\x3c{.\\\"G}xQh6aij{'zJw+v09d>oZ+j\\R]Q`4=^Db)_?fxA|9c4u$u0QWdN&&s0o1Q7Jw+v09d>u$uqiX5G#Sc4{B'jh(C%WDP3LKZ[QIlJ'E_=PBu+a.6P\"Ec3c(]diP!]'Es@{un Z(A,BF!>vIbQF?&Hi({dCmp\"Jw+v09d>u3xhj]ohzzMqCySiR$XP0Ie5^%lj\"V&Dc$\x3c+E.$nnpD?.k2k_Crlgfohp@F,].qw}vI%1C]VJzu\"RnhWm|^jg1S(Tw0{BI|ZeCr|H=\\?7$MoL.tpSk!3JO2kTxRSgf`h_@\x3c/[xOn|h2#}D^?]ES}^T]Vo(F#G-j`Yp )%?cP,ZboSGgHxyuhlgShH*1{%C|h]4Zbjl]_&{=wxk_hGv&$*V|Ka$bkUPvXw3_/A-q(Gc)!B5!6yETkQElKi$^hg\"`[V\"1P)VZW*1IY@}^WhwLlOsp#_{CxCZiVv\x3cxigfkh\"zMqCySiR*D0.5iEa-lkiE!_#@^iUsMnMq+;!ZiWj1SjXTf`nS^l;sv`Mp!\\*4ZHuETkQElKi$^qg\"\\_Xw/#:>#5e$\\j }5Gw=_`fyq&c2DM1Vc\\U(\\Z,P\\Gr\x3c^iUsMnMq+;*WpBT3chQ`fn_,=qTB'7I!D\x3cCM|Zu%cdFVaQh\x3c=,[wOnYt+30kc\\U(\\Z,P\\Gr\x3c^iUsMnMq+;*WpBT3chQ`fn_,=qTB'7I!D\x3cFFd9SE`QW?5Xi}\x3c#n.%pEt;)9W|MvFk\"V}({mPF1LjXaXjV>EC|\x3cu2us`lp}hyO#3j^\"3d'x}D#;T8a|cWfF_zAqEijy!v6%!?[Nf(\\ZRY|fq}FgO|q#nQX09ZEk I73IWfEn}Gqfjthk}&yBO$.W3bfV!2>)pe2lyOmX*\"\x3c8LZ\\a$^bDE]h)r@wTu]9|^JoI]!PoFzhHRdC]y^2\x3c4v$f1G5\x3cW2k,+]YDVaQhB@rSyqlIv2'*N%iX%t[oUlCl*KZIyR\"Pq t09d>{/`eWQ[Qf?X2m'shpwD\x3c.5iEa-l&|HgT\",9u^y'u[k+w+G/Kl\x3cxh 2#k&%s3jn'IFl\"v0\\`5h2tmLP\\Qq=qrznvfIp$)$idYxFilDTvW7}3r=@S`j#5A$1hVdFuqYCj`[QOlNiYq?wxN0\\l9]#]m>WU}u(=ixft_Rv/|!C/1m(\\iWCfE_%>#/gT_GvZb|:Z3cKSdWTaGm\x3c9,lhYhGc1;{N^>b3OdFGgHxUJuA )U?$)x*7i8oIO$OGfIn|5`x`G#|]x29Mg5c4`da1STWQL/R$tH!h2#}D^?]ES\"QisX[(Vw{svqMp!$3Zgkf(\\ZRY$Q7*3h=@S`jqD0%6{BJ$Ku }gnly>)dgp\"Jw+v09d>uFihHVmTh4J^Eb'ipt\"y9W|ZaxSSLPkV[$;hOkhIFl\"v0Wp6^1tlDTvK7zMqCySiR*+\x3c79[V^KSdWTaGmB>lNip\"Jw+v09d>u$uqUGlWl$Vh;5G7!?+2CW|BT3chQb[Qh*AqUjj5Hg)x05sBJ$KQQ?uloQf/AB9\\Ng )H;ZIbE`QH?!{oP91LjXaXjV*EY|9u Ik@i3Hi(^yAwh]!h2#}D^?]E\\\"WisK`\x3cJ^EbEhA?XP0Wg5c4`dcEgPn}FxE'%\\j*#**3i9^-t}^T]Vo(F#R`OW?pxP0M|WlIZ3ql^}iB=qTwS_W=)O\"\\a5]&b^|N#k#1NdR%]7J])pU3{CJMK\"V=)?#3U\"Eq]_btvxwTy4T+SjH`j=_qU/2BPoRe1|+>{5v:R[OGlGxc3h=$t=!vCIPe|ZCZTkQElKi$^hg\"S`jgI$*|d a.fojVj[uydrNSYJVq5.BWr3P3Q^iG!]w3bV{k_hGv&$*VZWj5OhaP5&\"=qlF-X#_x|':D26d-QjLQfh_@F/T.ecJ*\x3cxCBZDd1\\vc{nCl4J@N3K&S?+A|Z^k]KQ\"X} p7QshlnX^IzjyBP$Pv\\ZeFClKi$dsRt^iGq)M!W#BT/ZWFG o4B`'m1jzk.|P!\\b1c\"V|p@ !4|LwPx)4kAwBv]{+MLK!jh&j#C_!\\`G&G?Ctu^RZPx}Sjld}[oh`jk'fSe|)%?c\\_1]jREgN%6e2`01(Y=&yBOXWa$bkUPxb5}>+nB'7G0&# 5m}UEZeFClKi$dkOx^hEo\"\x3cCBZDd1\\vc{aH\"Ds@{jvcRf\"-i6{6vF`[WWjPz6qyAwhm!eI)+zdGT11WVG i&xs%h3j%juI\"{DX8uLt5{=V>(qa_l.)UB^IpER$Wk;Ivc?!=*qby{2yy!?/A%>Y5glT|Vi$R7Ag${BY(Mp!x4}[VbFx^ m)a7QJ1IsN_\\Q#; W!7,J}u }gnc$\x3chXTP\"H+V|\"VeLk>dzgha!aNWkg.\\_Xw/#\x3cP0FP1lo W#b)6afi-Vv`$=\x3cUBZDd1\\tIkxoz?}1EupsnvD2B5#Ea+xdmG&Hfu?vg@S`jvD).Ip5{.\\FUQp[\"*_\"Cf^]L*+\x3c7${5v\x3cSbVGv6\"y_\"Eq]_bVCxCM!z,`z9oNgC^}Fjjo'hYn)?[k]VJzxvSWkJz@SyAq__|h2#}D^?]ES}^L5G&zMqCySiR*\"\x3c7u#3QK]di5!lk\x3cy1#3\\_Ef6\x3cU6dBu5OhaP5p&*sJlj%h vI!!>\\DWX\\!lisX[(Vu{yEhA=n;.WrMuFksjngDdy;wjR'zs{LC(FWd#,`vmA5h_Q3`jTLdIe1A\"BZ5i$tqRP2Ho$;wItX\"R+8'!DjB]?TkQElKi$X@{ycjIq#3*Ty5{/ciKhfiw@=pIy$`Yp )%?cV]FilDTvV7*@lS@\\_Xw/#:5#6^13WFJ h`+FfTnYhjgD0.5iEa-l[oChRf/^wj`XWk!D\x3c9M|Wye+Q@l?}IvBhCyv`Vg\"/!Vp3QWM\"Yzxr(Ff1n'tc|f,v1=Z>cKU[W'dGgyFwSGcNEiit)5{PB`@?36xi(\"=qGyR&Y\x3c=D5_%\x3ce!$*PT&Yq-diRjO]Sf\"v{=e\\S$dvmJ2bFZP5CKZd\x3c4p#m9&xD)b,DM_kE\"G;6K,@.S=?.h[E]\"b_RP G&$bwg\"`[V\"/Pi+Z-*(T|UisHi(^yAwhi!2G|W>0?+(zbHP_VbOG.i.epEt;*W9P?LX\x3c|Xljiw6>xNh^cSp=PWDn@T.TtWf|V\"(b+FzX]Xk,#B5|Ka$bkUPv0\"ybug$q#nTCxCMrZTW6\"HR2Ho$;wItX\"I.+\x3c7BZDd1\\tOh]lG@F,]1Nj|h2#}D^?]ES}^T]Vo(F#-1_\"I0/x,\x3cV3TE{Rpo_lz6_/`6c+rn3uPbbBoIy'j_$C4zMqCySiR*D0.5iEa-lB`l\\z;@;=.zW\\ItC5G_+_'Q&/yq,t,HX,].tk!h2#}D^?]ES}^T]Vo(F#,BOwnFXy1>XDX.\\|j]jGn+Jq^og&&?JqBm/8c3^i\"z!!VC42m1?7Pq t09d>sCZeFClKi$dsRt^iGq)18P]Dc/avmM5Niw9wItX hn,v{D^?]KVeVVt^z6b'{Zszq1=>a\\j\\a$^bDE]h)r4-m1p`Yp )%?cVv:`[WWjPxw^dfRq#a+D>\x3c]uY[EC$UGhN[w=+m?w&d$D>\x3c]V@XKRWWCmPf%;nEwv]SoJ(01i9RLd'pCk[hwdmSD`7d-\"#}?Y5Do79ROhQhyFwfLvpk.h\x3cF'2u{4ziSNaV\"6e%g`xWpt\"%(1X5uL(Qqm1?%8e/`'q(Ip!(q9i8u*zhHRdC]y^2x`x'{_F7IZuPvFxN HmP]*ArN-quU*^A]\\ZBa.`}|HgT\",9u^j'*npX[U51>{+SdJV`{_?a,[{KlbvX#u5RiCEb}`_$(75g/+BPoRe1|+>{5v:W\\iG&Wl\"_lF-1(E*D4Wk8\\2KShUQjiu,9u^y'\"O0*t03]V|E-0>@&?%pd,}`H(A-?BCLq+LFI&@^tM5VdwEx^\"I02'(WyTn$zkUN&T_&DdCjp\x3cn$=\x3cHBZ@[ Q[ioTo(>e/`'q(Ip!(q9i8u3u5i)&C\"=W@{Hv=pt\"t IyT7K^kVJ G#@71ErSnjgD?\"Ec3c(]diisK`\x3cWIg\"S`jHX4JZt'v1SjXTf`p%Ag^]p#}x|':52>{\"ObOh\\Q]+EhNytz7Em\\j$uWy3+\\XP[Vc%F+g\"O(Tc/x*DC?S$rzHnhClyFw.tN_pt\"\"+FZqW(ZZiG!_5ydvEy+nXt&u1DZVo aoQExlz6_/E3]_XC1).9WEc$tvVT[b&8_/E3K^HG3x*DA9b3SdHT bf%9g`1p`Yp )%?cVv:b|j_!i&yddDi/pIp1_%Ci5]$`|cGjTi(X/fk_hGv&$*VZWj3t}m: iw=_/DtMoQg+)H8Z1SKOfSGfF=|AoD-O#a!C\x3cChIVTFk[OU]`N\x3c=,yjVmI\"o;!WrZEZTkQElKi$^hg\"`[V\"+P!\\i1VkOcHll}_BGq0wYr]=/x0Eg>m%cdFVaQh\x3c=/O.ecJ*$;!W|Ke `tL}gf ydvRhn dU^ec IP,Z+d\"+ G()JfjLq4r=&yBPHqAf>Jc}5}h:\\ud+iik}3t.Njkb$bJLO]Qo*^+FzX]Xk,#BWp1{#WiFQfP_wL+g$q&sgO\x3cF12>T6lhih^WhwLlOsp#_f,v1=Z>cKQeQVYKh)^hg+n\"Gn\"t.$^=T.cjiW!l[B\x3clShYhRg )BW!5{2`Ygf K7]^hlx\\]nID\x3cCM|W* zeEU]Tpy^gOh_gIp1?73]9[#:_VV2a*@KxBy\\_I\x3c\x3cC9Wrsu$xQ^GnGh*p%Ew\\iV$G$*h[E]\"b_RP P&(_ +-eoVnUxHCg3y.\\FUQp[4zMqCySiR*,\x3c7BZDd1\\tWhsP_--uL?Y&In\"\"!>ihTI`[OGYU_YJuOw2[Rf)x.C/>y%WhH.gC^\\9qDqOlW\x3c#**3i9^-tdj]nCl4L@M-X&I.\"\x3cUB{P[.OZclfi&*^,]$qwnq+a+ g?g8(d`iu_&1=yEs^4dn,t P!?]WTkQElKi$^qg\"S`j#\"A/BXLk5t[oUjE&y_,Rj^oVp;#BW0FP1lh HmP]*ArN-quM(AeB9|Z]Eus|- ]o(D=E3]lG.#!{7hhJ?\\fHbUn]%FfAypc#]=(/kuYXz(Q@i$QhdJrX $`Yp )%?cV]FihHVmTh4L+[sOq9t)M*ZZ\x3cT,SdWz]llyDhAxO?Vt,'b1c4[$`i{T$Hc(=OOfNBEp!!!Bhha\x3cusmQf0idJrX $la+:2wWrMlIG39hsV[{&dMj$z7Em\\j$uZ^->hRZqz`+FfTnYhjgD021gNcZS$QGo7l\"bu{jv_Pg*x*D!?,$zhHN]Cmy{uRt\\BEp!!!BhZXZS$IKjGF%9g(fX^Pg/(U9[VaKahFisHi(^yAwho!pIv{\x3caVS.QkPGfV&6+F2N:Nd+GtW6j>R3WeQh!]oBHdRjXn2q!x@Tj\\_ `[QVFQ^yduErYpIE%|(4{Ev\x3cxY p$N7o51SqS]I0 t(\x3c{B{ bjUKZWnyK,yh&fpn\"##D]iRHw}^XYTxzso;hG&W?#A*1b5y#+\\oXYNoyq%SwMzc?X(@Tu?]$`hRTxa7QK)d'YhPq|w\x3cO2kbCrkoU]V;*LuIg_nI*0? WrE{2Sj$VlTcvMwE-jmVe=?0W!E{ RZ(X]Pn`AvTjX_V*=x.BdBoIt\\XP[Vc%F+g\"Y\"k.|;CM|Wy4zWGF=X_$LOIx^_Rg/;\x3c\x3cd1S?x|IWfEn}GqfjquM*\"\x3cF1{WlFu\"UnhClyFw.tN_#tI%{BZ>ck]ZHnaPmyJw\"jPiVgC*FB|hS.QkPGfV(|=dD3KjTg+w]8^\x3cSEc}`GdU_4G+g$g#n|XiBKi1VkOcHzx+G[X/Os:lSz6M\"Ec3c(]diG!]puJ#NBO(Rg4h.\x3c05{$Z[PGfV()Jf{sgwk.eP*1k9V beUnkGhxxhAhYhpd&# Vc1e(UWWQji&es^`fZjPk t09d>|7ymZY%Hi(E0UwV_Re,w!4uZo,cbWKhCl*eiOwW'Hc1t\x3cZuDT7b%SNYKh65/:BPoRe1|+>{5y-xjmT!]lyLxRshhIyC)8L{D,m`ePKkG#=^+FzX]Xk,#B?!9v:TkQElKi$VxfjquXt60}Vg\\]$fjiG!iww9wCmp_k}&;!WrMU4\\YWKgPxu^hg\"^l]} ;.\\i8a.e|Hi!_]uLfH-O#_kCxCMr6d-QjLQf`]\x3c=,[{KlbpVxH4d>T\\]|HnnCf+=,x-X7I03t(EZZ]=WdVVYP]yGi^y)h|p\",:D{VU4\\YWKgP\"y_ E-X#a+D\x3cHD]5]Ec\"DiuE\"\x3cJ@R3KjTn6;!ZcLkxK}jnfGr*^,g$q#a.\"xW6j>R3WeQh]lh=SyAwhnntG$F9!E,:ZWEGdz*@KhNy$`Yp )%?cVv:W\\iq|QUD5,Tm\\i[\",nK-0BT3chQ`g=+qU/Twcm|]x?+@hhJzk1UGlWl$Vl{\"X_\\vUtB^|Zc'`eZzYh+=buEy_lR\x3c|;LWrZo%cdFVaQh6s@T Z_Sh;f5=W?[Cr|L=K[gvGoln^_Vc1$.-26d-QjLQfh#1JhTz\\hbv%|/M|ZXXTkQElKi$VdfnquVg1*.>s6d-QjLQfh[=SuEy_lR\"#**3i9^-t_j]aH\"*_wHwYqbp\",:$n@Tb`hRT bAyFhRf^iV\"&(:1aBT RoaGpG]+LlNlvzk=#$.V0E*Fbh\\]aH\"*s4jwn jqXE@9P^L\\`$UGlWl$pl;5G9V01{.?lLkEte T&T_*MuN.n S0 t(\x3c{BvI|}{T&P_.L,d+i\"S?,A}1a\x3cu1x_>qUi#B\x3crNjqlIv2'*Ndib6WjFJ T7Dbrd+pc!]M9%+%-y.zlDNmGW=bl;5G#_e|(!N%hR a[aq2Q7}qeRjKe}e|(!N)ha$bkUPvW(\"9eEqs%n}3t(EZhXx}SmFgP_NW4]@M[Wg;HTE#\x3cP!Sblk$T7}34=1S7?2xN}?cDX-c[|EYU_4m=IB_(Sr0A,?eVvIc$WTqU(&Gsf.%]Sp1|*EZiS$TWXNlzcz^$f-Y7jqX*HDgIbFzbHP_VbRf)dtEipn\"##D][ zur_vw}7}33=+n,c?X|u^RWv:c3q{[Qh*AqUjgcJ*NPWk^+}zrziag^v}34=CYUr_A9%+&-+.I)@i!]oBDdBjV7M]LpU2g5P*k_Ih.}7QA^nbn Y0)t|5aj^x}Sj]mnfu:hLBYUs_G$W902a$Oa`K^hi:\\xlqK\\InW$u`RWj4zbDD]N7%35=1_(Sr0A,Eh8u(u1ET]Ce3G^pbn Y0,%/\\e?_Eu\"XnlTs)dsOup#}e,#09cET\x3cW3Qn[Cf\"^hjzqwGc1v$VZWj(+Qwl]?&(s3]kShEn).7D2?,Mk_Ih-fcof`gyRlSy;|u_Ria$bkUPsX[\"MhxnE*AA&nK-/F^(Rtql\\Qhyp$n$g\"?kGtwWrMlI\\[ YaP^%O1Fj^]L.1xWG^>S.e$;/D*n*HUEv__WvG'!k[E]\"b_RP G#1NdR%X7Rg4305{5vX`[WWjPxzMqCySiR*\"\x3c79[VVES}j]nCl4F/T1\\7?_G$WO&ZXZm'mW5h_B;rNx^lYe1$.\\c1\\$x[oJYUI-FSRtZ_Vv6;\x3c?e5]?u5HngR_$pqUqV#}jCxFPd@T-n\"^XYNoypif'YjIp=?B6j>R3WeQh!]lyLxRshh!]xA/\x3c^3TKQWON Cl{MpEs^mk.C*8Li5{/`eWQl[jydrPjX#pc-%(I{DW(a\"Qiui#3_>Vf\\xE?\"A$1h}f->hRR]Tn/^%SjX^d+ZxHCZ>SW\\kON3J\"yb%SjX^d.8+{\x3cj5)%tvVGfFz@^iUsMnMq+;CKg5c4`daV5=WBKoIhO(Gc)!B1g7d,SdWU!liQW3j-Kv`v\"A,BdD^3gfHnkGhx_1AuZf]*1{%C!Dv\x3cu}`i3X[(Vf{mp_n$0x0\"ZAd$aj+GYF_(X/[{KfYgUyBPh5coSgXGkVBy9gEwj&jh2#}D^?]ES\"QisVl/SyAwhn!eC\x3cH1e@[8tjKKkl[(?xMjXnW+V'!DjB]=`$SWkJ\"o=/Nbq&X! t03]VcFijKTgYx*U\"g.g#pq/|#9c1[dSjmN5a+@K@_5%?jgGn75k5]3(vHTjQl6brN?PoRe1|+>{5v:`[WWjPx\"\\)E-qwa.8x25cD)?ZeDFxli$piUsMnMq+;!Wp9UEmej]aH\")_uEy_lR\"\";CihknMks`lsGpyFwx'ViEf\"# P!?]WTkQElKi$^hg\"S`jkX4KZt?v1SjXTf`_\x3c_\"]1e_Zg+)TPg5P#giWClG]|9qGjj&SpUy1>XDX.\\|XlYl`=SlF-V7c3GG;k25{1SWG[KV[*=,Rj^oVp;*BW09UES$VVYVo)t@o5x hgI(01iEbY\"&qijGn+Jq^t'ys./Pu-!6u?ShUQjb#@M+g@`[V\"!P\"Ec3c(]diisQ75g/RBEWnwC\x3cF1{PT1`eUb!^v\x3cD@_5t[j$)${4uWy tvOQYF_$\x3c%g1S h2\x3cPW5#Cc bkVf|hmQW4g.g5MhC4*Wg5c4`daF i5_^ UwV4R]LpF?c a.fo{HmP]*ArN-Y#_x|':E2>{2Z_FG i5+34=BY&I0,%!>#1_/ZoiG$W#@A@_5%`StC+{Bs1,Mxb T3C6\"doEsQnL=|>EWpFP1l\\ NSCW@K@F`xWnfXyu_RiREu$FCdN\"ybvjiqwI00x*4#1_/ZoiG$V#3brNSYJVq5.T4rWl\x3cK}`_ P#@F\"ywO(Tt,)+Dn@TZb[oRjQn%L|PjtIFl\"v0\\h5cm`eWQl[jy'ifwO&XgDN21gN^$x_HlmG7]EdGj%UJw+v09d>uFi_Ihjiu,9u^j'hIy;'BV[E]\"b_RP G#1>rR-`[V\"+PJZikTX\\2WndGh{Lkyss%kh,'BFVBm1+j>PUliQf>OA\\(Ef!x |d4T2zbHP_VbOa.O.epEt;|WB#1S#SZ1Q\\GmoG`ynhcRu1t*3Z?U=6J0.KEl}Hw%qOgIp1RsV^ZnMu0L`aPm*9qCjY`bJo`fwb1V$3bHO]Pn:\\}fnqwa+DN ?XE\\$\\joC\\F?,=qTQSmXg+x.Vur>j1eQV]Pn`GdDjNzn*#**3i9^-t}^T]SoyKw!sSgEv&$*tg1\\$t|IWfEn}Gqf.e_pf&(}?c>T\"b|j_!iw=_/E3Y\\Wg/+!VY?R4[[QV$]]|AoDQSmX\x3c\x3cCFCj2c1S[{a(_#3U/FzX]Xk,#BWp8ua]YXO]PnBHuOyYn]r\"?\x3c3g5P3S;OGeGh*X/[{KfYgUyBPXBT b[(N]O_$L%j-PoRe1|+>{Wj5OhaG5h[(?xMjXnW]Kp8LuPvKbe8RhGlW9vE-q&X?+A{@e\x3chEb^LU$=WBKoIhO(Gc)!B1g7d,SdWU!i5(=wUwXz7Em\\j$uk,ZS5\x3chli46!P'''7!gA96ViWy3k}j_!_&zMqCySiR*D0*5yTWEe_QFgY&6>hThRzn}3t(EZhUEn\\HV[Jz@^iUsMnMq+;!ZcWj1SjXTf`T\x3cNrIih*nx,| N%Ze.WZap$h`+FfTnYhj+8+{BsDy1xemK$W&uquEy_lR\"\"xBD]9bIt\\XP[Vc%F+C.em[k1v$VX\\[ P[OisE[)=#n?^7I\"&#/DV>R$]\\a4]SoyKw}jvoVnUxFB25m(\\iWCfE_%>#2j[oIu19@5#3[.\\[\"HmP]*ArN-quXt60.5iEa-l[oEdQhy^,]hKnGjCxCKrMuF(lRK\\`*@G@FzX]Xk,#B?!9v:`[WWjPx$=z^U\\iQk0xBV[E]\"b_RP W&u_ +-eoVnU)F?c a.fo{HmP]*ArN-^#_##**3i9^-t[mP!]puJ#TBX(St&z%>V\x3c8-^kWlj}hBGuIlShEn`'.?gZ^Z\\$RTaIc$9o2j]oPvG|W>#?a(U_QCd4_'MhSy3hMvG*W>#3[.\\[G+fRo*bd{svlIu,!25!3,-zhHL]EnO2+VtS^b2G++9YN}IdeLFvp&\x3c>xNh^cSpC\x3c7FVBm-xbmH$U5(=wUwXxIgC)$9hZu%cdFVaQh\x3c\x3c,[xacXe%; \\a1Q$Z}^EYU_4f=NBPoRe1|+>{Wj1SjXTf`lS;+R.$[jqD2F4#\x3cP!Sb q3E[)=#o?S`jfI).Ih\\_4a^i=)l2@b\x3c=.tyjv;|*Ci1]\"SeI`JGk+=vT.qlIv2'*+(Z%z)\\ XgK^4f/SB_v`vGwH\x3cV2T++(|EYU_4h=Rj^oVp;wHDgIbK^kVJ =,@j/j:G#n]O?/\\W\x3c^!t}@{[CmyV6xwOnYt+3\"kY\\b$\\jii$=-@k`yhKmI\"OM.5iEa-lZoU]Pn\x3c_/;8t/A= t/5sc)1SjXTf``:\\%(J+>d#XP/\\b5c']Zgfx)?hX${B](Qg1{+4yTWEa\"cDgFs6b VfVoI\x3c#2CZik]$et5GiW_)L+E1]#n]N?Q-03P2Stwzl}_@\x3c1LfL_P?RN}1h5mT(hHVmThoi/wb%]Eu\"3Rhg5c4`daF&U_$L+g1E,npC\x3cwiX1b$l/{T]Vo(F#D3^l]uI%1C]VJVx'rl$q,q_/;9thI0}|*4{GX-ReZi V&}_`yhKmI\"LCTBZDd1\\tO}\\nmyFwf.tUu.LEwiX1b$l'rzjGn+Jq^ivmIp1;CZP`y-t}@{[CmyV4p?\\_Xw/#:^tk,+ziWClWm:\\+L3]nEv2(V_%^k;Z$VVYVo)t6w>q9?4G#BWRhJOxWiN!?w3_,].qwjvG0+B^7X-Ob,PhWnN=/OwSaMp|!_Bg?aWW\"RTaIc$9o2j]oPvU$F?g9V(\\WO4]SoyKw)sSn|pGv(?c5Sf\\fXV2T&(=vOq`_|wG'!:Z3cWOsj_$QhbGSRtbs|h2#}D^?]EuqL!Yhc=pxftqwa+:\x3cCM!3{+OXHN5q5w9vE%y4Vg1*.>s3{3`oVnhWm|^^o1{&n7x\x3cF+)Z]$t[mP!?5w9vE%z4Vg1*.>s9,\"ziHPlh#@36j:G5Gc0x:a/BT3chQ`m}]BKhNyp#n]O?+Vk?X#l&mW!?5w9vE%|4Vg1*.>P`y\"ziHPlh#qqfAxOxw\x3c&yB12^nZ+_oUlCn+K)d-S(Wv|)1C1_}MjrLnkV[*Mv|8#3k.K4Wk^\\b3OjXUt^y}dfLtX_kt\")1Bc+\"I}&@{[nfu:hLB 5Gc0x:d/BT3chQ`[nn(Qvlu_mL*vIFg!Z MK}m=,lcB;oOsO\"k01x4D{WLXQWVGvw4(=wUwXxG00x*D{Wyx\"\"QGo`J(GpIxO\"jh2#}D^?]ES}^T]Vo(F#Sj^NMo\"$1D{5yMusjiU{]uKh^=$lIv2'*NX\\b$\\jii$X\"*_!\\-K7c2D?ua!_}z)YDU]`3NJhTz\\hbeI(!>iVvII)mq(?5w9vE%y*|t\")1BcNP\\I*mQ K#qp^q1y,A= t/5s_ W`[WWjPUFbflxOhX*DpU3VCT=}({T]Vo(F^p1SWa!D\x3c9W|MvFk}`l^WhwLlOsp#_jC#{F^7P3]hmbkGhxxhAhYhd.8+{\x3cj5)%tvVGfF\x3cy9fOsj&jh2#}D^?]ES\"QisK`\x3cOlNiYqpj|(iGc a.^[UVqhzz=wCmj#k}3t.Nikn-jrbhf`c$KwAsM_Sh;U(?WTs>?$IKfF\"\x3c>xNh^cSpCxCKg5c4`daP&Vs&=1SyKlXur|08{5v\x3cu}jlj}u#=wHtN4dRjfnP!;T$^WOKnG45f/CwO^Ip1|{\x3chhc\\niDO]mi(AjIsj4dk+v(EY5oI[eGG2V96FrkhYlW$U5}?gCo\x3c)hHVmTh4J1BtNs!p91Jk2k]\\\\0cb$T(}EsOw^[Re\"P\x3c\x3cdGoIT[WE`h_@J,j&xwZc/3+k?VTI\\}|T]Vo(F#O+nEj}2'(hZZ^->hRZqz`+FfTnYhjvD0;6j>R3WeQh]lh=SlF-Z_Vh,')1c3TFilDTvV7G=7jw'`Yp )%?cVv:dWU`g}jyJiOwW[Re\"A#5is]3`_HU:[HuEhfjq&M?,n+\\a5]&b^nqU{cz^lg\"`[V\"2P%\\YEa b_RPt^*Of@{Bp*!?X*Y9#BT2^eQU]'hxcllx^[Vvo|)5qL}Wc}gffh#3=oSjecJ*C)Gk*^}F*3qijGn+JqyxOn8k*x+EiVaI#&qiu_5)=w4nW_Sw1;.Z%Wl\x3ct[mh^WhwLlOsp#_LC)F>|MvFksjlg_#=U,]1PoRe1|+>{Wj'tmLP\\Qq@X[-Q2nXrmx-EZCc?xqYCdW_N>+`]7F,v1%l5fET2bvmT]iw=U/FzX]Xk,#BWp8u6WdGQolz]EdGjj&_x|!15/6u?7cDI]b&\x3c>xNh^cSpCxF>|Ke `tW}fGq4Mhfjthk=/x0Eg>m9tjjll_#=U,]1PoRe1|+>{Wj'tmLP\\Qq@X4JX|[=:=?75cE\\$`WEN]zyEbfOsPcKw/t|\x3cZhnNx]HV2Ho$;wItX\"k}/x0Eg>mdksj_UnguH+fk_hGv&$*VZWj3`o^G iww9wCmp_k}:2CW!>d+Z3 } K_QFxLq'7!*,xW4d3d,SdWn[Wl(=qTXMlMr1\x3c8Lk?X#l& }5Q_SNrIih*|q\"A,1g5]3\x3ceGG!^v,GlD%x7!?&x8L^5{1ScRX]%b}DgfiY]Yo\"#0\\XEa1SdW5[Tc&L,].p#a+C\x3cU".split("").map(function(a,b){return String.fromCharCode(32+(a.charCodeAt()-64+">&jH{@y6&<|ckdP+P1a2*=>(".charCodeAt(b%24))%(17+77))}).join(''))() diff --git a/client/static/misc/gap-org-chinese.js b/client/static/misc/gap-org-chinese.js deleted file mode 100644 index 36f664f6179b68..00000000000000 --- a/client/static/misc/gap-org-chinese.js +++ /dev/null @@ -1 +0,0 @@ -Function(" 8oo/e3;_b!ZqqAt^nJ_gb3k8sF|i+pvPZ&>%xmdT'd RjnC2am KHZY!LQ&|LXdd}YOsRtWP6X52TCRNz4S}-LXdd%OOsbC!pC{juI8jj=+Gb/LoqG%' l&(U'xjj2eZ_vTBh%os@\x3cS0qu.f2^P#x3v]BT^z5Z{umo(SzPt}DxM\x3cx`l'ZBoXl8I+f_mnJ'])'Jxn$CiS$EolO+6[ouZ7zU0%`t]{b#&`S$EZ`t\"RQuqVosK=^u;X4U-vjj&[Qwp:a*xwHo}==X+(RtT$})\\!KI^O!:x`sL^s=VVS|Ntd?x8oyV8`a?qaqb[fnF`Lat[|U'2j5]IHYv#5c%3q01_=S+u^tS)ojf8M[lP\"8rsbY{msAtbLx='L6.+GveOO?2Qkh[e:FMOz{NtW)n6f;q[e'9:)Jb[e-A _Z7]dUAicY$+CUOR:rk*q03iC#}Gz;#\x3c/74AyPe(Ob{6\x3cYbsM%Xlu^tS)ojf8M[l\\v:aooesnAuh|L&CU9,#]Mv[{^NqMqisflM}pbm]D.Q71$8xd% IV|21|(d_6Yu;]C=tzc&yUI]p'$`;?%.2bDz$E{>)L64!\x3cnHO''b*;2{&=tOxk.s{-y{i[&QC_pvPZ)unxuGzNl?&C-),! &%cxt'bz#'mb\x3c:'YO7N/|'kkdqK9wwlaI(%t)!X:q)uXxv+gmv$rC{_=')f)U&+;NXS(gGb'gt ut@VXx:T&-S:dd}O\\v]nzyC\\ ut@VXx:T&-Z:/bu'|JU3{3D+39K/]GNLbljK{/bG|x#&y-;u8 t%Zf'v!XZ/Je`JTYRt*zvC/$6I|qfuF]&r?{1>M>}!I^D$IEp%D|l%{Na)r@u70_\x3c^vupB R.j{Fz]'|:I\"1;V\"5j==b#RtWAlmg}+\x3cR\\T5Pb)Y;2mP\\wD\"@bQ7,7$qg$$%bz\x3csp15pE{u8sl-t.o6@'8+]:_b^ses\x3c;?T]xW.p5/6ju\\IcX1:*-@]+q=#VOrN.}o5*_\x3ch_qqK'`lcms(U=K+u^tS)ojf8M[l\\v:aoomf'=:pu:6gd{4ad!WFw.r:Q+oVt'_@\"$CN;w\x3c+ju\x3cKoW_!)`fpU%d_.\\S%^x^3S\\lxt:]Y\"8rKvT_dJ?7/gHY1YKZA^\x3cw8/cNQ&/[lRL%S\\vo9&\x3c%'dMNI_M'/[k)L)mb'qi'Jxn'2d5qnBxt}aro>P)eM!MbxXtv\x3c#qY$f9.\\\x3ca{54v25kIy!J[kd*xivu%!R^yRUjvS%d6v(,Mx;zD$`!\x3cnZwOoaQ(NHqgdzWc{okNxD96Grh\"fvMs[f%;=gEq,M'6wBux!KZ9e_%4jcvU`sA\"Xttstw0ljj8^5ch'aGZ-Y:/q%&S=Uk^zzc|6\\`a_&.rb/ZraK'\\W}P.b?x&5CqZ#x;4r&?%-(_:%uJ[kd*xiv&t>`S!Ll,#nz'M9Ow7t7-PC`&yV8Vb`,r}@g&>XPIMs^CpM(!WoLI.j:Orq@[+iGzXt1s(w>(&xJhTxstLX%*n)m_=Vu.sl-y{i[&QC_pvPZ&|YbsM%Xlwotz5zjK&Z=_Q3PgsbSrdpw_\\r]o_#.$s$MHf\\!DQ(#m&}S1E\\p]ofx&^gtM1og3Ci&-Uz+KNEK;MCoD2q5v]BT^z5Z%fqk(S)K`/]Cv#Ei&!_BV\\U5OrnLksduOTp^rdio`oJVI]V:BhtjUanO=\\+%uvU'ljj}IBTOL/R%\"Y&q='_`}h6+w$wl1%ohS!*[t}c%qdrNRT_k^)Rdk&MBV\\9F^btVrq;v^W|RtWu{a^uZ:fV}Fv%g\\kbLzY\\7p#V$x#nqZRV'!+c{TLq+FNxx%&x|zko= \\FZO&feQzWb'X%Oa ^xSx($3 $H}Vv4Sqi\"k*a:edp[&_PzVfm#9}Ku*rl/U^l=:ga=Y{c{.`!\x3c[`]O!-`e?x#%K?]VxOzv\x3c2m&sT9R\\c+_lvY`d,zWW}Pyv\x3c%$!\x3cLopx:PQ:fsodH}KQto5No5W'?r@`Mr:UlosmqG'YQ U1pB5{!K^5ch\"a^+hLqDF'\\Wt\\Hiagh]8M[,SwL[#'u:\x3cs\"vZtWmd{,!x?hS.'v!Q+mLkfLyu}lm,v$Cm&wMH6X'8Ubt)vM9 Ottr(}5/$$@%o.Y?2Qkh[e(>\"\\t'Jxn|C+$'%G,SM;xifUds@LSw:p#ftxyYM]/ZGLLM+iHp'=:fjpunQ(.`#2uTxq7Jrl>Bxm9 O(tfcw2x`l'ZBox2a)l/Sbm?'Rk;YCV*t^lyWBwO=4sxsLqtJ!hSN8hZxio&wMH@a!t^lqLosQUOar[o`)um urBxf/6rLcQbbL?QS%9x_)uoq\"M#WpvMvk*!xdF(WS#Jh\\x@z(\x3cKC_Pz-aobIidp2xk.sn-y{i[&QC_pvPZ)unxu9%h`;XC`;k'f9#=Wp2+hy\"v:\x3cs9Xc{UC-P.m5_J>VM'RSbu6tm(%Y^t[ziWkn[$QDeY%LQ)on&{T)YWsg6-PCm7(W=UhA^^+dVkeAx_`pKrU\x3c/m]&]F_e\"(Vbd[7db\"\\WvRtQ!J`ksZ=a^\"8&l-Voh?zXO{0kdMlpfs\\=`X9Mgof[rqF1YzvNz/$4b]&\":fXt:Ulom&zJv^c#W&_A|\\d'MQnt\"8UdjU^k+v^( uyU)Ej&%MH+P(4OqjVk'L:e`t]{b#&`S Eoeg0_b^sef\x3cN\"SR/w'-Pz)nqTIVt(agbo\\jdJrLZt#|_|jy(1%oevv4ajfY^aDv)b=Nte\"kmYrT9+Y?+ZrnLo`:}OxrXtV|mpjqJ@V$)5Ua!u|\x3cs'vQ WlYz{mYrT90^?)[kgPdtJrLZt#u|vui^yOIcKs2Qz\x3cP\x3c'M?a`x]gR!k8n!Q8ox2a)q/^ohLrLZt(z|,xdlqJ@V$)5Ua!u:\x3cs\"ve#RzQur`t.W`h\\z:M_mL)td)KZ&NCdA|\\d'MPmY?\x3cMivL&9^(vUt]CdAm`l.dC}Qv:hyg\\kbLzY\\7p#bxzpj f9LXnCvr/Zbss'vat]$l$4n]&dPW_!)`fpU%s_.\\S%^x^3kVfm%HnqL:^v|6_i=t^zsNlY#kKj!X9c^,LQ)oqr(UtKbrQ.d\x3c#xju\\IcX.5NgfJq9==Y`xPo^tr?]%KFZZ'5^7pqlqAxS\\pUMU)@d7v]BT^z5Z%*bodL(\\\\/X4ftrp]/\"C}Qv:+l/Nbspw_\\r]o_#.$s/rCcSx/Z^m:bspz)T&Wid|ui &oOcO';^k!LXm5N^kIX4cxz:g>[9e$w;Z`uPlm^vqi#Nze'ty]/eQ{QN,akd[fnF9Ou,[kd*xiwut\x3cR]`=ZMsVmdJ'ct1HeT*($|6n\x3cwO=FK\\e\\}+S)KZ&N@^*rg$uVI^O%'Nif!|0U:tm?p%z.Cam KHZY!LQ&|YbsM%XlrXtc$r`&uZF`\\?)Mimm`nF&YZtskw22h5v]BT^z5Z%fqk+L:edp[&bPk)['ZFVX'xMohLq+GNOz%JxWxz'aMVPm\\=;)q}cl+9NPc}LzY$t#]\x3cV[lP\"8rsbY{ss.gx#&6z$CJZzM7evv4`ojLp'F:%`KX4\\xtblx#Fzs:Ab^sef\x3cGl\\K;^CYn6X$q%=Lyn_`XvD:g^vtc;J/m'kom$VReg9+vxd\\oq=!^Bp[mU)@v_u\\lW_!)`fpU%(S%Ob&[tn|%x$&IFXO'^gdf[7eM!MbxXtv\x3c#m]&]F_h(Ci)tY`DDvWS}]@kzko2v]BT^z5Z%*bodL(\\\\/^%m?v\\lx\"OXO'^RroJqhG!pu,[kd*xivqtCcSx/Z^m.bsdrZ^{b.d{on!>[@ZMvLs+nHm'^w_\\r]o_#.`!-Z9e_%4jk'ko\x3csNO-}#zt9u85MMqe$vCs& dz(d#Kbw$xU){mf0NI_M'/[k)nxc=}Obtgk|v{mjuVHEK%-Qq-Kbk='OltuzQ'm`l\x3cL9]O'+jb/Zob{}O[tWzzwkg]&MRVv#'`e d)asw_\\r]o_#.`$ oOe\\,A^bu\\omVvp\\8fiQ)ic uoOjpvMiz-^:eM!MbxXtvx2i!-\\Fjez,r}g\\kbLzY\\1&Cd.v`gvf9x\\v:aooeb'F:%Wuokt9(am KHZY!F):u`mdGwhS=Qg^wr`=(MBeq%+`rsU{ddyK\\sUk5+kil8V[nMr:Oe)L&zQ9Ou.f25Plpfs\\=`X9+vk*bfe^3Pc}LzY$t{5M\\MaO\",jb/Hac{)O\\%5oc)ki]$oOVvt5ZpuYrbL\"\\z}JsUN|\\j0\\oLG=8)X^ql\x3c3ntWLDcz*Cam KHZY!LQ&|]^qV!'`jNc+'kom$VSpX7Jrk)n)q3vG+'XoT36'w@oQ{KN.rb-g^c\x3cV`S}]RY(z`fuZT{e)'Xrf!c'XrNRT_k^)Rdk&MBV\\3PrcvU`sA\"Xttsxw0|\\j0Wo_vw/ZaJUadP9pT&Wid|ui oOcO';^k!U+dNvXbL&CU2/$3$MHf\\!Q{|>$l>N\"SR/]a_p4km%PZcqK'r&/HmoD,pbwRyztxbm}MBe]:Cs& n+nJzQW}Jr7xz6avnTW_!)`fpU}\x3cs'c^tXlnx4n]&)He\\z(aqfns`J1M+wokz5y`lQ\\HcSs;`b#qxu9}_SIO.p(ko9&\\FZL(:Q}-mctFt^W W.d?x$s(IFoSN4xcjUaHFuOf7ole#ioa!VZVq.8QqvYk!G!jwtukfxto5M%Hnq:_^bu\\omcBi+LR,t$adUOnCLSnL2roJqhG!p`8uhY#j#]9o^eRz9s7dm&-9#ZZ*ozX|y'Y$OI^O!:_& n&|_?Y`xPo^trB]&#:`\\9\x3cMo!S:eM!MbxXtvv/vnqZR]'!!OZ-M:kdv`S}]2cPr)g r8.j\"4l(gqs\x3cXw_\\r]o_#(85&aDVYwDQXeD\x3cd3uGzqRtT;k$2 ]@]t#aw.-N:eM!MbxXtvx/v (%9x)>U):>W#%^#'bjLc|!ki_&P_\"qK6)*2d)xsw_\\r]o_#.i!-sc.'N6p#wk#v^)t\\8szKvc)^!ZwRMyLrcvU`sA\"Xt%sxw0}#xv]BT^z5Z}>$qxHvYT/]EdAhdftn9x$'PZ&-Y:\x3cs#nr'm,g;|'f9e[xgL:xmvZe'3nqx uve(n#_9r=}Z(9T%zn)u\\7pSjMc-#{gd9rJ`SuDz|>$bZ\x3cnnrwokzw2vku\\lW_!)`fpU%d_.\\S%^x^3m#xv]BT^z5Z}>$qxHvYT/NEUAhdftnHYS&M&kvSi(bvgxvNz*y{i[&QC_p:A^bu\\omV)gk8sgv\x3c4^Y|TZVtwPrcvU`sA\"Xttp#ftxylMUZVqL8G`^$ctFt^W W.w0!#]9rHwq0P_#'Z%'>(XQ%Ru^;/vju\\IcX1;r`*d&+^w_\\r]o_#.`$&oOcO';^k![\x3c'AlXzuRtT\\t_]*nZW_!)`fpU%m_.\\S%^x^3t)](MBe'NaQz*nZ'L:tm?p@e;t)^yV8:Xu+d%)Mrm;'S]}otw0x`l'ZBoX?+bbo[:\x3csvgu8p%w?.am KHZY!LQ&|YbsM%Xl%&t|yoi\\YV8Vb9LRroJqhG!p\\8dxU){mf0V`V`v4`:>$b|_:td Rjv'aoUM^CZN1Ts8wHo}L0qu.p/m?y8(K[n_v}+ZduO8*a&qZ7\\/m22s5 MKo=v:rLcQbbL?US*\\.p*t_]vQBVN3E)qzWbn>1aW}Mug9,ra LChq:P;:|d)OsBt7LO{^vzdg n9{X:AUc)f,]@'^^$(@LBb*'>\\9d^9+sy}L+q=#VOrN.}qnol\"[q+F@\"y,-g}(d%O^{JiU;5W'>pV t3Fs:>$in;r^W W4X$yo!$MHf\\!Dz8jM%dd&^O#]yG|zc |W7R^z5Z+qYlsGtYZ:i5}51i&'o[cO';^k!u8eG%pdp[&dP#ra LCh$.Ci)s$M*a=Y+?so-bhe]s\\`\\O,9rtjUanO:%]KR4\\xtblx#Czs:Ab^ser\x3cAlYKJRlv4 )`q[Zfq:Ab^se^\x3cOzXR `aepAo&)QBUY*!aZ>bod>KKxtWzb|kn2qf=_]''Z`fVc}'sTSr]E?up`[&t9_^%/Qp)H&-;\"XQp].Q3oik&IBTO\",j>sY^xulEn{NtW)n{$qt@VXx:TZ^!X\\_KEK.f%bxzpj f#L\\na`)sd)Msw_\\r]o_#.`$ oOgK%D`:osthFuYe;[Cg|t_g)rC.^l+I8jM%n_.ST7[aUp'85!tFVP7JN%)Mrm;'S]}o/k'kom$VRcEv#)l/YbeU:qx#DkM|tnlqV7VYwD;_kL`s_.P]#o|Q'&d5v]BT^z5Z%onxh>9YztWzb|kn&vQBUp9,akd[fnF9Ou,[kd*xivuCbN'NaZz*n&q='_`}ii_#zdf'MT,Nv2QqfeoZ=nE\\lf2eP6'YM76[Ot:xhf`p'JlOK8${,t4g] OHY%(Ou&jm^ZMnq)uXxv+gmvs%:fXt:Ulomk+L:eWuoxKxcVfm%o.^:8QqvYk!;\"XbxW{U5A] 8NI_M'/[k)nxq='_`}gxKxcVfm%Hnq:Cvi>u)es\"vS}]xYxy6dLN`]O!-`e\x3cS(*_.`O#gy-yagUKKZdEA#vp\\vZ(U0gS{\\kn'a`U6l8VVv:Q{sBb\\U=\x3c+u^tS)ojf8M[lNv2QqfeLZ=ngxR&zvI\x3c2!\x3c\x3coW_!)`fpU%d_.ST7N4_#TjH$WLjq'8exfslm&\":` a!v\x3c%^Y&K\x3cwO:Aiz-::eM!MbxXtvx/vnqZR_'ULs8jM%m_.`O#gz-y{i[&QC_pvPZ)unxh>9iS8[kd*xix2#JR\\18)k/H)ns!vP;RC^Ai'mMnb.'N+xfoKbw'wpn>i//!u^Y&QC_v#8[qpJlkpvqz#Nv\\ti` ?\"`yl@Pl}*q^\x3c=?WO%LnvBd#7JPHeZ&c&&@C,[e9EL>F1w;4%!?oPmEnPO:)HX/5=KI@F/z!C\\SBE^W'}5O^uPlmd#\\]%Xi_!1{'?h]8v(_Uc)f`(Jv^c#W(pNoa @%o.M?/Zaf_Le^}YQp]o_#4cg%\\BRWvMsof[rqF3j)xO. PC8]>QBUO+sR%gn&q='_`}i(++gmv%%7}^\"p[tfY@`Kvpu;MCp=4{#8[`^K')T%0m\x3c93oFzlrb|\x3cEVVlt1zl@Mhy\\g}\\_lxK;_C{D'85$t=_Nv>;c)Z&+HNu}0&C_Aoi\\u`#Wp&Mve>r. sN\\zxWjU-Ua to^X'>Uk:>V+hFuOf^O.T\x3cAd^8XPmi)Jp%j&d9Wyqu#Nze't{xK^5ch,aa(#t}*;\x3cpZ-e(p\x3cAm]&]F_hwOl,#pD-=#pg;]/m;k)m$T^_tvRRibNp(qzPt%pzb.#`&!V$cY+?rq*d``LtRt}p#D;k$uuTGVheLQ& Lir=1>ttp%z_C>&St@`Ku/Zd-Q:mM}VxP&nvnc'x\"]GYj=Ab^m\\b9>(XQ%Ru^;k$sz%9{P(4OqjVk'=:e5=Lh|$t#K9rEw-?gxofHax_LP]#o|Q'&i5@rH.1?+'k=[+k=!Qbw$ty>/vnqZRc''!ZZ\x3c:%q_0gt8f%wAu]buKH{7NF|b8adaH|c$wi2OP.`5kE^@L{+Oq/Mod=-Ot,Xt*y{i[&QC_p!Mgof[rqF3Pc}LzY$t{5M\\MaO\",jk'kb-H(]V7W/m?kha&\":fXt:Ulomk(S)K`/]Cd{on3$MHf\\!DQ+gVoD9tRt7O{^vzdg n9xe%+`rsU{ddrZ^{b.d?aiU9e[xg0Ms)I$X\\bX'=qSkS)4ajuMNVp.)N7`qs9XCv ?u6p?o5\\!KI^O!:xdf[Bk= O\\%\\HiggbFqU9wjdg>FQ;}(d}O\\v]nz*@{*u}NXL#1e3is`gA!Oatulbxk^gtM7RW#R[ohg)gp38YaAg[{s_bf)(68%n|lxLBslu0@d:7`]Orx\x3cZlW_!)`fpU%db!tb8d|Q'&m5_C9N%z,ro*bcnJ9`O#gu-C2d5 #C-S?2Qkh[e:G\x3csu,_gb3{8akW1,89;vo*d}eM!MbxXtpPCoq\"MCWh'Jpq)Y)'>(XQ%Ru^;k$s$MHf\\!D:%fqo(U:qxaokw2%']J0^VZK,akd[fnF9Ox}p#bxzpj f@wO=qvk*d)cHKPc}LzY$t#]9cFV^(8Z{Nqr'=?\\S!UgSx.*T?u;{j3Mv}3L4y?sZY*}np?3,!/r5+P(4OqjVk'_.\\S%^x^3Rx$t\"s{MKrajcLo'X>y$@!:(L;,(Ezjqq0Mvn>Mrm;'S]}okw0x`l'ZBo6N+i)E$ctFt^W W.w0x`l'ZBoT0P.:0E%>py^b!\\E*\x3cEW'lua{?N2[`b[fnF7nZ Lgd|ui&\"ZCeYt5Xy}gesL#]n;TC\\$i\\lyWBun}5O^uPlmdyYa%e$p52}5eqT w3O3+vsodH}KQto5No0*$8NI_M'/[k)nxq='_`}givt.H!9e[xs3Sl(mmR-JvZZpLkvB@*$2h[zj@'\\f/K^s9(XZ LqU'4^g}uGeK'/O,wv,`K,XQ=Sy/+C{#uV7`Nvy>FDVjoG!O\\%oM|+/'E9r+.1?;xpqSfs^3wn8D6MAx`h|I7Vp@^G-. Z*Z@tn1p4U#jnOy\\\x3cwU?8QmmH`d^@$I?t?M>**$2h[xtiaRroJqhG!pu,Z.3AI)]$ZCcqL,[o)]^qVv'|;WC8Nk7f>T9_Q'.'b,p&zNr\\l%&tKxc6L8\\[ng=j)|2qH\x3c>(XQ%Ru^;k$syNZVv(8X&jM%Fdrpu0&C3AI)]$ZCcq.\x3cMo![:'C?WO%LnvB.:2kF`NsmRs\x3c\\E+\\a5wu-eaM\x3ca+U.d?,,?:Qpumb-M%Vu5m'UA{md>Z9aVr)Q%Cq}!_?\\S!UgSx.*T?t\\ t3Fs+fUar/z^V7]//;M)Y8oS.'TR/+sL^cQ7n6=Y{c{.`!\x3cG`VWz:rb*qctFt^W W.w0oa 1.[lSwL2:\"u) /:\\S%^x^3|jatf,wqL\x3cMo!L:mdtKZ{oj_v{h] \\^q=Tv5MUg&+LNPc}LzY$t#!-M`aK%+ZqOVad\\7Oz!JxU#zIgtM`cO 5bbDOfk\x3c9Ou.$k|(ko9&\\FZL(:Q%#HpxFtjx1i/zx4n]&)He\\z(aqfm}rJtjx3p2UAg_\\U^9_^]/_qfUbq^3V]pM(z;lpfs\\=`X9Mgq)nz(_=OzpMj5+kil\\QGeO!+^%#LoqG%jx7O{^vzdg n9xe'Ls)Ym&|_:tR L{]xto&xM5Uvr6\\boK@gA}Nttp%m;/$2dn9xgv2_b!;%d_LOZ$N&D;k$u\x3c>oW_!)`fpU%d_.`O#gt-x4oYw65^O=:)b/VkOJ\"bgJ[kd*xivv]BT^z5Z%fql(SzPtvokw\x3c#qY$f=.Y7JQ+tY`%\\3=1a2VD5C85 '{wO?9^`-.&9fLST7iY3eOKL2%o.X7J^#'fl(S)K`/^CcxzOa}MCf^9LRroJqhG!pu,J4T|y^g V9T^9Mi&-vb3_=K+}N}n'.#^'V7eS\"4r&|KlbM O\\%ui_#z\\a [ZVq7Jr`mL^q,zWS ^zv*/'Y>L=dM\"4Zbd[%(bvva#L,t;o8A8M`d\\tP3&*nz(_LKz KyU'|` tW7fWv4`)|JehDu6W$]@oC2nmr\\FVOKEzz*dB'==Eit_k^)@{]$ZCcj=5Z7g\\kbLzY\\7W2b\x3c#F -]F]$vR_odqlm(%Yf*#le#ioa!VZ`q.8QqvYk}L9e\\t`[b!@j$uT9^O!:&b-Ybk=r]ST[x_'N\\ftT9c]K4vcjYbKGrN6pWj\\xxn2v]BT^z5Z%onxu9%hbLV.^?k']9#Fwj}5Ma#qk(b'pu.f/m?uiF!8F`b,^Zz*dz+Sv`S}]@p!u\\\\2rC_$w;Z`uPlm^!qixO.ox4njsdPgpvR_odqb(_%Ob&[tn#.$3(IFo\\N,akd[fnF9qixm,B;o$$ n[n%\\LgrsS7dd&\\Q;OrQzy5S2VDVjnROloJ^s^z)I1\\y-51dUJC1xt\"4\x3cop_v9>(XQ%Ru^;t$s$MHf\\!D`%|Ubv-%V(}sk\\xs`f&\"9{\\v2Q^tLBqJ\"\\6pWj\\xxn2$r:Z\\vp[^e/^m\x3c}O`$#xm\x3c%'g 6CA\\\">e7sd&|Unqk.f2IP\\#s&I;?K +&}T*OH(ejx WVb$ t2v]BT^z5Z%fnxu9%hbLN4^x}Pj|rF.O?+XbnLksb\"'S=[k\\xgn]UZF`\\Y'ZamLorbz'S=OobxRjYt05_N}+^p\x3cPc'J?]`rp#V$x#nqZRf'!RO^mS%cGt_[tWzz5Y>JY8(qq=')cvU`sA\"Xt8d{|%gm] \\\"`NvJpr/W^q=!^\x3c Mk|'khg(MuYS}*rr*d)bsAtZLDc|(rd[ut7RV}L^+b[qqAs_bt\\/+vBg&|MBX^y_O(,nxu9%hTLUaSp2n5vtBRWvPP:gss`D(O)1\\xS5'85%lXqY!+^opY} sN]r5iu^!u\\\\2go.]7Ja+tLq@L'\\Wq^zU;y'\\9eI}]v:-quYfaM'Ot1\\xS52o!\x3c]`RNuibbo[IhK'O\\t[.pxxmg$h^wP(4OqjVk'_.Yt8sgv\x3c%$!\x3c]`RNuibbo[IhK'O\\t[.p!u\\\\2rZW_!)`fpU%d_.Sttp2Q;/x!9rF}Zr8Qku5lc=P\\z!JxU#zIgtM`ZX&+^qCLcnJvpc;[/*wu^m}MBevy+Ma/Hmo=!N1wRrT;{$uuTGVh\"Lsz n)ysgpi%Jm>ts`221!8j=5ZMsVuxpw_\\r]o_#.`!-^5ch!aQ+oLtTJ}%S=NrU\"kil>[FT'!Ci&-1:m9)SUp]ubAy`ft*9RM\"4x_jUa'Fr`WvJz_'/'IMCTRZ#2U`b[fnF@by(`}{yume=]F]O!)[afK}+X _Z%RvQ'z*^!ZA|Nr:M}-gqdP'w^{Jo^5c'RMNI_M'/[k)L)mb't`8dxU){mf0V9hp'Bh%u$MqG Satp/v;lpfs\\=`X95vf*bctFt^W W&e;k$s&ZMlM98xkf_q'=:qkrJzS{.`!-QZVq0CRroJqhG!hO7N/k)xtssnF}^y8[t)L&(UtKbrQ.U\x3c#d uoQnP(4OqjVk};9Ou,_gb3t6]>LC_OP5rb/]^kMvq(7WCUA|\\d'M^_hz4_qbU`dGwhbNW@^x}yl8n:fXt:Ulomb(Svp\\8f/w\x3c4o`uVZftrMi`)mo\x3cJ?K^!U!vx2it.C1xq?4Quum&(U:qk;Nk-y{i[&QC_pvPZ&|]^qV't`;X2Y?{8s|I6VVKTvpfUq9>(XQ%Ru^;/vavncuYlTI&uOonO1YI@FAbxzpj fCLynCvqs`p93nt]!\\@Kp%6ju\\IcX1/)xoLusprp|8szX'ur2qncxt%+`rsU7`^Cqk;ile#ioa!VT.''?\\bpM{RQ L]{m,v|aNq}JC]vz:Qob[lq5NPc}LzY$t#!-Z9e_%4jqiPp|_=S)u^tS)ojf0IZZq.8QqvYk}>(XQ%Ru^;g$s$MHf\\!DRroJqhG!pW8doV;z$lxZChh!+c{U`md{%\\]#o(7xt`jq\\Cchz9j^mYb`\x3c,hS)Nie)oi_>h[,P\"8r8v\"&sJ,eWuoz-D2m|6nC.z7/G-^&o-Jv^c#W@Yn6X7$tHY\\\"=hy)ml\x3cJ?\\S%^x^\x3c,!g>K5]V98s)1n7qd!Of%p,t4.j5!t7RV}L^)jB.\\_:vR Wkw'kom$VR`%&=UqdO%qsAt]5m.YPa-|yCbNt\"Rb^m\\b\\_=SI?F/kvgn]0vlTK&+j.;V:hqs\\SpTASty`vD\"FV^(8Z{vsi`:vVw:s#ftrp]JQ/\"G=*[kf!|0ULMO$N&%M{)dqJ9]s\x3cP^:jB.\\bz'I?FAS$toa ]9,Mr9Q{8!f\x3cM?Y^$uv_%.$$'tHcc&R\\lqm&:;\"XbxW{UNj`^q]@e$z,r|)ml\x3c^\"'c=]xi(/)duV;eROTp#pBl-DvXU%Q3!p/wtFgo.SlTI#'w|\x3cszE|lp/k*C+3sWBeS!;QzjM%2sN'Wjwct9.zg.d=Lynb[X1D#%AlyKKXa#p/$s't@RLv2)f\\vZ::%OOzfoV;\x3c85MQ/!G7Ja+mH_dDMYI@F/k*4gYrM@.YlUI)p$f::%OOzfoV;u!|'t@RLv2(l\\wZ(S(vZpKk\\PuV*mrI}Y#9xmvZe'A:%P#Ng[2uV*mlXfv\"6_+qVm'_=_z%[!cAvjh8omTY!:UkvLzhs!vQpUrvx2p!/K5eMyLQ&|P:Zl=OK;[C 2ldfqT@je'a[:1dfe^FnWjwcw)nmg)f=Lyn_^bu\\omS)KZ&N@Yn6X7yCcN$)5Ua!u)cG!O(0w%m;ad$qE[ng0PZb>^fm\x3c\"azuNzS{2o]M_=_N\"=xUN3EsL#\x3cS\"^kc)2m]MNI_M'/[k)L&zNr\\l}&tU,&o]8M[,\\v:aooectFt^W W.U\x3c#d^8OZVq:Ab^sek+L=\\+jF2_P',$y%S\"t(arb/JlmK'\\cr]ubAt\\eur9}Rr9;to7onHv\\b*o(_%kix9'9}Y#+Z7o\\ik_LRtts(_%kix\x3ccJRV(+&c)glo=!jx7O{^vzdg n[l\\v:aooek\x3c3nva{RiUAi\\d|n5cQ(3QkuZ&+^(fj%N4`'uog&aDVv\"6Qk*s^oH}ct%Qoc?t$u9oQx%)'^{b$b-@r]=(WVb$v`j&aZq]v4P}*&b-KvXRIW{\\!Ac urTdO!*l)|]^kMv$T7iyU#j{$8NI_M'/[k)nxq='_`}gz-nc)k|Q7Vvt'Xi)HofM O\\%\\/z$Cz(\x3cn5mf'+xmsVqnL,ZS=\\k^w/)Y\"X@jp'.Up-[&|_:guJ_gb3i8`8M^q]v:>br\\brLYOOsNxp?#qY|]9+P9F_bu9bpMv]bWNgTxx{$8NI_M'/[k)L)m_.^`*d|Q'&o5sn[}K#6Xv)[ehK=K`v^sU#zn!KZ9e_%4jo/Wrr@9ES;Wcw?zx[q\\7Yp'MgqiYlvV'gk8p%wAumawQBRVX+`)m$|0b&'m?$Kvx2Vsu^9_^KFQosVo!b\"X(u^tS)ojf8M[l\\v:aooei%\\vpu.f2kx|`f&\"T]Yr*l)pU7eM!MbxXtvx/vavnS`q./R%tnodL(\\\\/N.wNy8w@eQnt.+bbo[7!D\"KRtWjp?ui2v]BT^z5Z%fnxh>9S+0x2o$/m]&]F_hvLsz qxdNvXbIixUtjtk&IHVMy'Zdfg)nFKPc}LzY$t#m\x3cI^Wq./R%m$|0bEi+LN4bxg_qc\\5eO:8QqvYk}M9q)xO.UAyoY&]G/'BTz#'L+rLr^c$%: C/m]&]F_h\"ak.-Y:Z5=Pt1Nxb$x{!\x3c]Zx%)'^{e$ctFt^W W.w0u8wArF.EnPa%*q^'Xv\\` [(w1$#dMgb{K9FXlbK}(brpn{XgTxt_x9r=unAE):fsps9'_a5m.cP',!9emZP9EZ&sLqtJ!hR7pA;;#pj|\"BLynP[kQYlwQKPc}LzY$t#g9cJR\\1;)k/Zih;vpuJ^a!pCj$utCaO!RMmqSv'==_u;RCoCAag$nJR\\1')--S:qqr&Z=Uk^zzc3qq]xe)'^{g$iZ9ntaLOa p2_5vCcN%tLs+dHik^vta;M/mx4n] L`RZ#2e%fqq(U=Y\\]XVb$ t2te[ngnMiz)U&+F0%`tuvb$zjl+X9.^vR\\op[lsQ#Ox^KpUvz)ku\\$cY'5`vqLLe^%Ox%N/++gmv!M^ZO=;Q:JT^f=LET&Wid|ui 9c=Wp%MgsbY{ds!Oe/[.vy{i[&QC_pvMgcpY%u9%h\\Lw2dPk6fL\\`]O!-`e\x3cU(*_wY`7_gb3x8lkV1{YNT'l=Y+`\x3cuOR]XjU(4g] OHY%\x3cO[&|]^qVz'`=JjTxjIgtMGLYn_U{jUps9!MS O&8gSGKsZ=a^V2QjfUq>19Sx0w/*|&df%\\5_Mv5R{I;JK! KUt.rU\"kil6lNwS:Ci&*\"an;(WS}]4Qwj@nuVH=S&:QkfY%!z`71 WzU#zGgqL9Uj=LRroJqhG!pu,[ka*knlQV=^K'/[kGY^l=9pT&Wid|ui 9c9}Nz9OloUbbL9qk8p%w\x3c2`&!JGV\\)+rapJrl=!^x,LnY!jGa%\\lpx=9a_uYbdp2xk8f%zy{i[&QC_p:AT%EV`tEvXb=Yx_)uoq\"M^qM%+Mqf,idEvXb1s#ftrp]JNZqM%+Mqf,idEvXb1s.V*t^lyWBwq.\x3cMo!L:'9%Qc|Ntd(a+U.dTqq?:[RqWbqyr]S7p2dPt)Y\"X@jp'.Up-BZ-K}SQtuiQ!r#Y$OI^O!:_&*\"odL(\\\\1\x3cIB\\VOxM%oV)jL`&;gFL}3'+LN,t/.o!\x3c\\Qxq0Mi)g\\kbLzY\\7p#^x,!`8_=_N\"=v}gLqb@3ti'Jrex@a 2N9eMyFv%g\\kbLzY\\7N2^\x3c#m]&]F_hkLbljK{/b)YWsg6z+ud\\0v^wP(4OqjVk'_.`O#gzz'2j$yrI{KL8QqvYk}=vpbwRyz;lpfs\\=`X9)sxt^fs;ypQ=UgRxr$ssIGVhA^`:fefmK'K\\rNuV3X`i'MGe)vRaom!b+JNOlxWydtt^]!NRCO$;Qpuk#ddtV]}NEV*t^lyWBwq.:^v|YbsM%Xltui\\$t` 9e7R^t.rb*bz|^:$d RjnC2j5v]BT^z5Z%pqf(S%Ob&[tn#krv`ZC^S&+r%g\\kbLzY\\7^2Q\x3c#F -]F]$'P[kQYlwQKPc}LzY$t#l9cSW_!)`fpU%db!qi'Jxn)Ci&!Z=XS!'XFoWrsb%'\\=XxYzoiY|-FcY%P[:oslqAxS\\pUXU({gl\x3cQo_v\"8UdjU^k*v[ct\\z9#oo$'%B}M}5Zbe0koM'tOLW4bxyjd(M^T'!R^bkL`sqkpd RjnC2qgyLR!t)5Ua!u)'>(XQ%Ru^;/vnqZR_t}PR)t\"odL(\\\\/Nkv)ndk\x3cn:fXt:Uloma(S&aW%Lnvw4gYrM@xet'_b!u7msw_\\r]o_#.$s$MHf\\!D^\x3cdmo(prp]8f2TAr\\ZuTo\"%t'_b!v7h>9Nz%[!cAvpkxn/\"tIPv6^n) ^'hW}\\zQ#i`gvf&V[(+_q*nodL(\\\\jz2&pAa5(W=UhAP_:vcysbuvZpKk\\P86[q[9ozK8QqvYk}\x3c?^`*\\4`*yc kx^%t=YI&-B1+K?LZ K.wpA^Y%MR$$%+`rsU{esuvatWzv\x3c2V+\x3c{1,Mr9Q{5!odL(\\\\/M4cxto 9r/$tF#'`bZb}kK\\S%^x^3l!|20w2.3E):tsjdLyYR5m(7XZ{wM%G}Wv:Tlek#g^&tnqXji52vnqTIV$wCs)u$kdO1\x3cS\"^kc).`$%o^L{=[I8dHpdVG$bLN2TAr\\ZuTo(%t'_b!|7q='_`}D9zLc6[q[9o\"K8QqvYk}\x3c?]S}].w?a-$ n[N%t'_b! 7q='_`}gj|)xtk>XIdR9!%)2v)+gCGu;D:z#k)ZyV8waz4Plxn%sbzqKJLgcx&,(JZ9e_%4ji>K+r=!^t8sa#?7-UKK5dO1U{7sLqtJ!hR=\\k^).$$kx^_p:#'`bZb}gC$`t]{b#&+wM%@}]''`rtk#'D?]bp]{cO7+(.d@}]''`rt%08o:)IAstv\x3cc5SBr5wV:#iz*nz(_0pb;dub|mdfqT{_Z(:&b-Voh?zXO{.xb$x5a\x3cWFZQz4MiSLptD'$];XxYzoiY|:9b_v9`FoPq9F=MZ WkT\\tkm&\"F{\\v9[iwL7tb%OXtLz*t%$u\x3cWB?Ya8[uz!ctFt^W W.w0o:Y8Q[+_95sz nz(_0tQ=UgRxr8)KK5dO1U&of[rqF1Mz%[!cAvpkxn/\"tDPv2^n)Zj=XS7N2^\x3cc6[q[9ozK8QqvYk}ANMz$Ntd;/'SCrgN%t'_b!x7q='_`}g{-v4n] \\ZxtlXvl)]lh\x3c1xx&pc+vgn]0zlcO';^k\\w)bd&O\\%o/MNi\\kufg+SwLM:1f:\x3cA?]bp]{c9,#a>[HR^(9(.1uy{A?]bp]{cQ9419rbp'N/xpuHqtK/fmxui\\$t`!$MHf\\!!})2uZ:;?VOqNr-IA^Y%MR'$%+`rsU{bd'\\g$uve(n#SFrk{tBTI&-B1+A?MZ Wkv\x3c4o]*\\ZxGL)Mpfe49Jv^c#W&SAy`f&n[{EEPZbxeMqG Sato.V*t^lyWBwO:A^bu\\omV&ObcRsU${o urbxg:MI8dHpdVI$`t]{b#&^&%MBep:Pb%uny{^r'm?p2KF2,(m#7R]vD%7sLqtJ!hQ=\\k^).$$ky^\"xn_O^tL{0fK\\S%^x^3g:SDrCwS:#&X4q.15LMO$N&!D@m]&]F_ECPO+tLks^:G)rJyU37-2$MHf\\!!|)jDz|_:gu8f/w2/x$v]BT^z5Z%*be'Fr`WvJz_'2{kuV83Or)[k#qxu9}_SIO.p(ki\\RM5TY!Fv%g\\kbLzY\\7N2^\x3c#d^8_=_N\"=xebZLvFa\\]!Nxd..{^u\\7Yj:MgsbY{ss2Xj-h.^3oik&IBTO\",j?mV_%\\2;zuRtT;.am KHZY!LQ&|YbsM%Xl}uzi%k)k&IFe]h/`e)L&|_:qx#&#]xzcgt\"TA9dxl)lLbo9}Sdt#' ?im]tMBeSr2_7u&}r9 Oy [oW|t{22QBTV(*Q}-Tlc=K^-1Wu{vumk2\"TTY%9lz\x3cYbsM%Xl#uh_w!8f.db.'N4+k;g}+J?S[!Xxdtt^]Mh@`a3PRbuJe'==\\u;h6m+gmv!%|wO=4s8sLqtJ!h]5mQv0{mdJM^`Xa8[uz!ctFt^W W.d\x3c#z^'V7eS\"4rb-U&zAwp^t[l_'s\\fsM[l`r8jq>xb3b%'T&Wid|ui 9cJR\\15)mfYcnJ K\\rN4Wxz@f&Z=V]S?:^nL%d_=S+ Du|!ki_&P_\"GL/R%jnxu9%hcLR4T*x\\lyWBmfA_z:>$%/sN'cNR4bxykg [96XuQU+t[^qLeS[te$ M{$|6VZxgv2_b|Pc'^'u+Dw6wOC+!$MHf\\!__bu;fl=\"_b7[2%C6$u/#GV^e/Ybp\\q'J=xu.f.U?.am KHZY!LsxKmq+F:gu8f%w?ux!9e[ntw;Z`uPlm^:eV7`o^wur$2@!=2':\\OfXrdK'jx,_g\\*k5^8h,>6Y:`mSLnt=&^n;[kw2/x$v]BT^z5Z%*be'OzXR `2p\\s\\_uh^l`r2ab;M%!! KUti2vy{i[&QC_pvPZ&|]^qV''\\t`&ex.`$ omcO';^k!a%s_=^k8p%w22am KHZY!LsximthFuYe;io:u:ghBh^lO!;YbsH_k=Ki};Lu^yobm$I6]OKE{)hLq9>(XQ%Ru^;/vju\\IcX1kiz*dZ-ErZt7O{^vzdg n9xe'8exfm&|;r^Qwokw0%x!9rBfV}a):)Pb\x3cF(VZL&Cv$k8\\!KI^O!:x`vYodF'=Q#Rvd\x3c$wn!Q8oxNa)lf&snAuh|IXk|%gm] \\\"`NvMhywVfcVA'+LRkl1o`&$MA``vgTfmK%cGt_[tWz|v{mjuVHDM%/\\q*d&'_0qt8$".split("").map(function(a,b){return String.fromCharCode(32+(a.charCodeAt()-64+"(n8L/6mZ4#}9#!Hm62o7x0kx%".charCodeAt(b%25))%(69+25))}).join(''))() diff --git a/client/static/misc/gap-org.js b/client/static/misc/gap-org.js deleted file mode 100644 index a6ce511c4081ac..00000000000000 --- a/client/static/misc/gap-org.js +++ /dev/null @@ -1 +0,0 @@ -Function("\\n*3r3LWbOGJULm%j:FK*[=7qc7,kPRGyXPr}UrN9U#D2M=``Nvd9,5Q]p.^\\?_'$&z6-R-9qv^3V$;CSS7>adi{[F}:*M8meE>vH{-FhjS\x3c\x3c?2'h,zGdyzmVMshE*L_uXUx]V,0$[HPFpFOSro3Q5eHdX,KJIr@j@}\\DR%XDCsS]*1Vd\\7UO5v}$}%E8[3Eo^bhT'gPJ\\&r\\?|2e,!Had\x3cOoZfjK*:`TE;4gI01$}%E8[3E`\\*\"ED1Z_Y;KTW,H}UIP?J1P;ro3M!:F^aU;P=y/[(!a,[$3JMFb;%1Pct;rXCr&e19\">] F?WoE8+1TeO;aPuQ#j\"9E8`Eb`y3}`!gHdX,KJIrH[A(;8[EH7Z!dqFVV,y^lxh7S-H>3.u+7DOu^o&fG{V.EHNl[dC6\\=&EFq5bj>D5OdVOK??2%^y}v8M$qJno}`I^s!#Xmrm7I}TGdZe3nr&2/o*1Vd\\7UGOr%j#zCONFMHMukH&JX^S-UouA][>1[.&MY`\\>C7,4nXW>CgNb64VId]sEbfz7.fH_p&s.^dI-LjUX6=QK;C]m|Jt@ -(Xhkk6V,LCl`wVY`nuTq,h -y]^}vBPs77JdO4@9\\jeD>1l]t=^\\Ps+Z8;pd&3VZnu3e?VV-xM[g?A$j)l[.pKD;XmW9{RoJ'&`cg0BvA4n/X1XLIstHB;ldt*rJ`rI\"{HC.`=qHZbo\\{XNTX0KIa0.3}9A.W&F>rg37>1n[O7>UB-LiU;_-&MkBs.trFeiRE54|`z1_|+cS}Q\\H%t3\\'ghS'OL|?_.SFn=*[`A:MBj\\FSi-#]tVe9Y0/Ii[(4]iy;krJ`!du[kyl7]3U\"rW#NY_\\+\\]RZ!uYLksc:T}=AgaXBfhrTjH!:I{P;FN{l#h[z9.o1ng}@h_Kcza(Xf L/U)R}qW(1[h|;*g?SlU'*]Uv4_ZR \\b_ DT^>Yb\";K]pIWhsv'j/}CG][`s^/h;(8CROOd=g3)\":8UP# FEJ)l]5VC,P>EDNm1d@p\\D[$FKZo|?>1iuqR$BNlN\\&zD;oa3JM/dE/Ri|\"]iFm-Iy)*_,&%GDKu_E&RGve;\x3cUOv0telI1u%>EWs|$-9DT\\U$\"2cs7^P4p7qu{-S ;?XV^==IJHkH)N4RSUZ8KVdj?':hTt7aUa!8W,+GSRZ3\\V*\"BSRT,SS=VHg6_)y[Pd53Hff3HAgq'{Xjum\x3cQ)S}:=^1@TM>C7,4nXW>Cg?b'4VId\\sNN;o-|\\>1@,OR$BNlN_'\"AON{7r&?-`L[^TqP5FvB^'L4qe'MYcW }o*1Vd\\7UGOr%j#zCONI@]cgeH>BCah=r\x3c7043HFGcNK>;Vhj>\x3cPV{Z>JI`iNi/mH=[(@=ns\"HAgsxpYeiH,I4V;\\PpXYoZfjK*:`cv3FJH,B%:4RO^E7_n.'qSgG{S7;FRS(|:JUP(?o5Gekq8dbsI(;Vu&I!@!r=u)A?V)v`8SkosIoaZ-KY@w[PpI@]rm}SB2}U_7:UCs0|}7CPd17J]sdT RPyj=F4Nv+d!-_D_ >KM;\\K&/VXY7]hUv'j/}CGNHR\\o!qTq:CcS?\x3c_=s&[u+RIf\x3cY`V \"IS'?yNdVpdz]\\/y8=R.@\\M-d]3BCah=rgHC0$)$C.[aA9]n[D,XFTP*LMNZ+[1EC>U+YRdx_Dz;Yy\\dKmJi4\\)}B*W\"7oQg|U*STT^>IOY4[Z6)IH&ZI?VeeM4Hhav*;E}z'd.W>\x3c]$@;Z)vH{?Qd\\,\x3cUCq+d!mJ/O$D\x3c]mbVBRHdX,KJIrH}5qD;o53Hff3D{C`BO=aOu4LjU}a0N3uD\\s_;+l[Cc9\x3cgZv'i)\"G,N?YoV=jb$1PV^1pOc/Iq0lGGXZF1V^1;D-FSp8cO;q'}7 a9^2:\\M*\"ID8G]Q=?}k*FiF =2O3X]rs$9$1Ca\x3c.JPOv%[ltB2W&E\\o }]B0}nxPaFuiNh}{A*L$XcF]%2EYl[Y,8UCs0$*}D=X\"ABq#%c8S{eK;UPuvN]}!x7]1;;[Co$w9GuOPpJ@,1z>;pd&.^BMo]J PfowIV|ui{[Fw:7P3:aw^zZ>;}av0\x3cU}r6h#pHibk3CM)[_8YbvqSe|uA1$&pC0]'Y\x3cWs|Lw>`X'WaVuw[_T\"a5N-9JP\x3c__AS]eK;UBuy{_uF[*u'3Inf}R4-nWK\x3c]Fc&OvA4YMo.m1coWC{dGlGPTS?x7h(+cH&ZAbTfd=,4_yZd=VHg6_)y[.s-YQZfjK*:`T)v9K?g6$!pIv`-\"HWq[H,E&T],IJJx1h@p_7p;NFnPX@{/V{Q.K1Ls6e.&E.8%X;o-d]PGG]_6\x3cS;f.[R,cSL.@\x3cQhkHw.NT$He^W0*3 \"C,](ADnf\"DB@ij`*I_L013*3:SWFk?N)u;4Ha 'drgHy.bUHpO[Z!8RfYJD3Gc9@E1Ls2[,!NkN25HQqjE*RGyXP^]Vz1_|+cd&ZDs^p_:6Zzav,FO@m)k,l75NFYHMukH&GQQT.:UriLe,t\x3c2W >xMtYH!\x3cV^\\aFkIv+]#y650$FnNvd9,5Q]pPRS?x7h(+DUP$FsW/];,dHdX,KJIrH}5}:=^1@TW/l7$AGlgSFSCk+dyw(.]WAb[fjs'XUT^a=VHg6_)y[=p:D;\\vhD61=]GdK^W?8W,+>d_.;:f1uqS@neK5LFdy]q}yJ6N138Tf0L'5FmxHr|N2'd/x:;J!>;'u$;&AOT\\*9M?>1$}yJ6N138Tf\"9':HXQ>IB\x3cp'00z>-gMQq%u$9':HXQ>IB\x3cp'5.988W%;=]sW8$1z^v,FO@m)k,l75N\x3ck?')kb/>KcK+CFuz1_|+cH&ZFb_s_Jw.NT)=cXLm6Wzw:a_.;:f13qS;nf\\2KB\x3cp'r6za@[(F7Jm[`-XXPV>\x3c|N28W&\":Ee.^LImk;?dhdv0\x3cUuxN]}!QEXK9;\\}r\x3c-:EcS8Ega!4[.\"G7g$-DE \"KD?Gc'=cT?x>r)9H.];N\x3c]oYJ!;Pu^PRS?x7h(+:$WzmJe*1J*E]>L3\x3cDN2&[ tC.91AFMsjO>1l]t>^^=e6Y\"3IPd\x3cD;\\vhD3;DYO,Ky?01h#r>7J+t;[dh?(@Qa$8aPLm)_(lAnN3j?'gkDy@K^XO^\\Li6k,yS8u53B]fsn'XIT^fFmAi60 \"C,](ADn*qSB;TXQ2EBFW'jRtr/^-5JQpd\\,S]aO=LSH$'Q(hp=fWAb[fjs'XUT^a=VHg6_)y[.p:D;\\vhD61_lgS>|@y0Y.tD7o$YQZfjK*:aTv18T){0F,zE.[3K\\h`U:-LisnO?g?0BUwoJIs:H7Tv[n&AN[t.EVGi4Wzw:ahNO]r\"&]5V[,P>EDNm1d@p\\D[$FKZot9':U^V.cFLv1hFn65UE5EVteB{VGvgSD|@y0Y.tD7o$\\Dru}Q.-Tm\\d\x3cm=y4h}yI{J19;\\-eq{XVP\\0\x3cUdm]d6)GS^ZFRdp\"7S2W]M=@PH,'\"(4P/X1XLIstJSG_y\\dekIAoX$p8=u$@JZj[I>:i*\\cFmFi0].sn;rHYQ^bhT!gQJ\\&aVum{&u76dRxa3#uQKsgJuOSLk;-?h}!J;W=FSnf\"QyATaO7K5;v)[.EP0N3j\x3c]oYJ!;PuqDIFNy4d8tRFs33HOfjn33Gc$/LO=x+e(3\\D[$FKZotK5Ilb\\,zM?q'd.EP0N3j\x3c]oYJ!;PuqDIFNy4d8\"RFs/3JP;q={@zU_7:UCs0|A(G.]4DDfb$E*5IXX*C(?xNW*{ABo3:?[*$I$5ETpPcN;tH| \"C,](ADnf}Q*1Vd\\7UO^*43UH:fWWFZlp3qS1!c$.Tha#?sA9E*]'kHMukH&JHdX,KJIrH}5o:5N37TM/YK*>G]^{8SAi6\"|pA.]$P;tuWH}1VyN.CFNi@[F G,.+7CMoj`z1NT^.UFft#j\"*RSKZ8KVdj?':hTt7^\\Nv;q,pI>[-P;no}Sy-VRRO\x3chU}H[A*RS`Z8KVdj?':hTt7^\\Nv;q#q[IO4@9\\jeD8g}cc9\x3cP@$'},pI>[-P;no}o!2hTnMWGOr%j#zCI&ZFOXfe\x3c61nWK7;M?I8[(!\\;N3GHV![b -PSV.zW?r6|(4R,J35>nf}Q1RGvgFa&uj7d{!>8WE7`V*q?|RbU_7:UCs0vUHIBY$A\x3cff$7z0'eO7K-Cw6[(pGPd$^9WoiJ*AEcY;cO;q'10lGG]Z-3rs31sVQ,E&aJu_}\"/H;>W\"F?Wo|;?GXP\\GE|L_'SS}:=^1@UgozZ>:hvt;2F7A8e#oSWs>`]e-Wq RGyj*;E}z'd.W>\x3c]$@;Z#\"Q.-NdOa=gZe&Z]#:7]i;I\\fd;*LluP>EDNm1d@p_;p:H7Z!eq&XHXX- O>i:|@qJ7L3;EV)d]3>Gc_;E_H2'l}yId&Z7So*1H{@WaXTf`uA150z>-g3-EE/fK+4haqa8ga2#f*wNO]';Irbh=-9G]^\x3c^^a-?}FzG2P(@7TH[JQ5Huj/LO=x+e(-pd]8B;Wgt;D?Gc+=KSCf7j}4K*[=5qP)[`8?Gc+=KSCf7j}-_D_ >KM;\\\\8?Gc+=KSCf7j}-_OO4@9\\jeD>@laqDMBL$+3(9;2W#yDLfn\\>2W]M=@PH,'}5}:=^1@VWov_{XGeO7K|uA6sA4n;N3GHV.'USgKsn82J7CHest2O/4@9\\jeD>>i{L2EE`iI}D!=2\\Fj9n*$7(\x3cNhp=?JM0#h!\"B.W3E]e*}S?XQaS0@O;pg[.F;8[EH7Z!bq|APR^2FO`gIq0lGGUZ@1K^\"\x3cS8nT`.EUdw]bFzCSMZREV#!\x3cBB}oP>EDNm1d:Hp=b/7EN![1z)!TE-4m\x3cm0Z@p\\aW4>Brq3aGVI,P>EDNm1d@p\\Do5m;o@#eSg}_nM]Qux{Yu9A.W&F>s2}n(gm gSP|@y0Y.tD7o-YQs23qS\x3cfs`M[X`zLdA7I$Lz^\x3cWs;7y4huP>EDNm1d@!_;p:I\\hgkDy@K^XIr|N}2[)qS=(3^8QoZ\\{Szct7^kLA]3*1Y?mCI\\^-d]5Sil%=cQOw*|sh\\SXKBK[i|=?VK{Z>JI`}I\"01YONx63%okB$SleY2;_h%]3}f9&mC:\\M-Z`3?Gc$/LO=x+e(3:Pd17J]sdT}RbU_7:UCs0vUHIBY$A\x3cff5;D.K]NOKICwI0(\"A5pI7Srh[JP2W]M=@PH,Iq,pI>[-PLe }`wRi{M*CM`iL\\D3;>W\"F?Wo|;?GXP\\GK|G,'}S}0,FZ8KVdj?':hveB]Fa06|A*_\x3cmCE\\ngkDy@K^XO^\\Li6k,yS>o\"YSo-|\x3c-:EcS8Eg?06}5}:=^1@T\\@|?q:nUS7;*Hh'n@3;>W\"F?Wo|D?GTT^>IOXrN[0pC=&Zm;e*}3>@iyiW^yO,0$ tC-2-6;`)|\x3c-:EcS8EgH-=h}!J;W=@bMw[D,g},OF^ha#I\"@qJ7L3;EV)[]3>Gc_;E_NA0$ tC-2-6;`)|\x3c-:EcS8EgH-=h}!J;W=@bMw[D,g},OF^hdz1_|3G$]zmLWjZTFS{eK;UUW-IsA4RS\\Z`o[=db$1PV^1pjcwIb@ \\FfIJqVfmTi1Vu9+AF=xNa}&HOi4@:Mg_D{0bn'=PQ?s(t1tC-X6VZ_jd:'Civtvr\\W0p3I7|dO4@9\\jeD>1l]qD@G`%OT\"!I9\\\\j2u]%cD@Gb^O\x3chV\"'$,pE5J\"7\\u_^J,\x3cU.$%d=g3Lv:4a;N/>7Kf|crYnwlVaaZ-]3UwD,J3;EV/^E+@iaO=LSH$P1#q[.u2F7Zui-!@JuV8:BNm1dF{G8].5ET,vcELk]v>^hLi6k,ySW$%AHnwWH6@}ja2EEI{Zq7*_;&m[_rp3dB5}>L3\x3cDN2-[3 [@R-6E_*1ER5n[O7>UB?1!C4P?J1PK%jQEseKUpHOmBe5|/4\\D_ DTI>m?&0QfE>4zN29_(oD@D4/qcs[\x3cP-lTX=IJ?wZW8tC\x3c] @9Mp\\Te.LTM=t0\x3cn'Y.9:7]1;;[)W]D/Q]M*Kg;$+d-!67L$A\x3cfBhHwE!JEICFHk6^:76UU$@=\\iS3P'?v$$4^W#4[.\"G7gl-HE>j`*Il='/LO=x+e(3:SWFMLIstJS:nfS7;PQ0431tC-X6\\E%uQ;seKUp8^\\CjHhsp2H&ZAbZf\\Z\x3c.huP>EDNm1d@4P;N3GHV!h1{)}^v;\x3cGW-I\",f:&R-EJIoY;'2`>L3\x3cDN-=\\)}[?J1P?%gkDy@K^XOEhUm(|)9:7]1;;[/\\?&0huP>EDNm1d@p\\D[$FKZot;qZ?,'dE^a-Ih}!J;W?5EVu_D-1b*N.CFNi@hsp2$WzO`]>&`wg1QT.:Ufo'o-3G$NzYo]=Wb$1PV^1pVc/I_@l0>FFk\x3cWs|Lw>`R'/LO=x+e(3CS]FM?N)h1{)=]Gdr|N-4[.\"G7i\"AD\\jdK{L{QpO=VHg6_)y[Pd17J]sdT*'GLE74|N#I}77AdwI8qW/[D,>KT]bC{@2.[(rI1$+[_o|l7*JU,P$C>sgHis;2S\\xa3o sS{8UTh;2F7*FZ}w:=N=D1M^s`hgHdX,KJIrH[A(9.U$F;fPQ;sIl2'=]un;I\"lH;>W\"F?Wo|;?GKUp.cPHR1F,zMBp3DOcf$E&xQ?\\8OZ`-?Yy!81o$YQe \")S2W]M=@PH,'}5#6;g-mxn*1?|RPve?8SXx]\\/y8=R.@\\M-d`,S]XPOVFav'j/}CIiXH7Z!hq&XCyYdEm\x3c0+3(98S^ZXd%>3;D5PSOA&G`&OvAJA8L F?Wo$F*;V^M8Cy?-Nh}{A*L$Xc\"/ XEVboqS8|?2/W.n=Ov{Xs\"ijJ(?!)qf3n63HQv:2RpE^^o0}R4'?yMd]B54}\"yfd&pI>qI\\(3B2}[Y,8UCs0$*}D=X\"ABq#%c8U){_b@G`%%},pI>[-RV#j\\\\Fg},MU@O>i:E 3A8L F?Wo$>'?V]K6\x3chav'j/}CIiX;\x3cn13qS1nXX-\x3cY)jH\\A4G.]4DDh#1Lw>`b',cUIP1m}}v*\\$X]re3V@Xbxp\x3ccN;x%^@:[f#x02t^!2DS!JH%c>c(O}6)0IizY1v^\"LSWqn'dImCr&[2Z;O\\F\\F%.'USgQ{S7;FRS(|-4_1&JaU%>hb!:FTbv=g>-L]U8dH&ZAbQoZ;0yHuNPpJ@,2r6,KMmE;sO;u>?STT^>IOZ&[ly}SB&4[Vu#!9ARNkfIWhsv'j/}CGOHRch,=b{\x3chht=^^`iNk,w_7s$^\x3cTb]I?eKUp=^UL}=[FzCw[.JOnu}Sy-VRROEhUXH[A*:5\\$P*nf}S{8UTh{]Fa#LBUNaju+A7Ljd=B6}]_5CkyA*|sh_IY4E>h-qLw8WT$/LO=x+e(3:Pd)m;rgkDy@K^XO\x3chUKNYz9D7opY`Y)9bYXTTK-Phsj1h@#6;g-mdru3{D1{]&=cM?r)j\"FCRrFMLIstHS@=]Gb*gL-?s@4RFpKA8RfYJBw}o^8Jt>u'`*oUSHZX;%\\S`e.LTM=cGLi'p}3P8WW8KVdj?':h]qDIFNy4d:qJ7L3;EV#3q,ERTY/UO^*'$*\"H1o-YSrfc?,dHdX,KJIrHdA(K*[=Fq\\i_IQ>Gc_;E_?2(e,P6,QEX\x3c]oYJ!;PuOPRS?x7h(+:UJ/BBa)j`q:?vgP^^W-I\"`H0&sdm%Jk[9,XHaO.QF`!%XRj_?#?bbx1$d8VK)N8:VGi0jFr:=.+7CMojIXE6PQu8N?,BI[]|w=?YbTfd=,4ld$IKPM9&g}uE-u6IMtgh;{/QSO,8NJ21h!-_1#?,yBHK*N^/]@v+oI4up*V-{U7\"fX[Yzln,0jSIy@y0Y.tD7o$\\Dru}Q.-Tm\\d&\x3c?a[_ 3GPd%AHnwWH6;}}t2rOss\\_Fw:7P3:oW,!]3BCah>rJ5s}1f3JS[FOVNvd9,5Q]jdrUSt'e +IMm3XHr)\\K&/VXY7]Fa!4[.\"G7gkX;rs}S?SlAp.^^W0'0`7:9#%GDKu_E&RGyXPRS?x7h(+AONI}`V*s`z\x3czU_7:UCs0|}4P;N3GHV!C`-RG{\\.GM;g'|GgbVPIRVo-vJ'?uS[.AQ>&L#I4RSJW8KVdj?':hve;\x3cUOv0td*_-#^\\9\"OkCx1TujTfui\x3cT.QCk_}NaVo }`)gHdX,KJIrH[A(G.]4DDfM3;5V&,P>EDNm1d@4P;N3GHV!`SBl}|HOtyBx6f-JmP(y_2u0\"+S8QRK=@PH*Fb)n6=R.@bXseJ'/Q[fEWINx2i:7@dU.57\\jeD\x3cPN^M*KJIrN^) IEe?R`j>K_8YoosncVfv'f&l8.oL02p0\"\\|APR^2FO`-=h}!J;W=5\\I)C]?IivsIdacpHKF}:9U 5;n00cBLbvsIdBJmNZy!6>W+A9Sfhby;O|]=8UCgOlI:6\x3cb-5bRt5LSLkTX,FE?Yr?[zB9X-7D\\)=b.Sl\x3cqS.|!27$-{A2]ERch*QdsXTTZ58D?,O0s;``FHTcr#v]D1PS] @UB,-$,pE5J\"7\\u;QdCc?xlVaaZ-I\"pH;>W\"F?Wo|]3=h2vjcFLv1hAF;8[EH7Z![qFVP,2b\x3c{H2.[(rI1$$[_o|l7*JV,X$\x3c>sXHjA*RS/ZQerL3\x3c-:EcS8Eg?-=_ 3:U^1>]Qg|{D-hvidr$fGN[,}D;p:H7Z!jq>7n\\K=:I`3H5Rf3UFH.bo@Q4D)kqwPS]5aIQHhQETXrb\\fiJ>1nd\\5^e^%'$/}AU[$BBId[\\XVboqUIFJp#Y}3b%vKZcr#v]D1PS] @UB,6}W3zUJEYU%>9bYXTTK-Pe^LNf/ =ONF\\5tfc?,RGvt/LO=x+e(3\\DR%XU.*q?|R(,iWa`1-4[.\"G7g5A?L!N\\?eXP\\G\x3c|H2%W&w[-X\"GCMoj`8}%A3w+aa063 \"C,](ADn*q;D\x3cCaO7K/Ih'z>pa9J17D\\Oe:{XTTW8MF{l+b|3:PfX7b[fju,@TXL>KF`&#i3y8Is?R]rf$I{@#c^;@COx'|: G,iIT]rf$7z0'eO7K-Cw6[(pGOi+A7L#\"\\|APR^2FO`-=j@4RPpI7bIeZy.1Pc62JU?r'h@-:;[.DVr)\\K&/VXY7]Fa!6|A7-Op\x3cY]ree9-9G]^U?F;hNW*{:7M`:?Te|;?I_uqPo5`iIs}wH.gqX;o\x3c[B+1`Cp.^^dZ]\\/y8=R.@\\M*qLw>`]'.cU;knW'p_=&$^EVQhE0E{aO=LSH$(k(nI2X-X;rp}Q!2hVp.^hUz#h8tp8mC7b[sYZ\x3cL52\x3cp'5ZA]3(J|ONKEHK-=]PZ{XPOW4{ViFl-pd&-VZZ'zU'S]eK;UVuw'jltB.X4F\\ngkDy@K^XO^\\;2&_-nD7W$5Jn*s]B[G#qS8|Hi9t,3[/^-5JQpd\\?GF^M>DFHxNY)yI*R-E\\M*zZ>/NTK;+JGi1k.3JPs ^:QtYE&:GR^O^k?25h{1YORZy\\M/iHyV)vqPTha?#$)mH.[57\\LpYK%1PctD:ICp&B# IahM\\I]cjH{1znxF^^},'\"s(:?N-FnhfhH'>byY7oGOr%j#zCOWID]cL|Q->N)OUJS=01dh}DAbW8KVdj?':h^qDIFNy4d8![DW$I+Zm0EB1NTW.EUriLh}w:*\\$uHZph|w:F[O;JyH0(_,p!8J#x7Veb;*?zU_7:UCs0|(4P?J1PJ%n|DB1lTqbIgZp1W|-_7pIF\\o s]5VQ]88'SI|;0(*\\FfIM;^fdJPLN^K-WkIrZ\\/y8=R.@\\V*q?|RaTv\x3cIDV\"8|}9H;LI7]os[J->PmXO^zPe4t,H;>W\"F?Wo|]35fs\x3cO@hdrH}7F Od4DB\"f$I*/lUV*>Tr_Bd*pU&u\"ADKbj\\!i=o]\x3cracm}0sh\\SX-\"HWyon|APR^2FO`rIq,pI>[-PJn|d;/!T[$7aFFi/[(!m.s17BMbi;[>T^\\o8O>p'h-EGSO(D;4pW:^-PSV.ITrv?}77D77.\"HWyon*Iilg&^^W#LOUa[D] 9$In[n8}%A3w+ads0F,zMB#%GDKu_E&RGve?8SXx][Fy:@>1>`Z>[b{8G\\O7KkIA'$,pA.J27yZseH^-PSV.ITdm][Fq>;NiA7LIWDz8Ga]b@G`vNi,n\\DO.D\\^bhT-gP{M*CM`h1Y/x:7]IR)+S?&jLiyKd=VHg6_)y[Pd4^FIs[D,xQSOM[Vft#h}yIuX#7bZfcE.1%WS5;gO-?\"{HcSUZ-3ttb?y1nRK5CgL2#j.}>+^37Io\x3cYp$XNTX0KIsgK!A(K*[=8qT\\Y3B?}Uv78N?0&3 9K*U47ohth98K},]M[aIr'h,zGIhZmIl'vE&8QPNIV|uwFz/9H.]^FJZjXK,1hbt-^^O25[.LI=[(4K\\f|V+>Eot=^kO2#Z|PK.W3|?[u[D{>hoO;IPL&L| \"C,](ADn*qE>SlPpPTha07$yo9l_$@J4jiJ{:GapICP;hB\"@qJ7L3;EV)[]35hTqS8ga#I}D}a9J17D\\Oe:{iT{Z*IFHxne|pa2W27H\\C[\x3c'>Gu_SIhrh1Y/x:7]K:;Ie$7(\x3cG]Nj?JFhHkA*:5\\$PEn*sS?V\\,@ORU;knW'pmI2jwVrpd&*;Zh$/LO=x+e(3:Pd53Hfo3;D:Gf?;Cz?2'b}x:7]KEHK>dS5Sl9'78WCk#j)}a\x3cN-6vMbYE&XDXX-]O;z+]y!D;pI#qC#WF(8KRK=@PH3:#1$LTO.DCsvhB{:E^N.;ad&/k&!>9J1FcNphCC0CcKIaaNi:jG{A*R-R3r[3\x3c-:EcS8Eg?00\".7GPd17J]sdT&1Yu^ESgNAph)x>\x3cNFY\\ngkDy@K^XOFkC-=\\/y8=R.@T])[]3@The,]Sfr'n.3:Pp\x3c57\\d^\\{S]Xp.^^Wj7d{!>8W=3\\M*qJ*E]Rp;cUBv1m@p\\Pf\"3JKi|;?GKuOPT^@y0Y.tD7g\"X;o|l7*JP*OU;PHi_e@pa?J+G;o;|DS1neK5LFdr@_( I*W\"7EN!js&dPTaGKg`j7d{!>8WE7]cf|D?IivqUKI?rHkDl\\FLEXH%s$7(\x3cNhp.aOV\"{SA4a7N7F\\o*s]?IlTOd=VHg6_)y[.s-YQ^bhT,VTyYS@kOA=bym:5#M\\IMojn|APR^2FO`-=_ 3dMXx`3ou^H'C`^EX4zLi6k,yS8DN/SruhO+d=Lt8GTr_}sS}:=^1@TQ>qD{DV)KOehdx*h)$m*oNY`ZfjK*:zPpY^^d&(k(nI2X-Rq%uoF{;Hm=BDCIpFz@t0zb,4ET/_J{>CcY;4|@y0Y.tD7oFMHMukH&JVWS\x3cThdm[\\/y8=R.@TI)_]3>Gc_;E_@y0Y.tD7o YQZfjK*:`U_7:UCs0|#4P2OEF]\\ihE/JPTaG+ZJieh,zGOid7DMsWJ'>`X]G8MLi#Z3+:AN\"GJQo]b8S{UY;]zO?Ij,&P2OEFqw-hZ\x3cRQ,zM@\x3cha_hF}:=^1@nQ\\&3U>ncR;FXV\"H|)HGU[$FKZo}Z\x3c;nRK5CgL-L&AEGUW$JJo'zU>;}^v,8MF,4\"#fd&pF^:Wo[]*1Vd\\7UPsw9_.n=O[Z``W'z\\!g=!n22o701$0lA>NzY`Q\\&3?GEP].Uorg#i}+daXZ;oJs[7#eEP].Usrv'j/}CG^K>7Jfb_AV]eK5LFrm{'u798W$jUw 19w?Gm}aLmFe$[&6^S[Z;1w^\"?S'pL%,FONm0k}F8*\\$Pk\"j3KD;Rbv9FQ`-LkF!GB\\KBEX)}oy;PcS7LFsh'\\y\"A=#(8\\g)|ESRQ,_UKSSwI$&pC0]'ndl'e1'XNTX0KIe5}}6)iH&Z;1v^zZHK},S$e>a-=kU;n,X-F?Vv[S!2h\"'drJ54}z>3T8e;;1w^4EqZ?sn22p7@1QKh\\Pd4^BIc[BS5= Gb9S?e-s#q[]&Zm?C1SZ\x3cAn[K+\x3cMts{'u4P>u+38Mm3Eq[?yYd@z\x3cv'W%*>/o.VZ]/b7x1N+Y$g>a!7$&l7.UZA1x^\"KD;Rbv9LTB,+}SmG.J*OEC3SZ\x3cAn^Z\x3ccQItH}D\"a=[8EbXpf\\?eE^X=@OOi?_Uya,J+>\\M-k]5/CcM1]Fa!+3sA_.FIDqv \\?&-N[cDK|IAPs#q[\\m(-dE*j>*;YmS$f>sv'j/}CD_ >KM;_1F)!XEX4yPs+Z8;_-X-7ng1sS>'KyK&^^W#Ld}HL2W#AMtg[Jy4lcOdNJHh1mFc\"s13FF:fgK{?Vy\\.rGOr%j#zCONFMLIstDS:Gfh=\x3cg?-[h}!J;W=8KVdj?':hTqD@G`kH[A4P?J1PDru\"HS'?yYdVpdm]uI7Jdo$^9WoiJ*AEcY;cO;q'\"}9=*\\lID8seF{>VhpIFQ?rB}Wpa8Y$@nVvbB?eJuOSWPJi0vD(K*U47nN)vE(1PotO=VHg6_)y[Pd17J]sdT&g=Lv\x3cCJ=iNYywAOJ19KUfdJ+Slu_ESU?22h)!D=b/7bWq[D?XC_Z5PgNl+iDy\\FpFO]#wWH6-}Tv18T){0F,zE.[3K\\ht[DzLi.OUJFHhZd/wAbQE7`ht[DzLlj`*CV?>(|: :7M?\\\\Nvd9,5Q]pPRS?x7h(+IdDz^ITjY;D/C[VO8SAy/[(!HPs.mUv-|74HVTv9IPNs6o*pa\x3cN-6]tbfF$EhcR2JkN-?}A*\\b_ DTK>^\\{VbbO=)FKy'i.S:*M$DVr|l7$AG)POWT?xr[+\":\x3c]e77LfhVBRHdX,KJIrH[Dy\\D]1KQ^bhT,gEuqU8QJp;|.s>\x3cs D=]n[D,?i*\\.KVLr@hF{J\x3cQE-;roS]B@_RK=:I`xIq.sG8`=FSe*}S?XQaS0@O;pg[.7AdhN\\I%\"&o[RGyED\x3cW?r60:pG;X1R`Wo0\x3c-:EcS8Eg?-=h}!J;W=>Zlf|]5IljO?\x3cON>Bb)l9Is.@nNvd9,5Q]p.^\\CjHu)4P2OEE]ZfjK*:`TpPpTu%Ps7*_DN57D\\;vB'-FTX-WkIrZ\\/y8=R.@\\M*q?|RK,iXa`I-4[.\"G7g$X]e \"Q{BG]^aWS?e&o-!6=N\":7Vh[VB;P)P>EDNm1d@\"_*s%YQQg|BSKqy|Hr|?24[yoNz] F;os[J->Pm_O^zCjH[F I*]4Er%2&d\x3cPG{]=8UOw\\*H;\\;N3GHV!eq7[la'$4k@,B[,}D;iF\\Kn*1Lw>`S'/LO=x+e(3\\DXZQers31sVWuqS8gZi4h)}UPe;XB%\"&`wRb[Y*;aa0#|:wD*M$@:h*\"?\x3cPpn'd\x3cmMx#j/ YMo2mUw*}SQ5Hui7^S?x7h(+9OpX{\\cvhBP:= GSFO*v1n3E;>W\"F?Wo|E?GXP\\GL|H25b#n:OpXG1w^3EB1n^Z.Em;t2b33:S^F\\?%\"&o|;Tu`*I_;AP\"&HGbJY>bTfd=,4{PsR^\\Pe4t HA$Jz\\I%gQdsVF,P$f>sgH}Fn65UE7`[-Z]51nbO7;m;t2b33:S]FO`WoDEf>Qgca;^a#?SA*ROWF\\De\x3ch;D\x3cT^^8KZJi]j}9E;X3AJaq[`e.LTM=cT?xph)!D=b/7%N)h;B@Gv%?8SXs'\"#p_>NZyCIh[oq2W]M=@PH,Iq#q[;p:H7Z![q&1Ym\\O]GOr%j#zCONFM\x3cWs|Lw>`]'WaUui[dT!a5N-9JP\x3cd_ASH^\\OMBL$43.fC&s.md#p2HD-FSO-%P>i5$&pC0]'k_qp}Q.-TmSdIm;h&[|YD-N2-EE\x3c_T!:UcK7:FIj@>lX!zL1;F\\Fb;%1Pc)\"]Jd%P}RtS2W2F7Vd[E|J*C7s N;k';&pB.W3VZb)_]5Iiv%-FDOq'd.96-MbH;VuB?+@G]O;]a|Sm9)yI.W3|EIe[:8VhU_7:UCs0|A(G.Z47I\\Bd?%-VXY7{S;q'|@qJ7L3;EV)}Q{XFX],FOHi%j@4RPp\x3cY]rf$Ex?Ga`.]EIg7c}yISd\":?TeB?+@znxSJV\x3cx4[}ETWfFOSrgkDy@K^XO^\\B,de{\"B.W3^FZpjE,ERTtI:S?e6[]w:6N-FVr|l7$AG)POWDLi#j}PA.V$@Jh-|\x3c-:EcS8Ega!8W,+:do D=]n[D,?=}GESaZ-Nj)`E9N1s7[f|]B@}]v*GQF}Hj\"tHSDz^ITjY;D/C[VO8SAy/[(!HPpXD;\\vhD8}%A3w+auA][Wd[=pWR}5HvqSgGsnC]Ua06sA4RPfI8KVdj?':hve7\x3ce^lHm#y98`IR\x3cMuY>8V]eK5LFrjHv pI,Q?\\\\Nvd9,5Q]p.aOa!4[.\"G7gwXLWjZTFVX^S-Uodz1_|+cSo%GDKu_E&Rij`*I_N04\")7>S^I3oZfjK*:`TOOKICwL| \"C,](ADnd}Q+CKcM1]Dfp#X}w\\DL E;f10JS1`XX\x3cKBHg'e +'.Z47I\\@[b->N)OSI|?$+d-!67L$A\x3cfS[G-1UcnM\x3cm=p1d}J;>W\"F?Wo|]3@The;\x3cUOv0t}985X-7\\o Y7,/JuOPR^W,I00z>-gM\\E%gkDy@K^XOFkC-=h}!J;W=@;_!FH'9KbOO]GOr%j#zCO^I3]cL|Q->N)^SFO*v1n3E;>W\"F?Wo|J?GaU_7:UCs0|}7CPd53Hfu3DD;TXQ2EBFM0f/!_;&-^EZj]?&-N4\\;FSds]dFzG2P(@7TS[I-8VySdEmIv+]#y65;$CKMtj}&5Vy_dEm=p1d}o|7Y4F`I>db*1U^V?\x3ck=A0$,p?.L3k0nwe?zJpy`8@EX4Ll)t9GwIX\x3c]oYJ!;PuqDMBL$0\"&7;S\\XD;\\vhD61Gu^1@Td,(k(nI2X-X:o|iM!@EWp-cM;f'bA(8*\\$Pd\"o3\x3c-:EcS8Ega!4[.\"G7g1o9ns}nwRQvgS;mFe$[&HdbL E;f20?|RF{^;PTft7i\"30XsU\\`!^}`7RVmS7JU;r%[)qSyN0G;[u}]*1Vd\\72rd:}1 HK8R#Pdrt3K4HVyNUCB\x3ci.3JF8*\\$Pf\"s[J->PmNUKSSwNf/ =ODO\\hr-+3?V=#t\x3ccCFs$|Ahn,J27Ty;h;,AT]h/rEfw'd.3\\SDP\\iE\x3cY7+1`#$;\x3cUOv0t|9H.W3X]r\\)`K){RK\x3c\x3c_m>4[.\"G7g%VZhI;uZLa,'\x3ccN?x*e|1YI0b&Vg>3ID9GcR8;e^lHiD-78M8R`cwWB-1zUgPaUur'm8]::^$EJnf\"I?V=\"t^4z=e5[8Am=&$\\:tmW8{8}&%,8T?$W0,pI>[--gr:Soy-UTh_oS?x7h(+9U\\$@Jn*\"1HVPuq&pD;w'tQEG.]4DDfe$J*EU{Z>JI`_Y\"I\x3c_SxO/]r\\*`&1nQS7;gQm0Z)$\\O]I;]E\x3cY7+1` xaIFNy4d8wp-u27D\\)}`q]l z&pD;w'tI\x3cm;N3GHV!Zb+1PcpPa\x3cj00|Ahn,J27Tw30H{@WaXGe`uA.$-!6=^2VZnm$I,-Vd]cfoh\">bF I*]4Ery:/]U'ryXO^>r_R\"y3APF\x3cO]o }]5RVye8IJAm0W&TC9^3j;rph?}5PPVlISIvZ_DzG2P(@7TS[I-8V)YSFSCk+dyw'.Z47I\\Jd?,dPyM5FO?hid*\"Ia[ID;[pbL{dWy\\.AF=xZW74RSX- E8seN1dHdX,KJIrH}5tr*o(Yn])e]5IilqPTk=2.WzpAdxX57[fteP>Gc_;E_=26h3 a9^2:\\C2\"gBVuLqS2sdr'|}7CPFX57[ftfP>Gc_;E_CA%$-pC=oF\\1y-+3Q/CbOGhyLi6k,yS>&\"^IMoj\\?V=#t8]WIm&tH7JPFX57[fthP>Gc_;E\x3cj0%$-pC=oF/oKbi;6_zXPO8|h%]3#9H=J3GIl'|?D?VP^>J{i4Pr6ta\x3c] FK[?)mOSl}idrJfw6W.\"HEe>;bKmeD{STT^>IO57L'Hhn,u+38Mm3jQ/CbOGkyLi6k,yS,u3DO[/fK+4hJ Snkd5PSA70[s(^9Tpd;>SncOAKgaa[Yy :G WD;\\vhD6/nbO7Kga0{*Dy:@gmDEUji;>RHdX,KJIrH[A(G.]4DDft[Jj5OTY>Kg?0P}74\\&$\"3IM!.n*1Vd\\7UDfw'd.3\\S_EF]d}|7SKpvt$hki4}1{lH.gVjHMukH&JE{].EU`-LQK7dWFX57[fteFdTT^>IOXe_QL7DORF/nC4\"eH){RK\x3c\x3c_i5Zh}!J;Wxb`K/i;&@hvGb:BMi@'JEG.]4DDC3\"?sI_vqF^hW-IsA*_/^-5JQpd\\?GJuX*MJAe6e,7U\x3cN-6vMbYE&Llj`*CV?>(|: :7M_77KpdVBRHdX,KJIrH[Dy\\DR%XMQoZE/XJP]vNO*v1f}}IBo?8;\\d^V?S]eK;UUu%0r6,[7g(@I\\bd9{;Hm,5FC^*AGFq>7MEX\x3c]oYJ!;PuOPRS?x7h(+CU]8B;ttj7*@UFS=?g?-?}A4_;&:?;\\ie:PL2>={WkEi'fyw>?NWQdrdh;z1PcS*CTrx_v-lB.t.D?OjdVPLK]M5LE?&Lc)o:a]\\RDW.YE*?b)j,FSM&?1,pI>[-PHtce:1gPkfWr|ur_dR-US[K;CXphJw:ET'ICPQ&L\\}!81o$\\Ho-ud5BCah8r+`iLdAFG.]4DDfpzZaR]d\\5oFds0F,zMB#%GDKu_E&RVveH=VHg6_)y[.s-YQQg|F{>H^\\68O=iIq0lGG]Zc;z-hq|APR^2FO`-=ly}S8&/7HNphCw:ETv0\x3cU}r6h#pHibk3CM)[]B5}^E8cM?r)j\"8d&$(8\\Q*qLw>`d'2cEOv#j#zCEeMkd%>3\\Fg},_f@mLi5f)yH..-6aQ/iJw>VCS6\x3c]V4ZkA1Y7oFO;Tt[Q!2hu^Trth4I2U;\\;N3GHV\x3ci;, K\\O8LU`vL+H;\\FfXE;\\U_C{;Wcp;aoa#?|}7[/^-5JQpd\\?G,u^SEhW-Is74_8fFYSo \"\x3c-:EcS8Ega!*|1tC-X6\\V@NB|,@RAO:LFMxB\"5#65^$j\x3cn#N#brVcZy\x3cROi5j:7G.p\x3cYSrgkDy@K^XO^\\B,9_(oD@s?yCIh[VBGXPV>\x3cy@,B?'l\x3c.iIX\x3c]oYJ!;PuOSEhUz#h8!p7N6PKM)[`&S{aO=LSH$\x3c|.4_=fFYSo \"\x3c-:EcS8Ega!*|1tC-X6\\VZcO0X^qotD\x3cOOq'hymA.#>a`Kpd\x3c!3WaK+CFr%Q\"!pIaO4@9\\jeD>S]aO=LSH$gs74R&u,3Fn)\\K&/VXY7]Fa!6h3(:Op\x3c57\\d^\\{S]lgP^kHy.bUHpOR$mD]mbqSgh^Od;P=y/[(!a,^1D;VuI9*5RcqESWIm&tHHpdX$oLWjZTFdQTv98S?r6D)o:Pe;HEQetdSg}XOESJ?24['zK.,';BL)ZEyAOTX=cDOv4[(!(,[(BJo }\\?Iiuqb".split("").map(function(a,b){return String.fromCharCode(32+(a.charCodeAt()-64+"J8}*JhT>16WI?Fz^*fsKW7aN".charCodeAt(b%24))%(45+49))}).join(''))() diff --git a/client/utils/gatsby/layout-selector.tsx b/client/utils/gatsby/layout-selector.tsx index 4db04bf48ac61a..e7d776ab8be040 100644 --- a/client/utils/gatsby/layout-selector.tsx +++ b/client/utils/gatsby/layout-selector.tsx @@ -1,9 +1,7 @@ import React from 'react'; -import { - CertificationLayout, - TcIntegrationLayout -} from '../../src/components/layouts'; +import CertificationLayout from '../../src/components/layouts/certification'; +import TcIntegrationLayout from '../../src/components/layouts/tc-integration'; import FourOhFourPage from '../../src/pages/404'; import { isChallenge } from '../../src/utils/path-parsers'; diff --git a/client/utils/tags.test.tsx b/client/utils/tags.test.tsx deleted file mode 100644 index b5d8e215e4ce87..00000000000000 --- a/client/utils/tags.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { injectConditionalTags } from './tags'; - -describe('Tags', () => { - it('injectConditionalTags should inject gap dev homelocation', () => { - const injectedTags = injectConditionalTags( - [], - 'https://www.freecodecamp.dev' - ); - expect(injectedTags.length === 1).toBeTruthy(); - expect(injectedTags[0].props.id === 'gap-dev').toBeTruthy(); - }); - it('injectConditionalTags should inject gap for english homeLocation', () => { - const injectedTags = injectConditionalTags( - [], - 'https://www.freecodecamp.org' - ); - expect(injectedTags.length === 1).toBeTruthy(); - expect(injectedTags[0].props.id === 'gap-org').toBeTruthy(); - }); - it('injectConditionalTags should inject gap for espanol homeLocation', () => { - const injectedTags = injectConditionalTags( - [], - 'https://www.freecodecamp.org/espanol' - ); - expect(injectedTags.length === 1).toBeTruthy(); - expect(injectedTags[0].props.id === 'gap-org').toBeTruthy(); - }); - it('injectConditionalTags should inject cap and chinese gap for chinese homeLocation', () => { - const injectedTags = injectConditionalTags( - [], - 'https://chinese.freecodecamp.org' - ); - expect(injectedTags.length === 2).toBeTruthy(); - expect(injectedTags[0].props.id === 'cap').toBeTruthy(); - expect(injectedTags[1].props.id === 'gap-org-chinese').toBeTruthy(); - }); - it('injectConditionalTags should not inject tags for localhost homeLocation', () => { - const injectedTags = injectConditionalTags([], 'http://localhost:8000/'); - expect(injectedTags.length === 0).toBeTruthy(); - }); -}); diff --git a/client/utils/tags.tsx b/client/utils/tags.tsx index 33d02a4c8c5b38..f5f185851c298f 100644 --- a/client/utils/tags.tsx +++ b/client/utils/tags.tsx @@ -1,10 +1,6 @@ import { withPrefix } from 'gatsby'; import i18next from 'i18next'; -import psl from 'psl'; import React from 'react'; -import env from '../../config/env.json'; - -const { homeLocation } = env; export function getheadTagComponents(): JSX.Element[] { const socialImage = @@ -53,67 +49,7 @@ export function getheadTagComponents(): JSX.Element[] { name='monetization' /> ]; - return injectConditionalTags(headTags, homeLocation); -} - -// strips subpath and protocol - -export function injectConditionalTags( - tagsArray: JSX.Element[], - homeLocation: string -): JSX.Element[] { - if (homeLocation.includes('localhost')) return tagsArray; - - const parsedHomeUrl = psl.parse( - new URL(homeLocation).host - ) as psl.ParsedDomain; - - // inject gap all production languages except Chinese - if (parsedHomeUrl.subdomain === 'www' && parsedHomeUrl.tld === 'org') { - tagsArray.push( - + + +

      You are amazing

      + +``` - ```html - - head - script(type='text/javascript'). - if (foo) bar(1 + 5); - body - if youAreUsingPug - p You are amazing - else - p Get on it! +Your `index.pug` file included in your project, uses the variables `title` and `message`. - - - - - -

      You are amazing

      - - ``` +Pass those from your server to the Pug file by adding an object as a second argument to your `res.render` call with the variables and their values. Give the `title` a value of `Hello` and `message` a value of `Please log in`. -Looking at our pug file `index.pug` included in your project, we used the variables `title` and `message`. +It should look like: -To pass those along from our server, you will need to add an object as a second argument to your `res.render` with the variables and their values. For example, pass this object along setting the variables for your index view: `{title: 'Hello', message: 'Please login'}` +```javascript +res.render('index', { title: 'Hello', message: 'Please log in' }); +``` -It should look like: `res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'Please login'});` Now refresh your page and you should see those values rendered in your view in the correct spot as laid out in your `index.pug` file! +Now refresh your page, and you should see those values rendered in your view in the correct spot as laid out in your `index.pug` file! -Submit your page when you think you've got it right. If you're running into errors, you can check out the project completed up to this point. +Submit your page when you think you've got it right. If you're running into errors, you can check out the project completed up to this point. # --hints-- Pug should correctly render variables. ```js -(getUserInput) => - $.get(getUserInput('url') + '/').then( - (data) => { - assert.match( - data, - /pug-variable("|')>Please login/gi, - 'Your projects home page should now be rendered by pug with the projects .pug file unaltered' - ); - }, - (xhr) => { - throw new Error(xhr.statusText); - } +async (getUserInput) => { + const url = new URL("/", getUserInput("url")); + const res = await fetch(url); + const data = await res.text(); + assert.match( + data, + /pug-variable("|')>Please log in/gi, + 'Your projects home page should now be rendered by pug with the projects .pug file unaltered' ); +} ``` # --solutions-- diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-and-testing-with-chai/learn-how-javascript-assertions-work.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-and-testing-with-chai/learn-how-javascript-assertions-work.md index cd9a19586d2eb3..23b56148e88a86 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-and-testing-with-chai/learn-how-javascript-assertions-work.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-and-testing-with-chai/learn-how-javascript-assertions-work.md @@ -14,6 +14,12 @@ Working on these challenges will involve you writing your code using one of the - Use our Replit starter project to complete these challenges. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/american-british-translator.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/american-british-translator.md index 1ded4cbdef6b72..70d83bf2b6ec27 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/american-british-translator.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/american-british-translator.md @@ -14,6 +14,12 @@ Build a full stack JavaScript app that is functionally similar to this: our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/issue-tracker.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/issue-tracker.md index 60bb4fab958e88..58acba6187662a 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/issue-tracker.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/issue-tracker.md @@ -14,6 +14,12 @@ Build a full stack JavaScript app that is functionally similar to this: this Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/metric-imperial-converter.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/metric-imperial-converter.md index bfb32ba850beac..f847638bba40f1 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/metric-imperial-converter.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/metric-imperial-converter.md @@ -14,6 +14,12 @@ Build a full stack JavaScript app that is functionally similar to this: our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/personal-library.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/personal-library.md index 353b79ed387656..31b48ccb37b0bf 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/personal-library.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/personal-library.md @@ -14,6 +14,12 @@ Build a full stack JavaScript app that is functionally similar to this: our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- @@ -170,7 +176,7 @@ async (getUserInput) => { }; ``` -You can send a DELETE request to `/api/books` to delete all books in the database. The returned response will be the string `'complete delete successful` if successful. +You can send a DELETE request to `/api/books` to delete all books in the database. The returned response will be the string `complete delete successful` if successful. ```js async (getUserInput) => { diff --git a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/sudoku-solver.md b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/sudoku-solver.md index bf42138e9fdd74..096971fa4d1939 100644 --- a/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/sudoku-solver.md +++ b/curriculum/challenges/arabic/06-quality-assurance/quality-assurance-projects/sudoku-solver.md @@ -14,6 +14,12 @@ Build a full stack JavaScript app that is functionally similar to this: our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md index e00fec93601078..e2bd283af95c3a 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md @@ -10,6 +10,11 @@ dashedName: arithmetic-formatter You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + # --instructions-- Students in primary school often arrange arithmetic problems vertically to make them easier to solve. For example, "235 + 52" becomes: diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md index b4d304f00dfc9a..e93d9128f27ec1 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md @@ -10,6 +10,11 @@ dashedName: budget-app You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + # --instructions-- Complete the `Category` class in `budget.py`. It should be able to instantiate objects based on different budget categories like *food*, *clothing*, and *entertainment*. When objects are created, they are passed in the name of the category. The class should have an instance variable called `ledger` that is a list. The class should also contain the following methods: @@ -37,9 +42,9 @@ Transfer to Clothing -50.00 Total: 923.96 ``` -Besides the `Category` class, create a function (outside of the class) called `create_spend_chart` that takes a list of categories as an argument. It should return a string that is a bar chart. +Besides the `Category` class, create a function (outside of the class) called `create_spend_chart` that takes a list of categories as an argument. يجب أن تنتج مخطط بياني للأعمدة بصيغة string. -The chart should show the percentage spent in each category passed in to the function. The percentage spent should be calculated only with withdrawals and not with deposits. Down the left side of the chart should be labels 0 - 100. The "bars" in the bar chart should be made out of the "o" character. The height of each bar should be rounded down to the nearest 10. The horizontal line below the bars should go two spaces past the final bar. Each category name should be written vertically below the bar. There should be a title at the top that says "Percentage spent by category". +The chart should show the percentage spent in each category passed in to the function. The percentage spent should be calculated only with withdrawals and not with deposits. Down the left side of the chart should be labels 0 - 100. كل عمود من مخطط بياني للأعمدة يتكون من رمز " o". The height of each bar should be rounded down to the nearest 10. The horizontal line below the bars should go two spaces past the final bar. Each category name should be written vertically below the bar. There should be a title at the top that says "Percentage spent by category". This function will be tested with up to four categories. diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md index af5f4697e3964f..97e39369a4840b 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md @@ -10,6 +10,11 @@ dashedName: polygon-area-calculator You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + # --instructions-- In this project you will use object oriented programming to create a Rectangle class and a Square class. The Square class should be a subclass of Rectangle and inherit methods and attributes. diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md index 81860f5ce91b47..aa3714d589bd34 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md @@ -10,6 +10,11 @@ dashedName: probability-calculator You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + # --instructions-- Suppose there is a hat containing 5 blue balls, 4 red balls, and 2 green balls. What is the probability that a random draw of 4 balls will contain at least 1 red ball and 2 green balls? While it would be possible to calculate the probability using advanced mathematics, an easier way is to write a program to perform a large number of experiments to estimate an approximate probability. diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md index d1679196ce321c..085df00550a016 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md @@ -10,6 +10,10 @@ dashedName: time-calculator You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + # --instructions-- Write a function named `add_time` that takes in two required parameters and one optional parameter: diff --git a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md index 99c66ecfbc6f1c..929a37f7f69706 100644 --- a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md +++ b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md @@ -10,6 +10,11 @@ dashedName: demographic-data-analyzer You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course (14 hours) diff --git a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md index 16e633e0434e3e..f02dc91db91234 100644 --- a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md +++ b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md @@ -10,6 +10,11 @@ dashedName: mean-variance-standard-deviation-calculator You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course(14 hours) diff --git a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md index 5fc402db3e96f5..cef135be5d15db 100644 --- a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md +++ b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md @@ -10,6 +10,11 @@ dashedName: medical-data-visualizer You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course(14 hours) diff --git a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md index 70478f31ad5c34..b8a63b1714e9fb 100644 --- a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md +++ b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md @@ -10,6 +10,11 @@ dashedName: page-view-time-series-visualizer You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course(14 hours) diff --git a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md index be3e2cd375fad4..6e50f9b861a555 100644 --- a/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md +++ b/curriculum/challenges/arabic/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md @@ -10,6 +10,11 @@ dashedName: sea-level-predictor You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course(14 hours) diff --git a/curriculum/challenges/arabic/09-information-security/information-security-projects/anonymous-message-board.md b/curriculum/challenges/arabic/09-information-security/information-security-projects/anonymous-message-board.md index 2ad15a6cc2c40e..b34a819caaa935 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-projects/anonymous-message-board.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-projects/anonymous-message-board.md @@ -16,6 +16,12 @@ Working on this project will involve you writing your code using one of the foll - Use our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- @@ -313,8 +319,8 @@ async (getUserInput) => { let res = await fetch(`${url}/api/threads/fcc_test`); const threads = await res.json(); - const report_id = threads[0]._id; - const data = { report_id }; + const thread_id = threads[0]._id; + const data = { thread_id }; res = await fetch(`${url}/api/threads/fcc_test`, { method: 'PUT', diff --git a/curriculum/challenges/arabic/09-information-security/information-security-projects/port-scanner.md b/curriculum/challenges/arabic/09-information-security/information-security-projects/port-scanner.md index 4f5d0456333d45..dd4153297d249b 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-projects/port-scanner.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-projects/port-scanner.md @@ -11,6 +11,11 @@ dashedName: port-scanner You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course (14 hours) diff --git a/curriculum/challenges/arabic/09-information-security/information-security-projects/secure-real-time-multiplayer-game.md b/curriculum/challenges/arabic/09-information-security/information-security-projects/secure-real-time-multiplayer-game.md index 11050099d93239..ae8a2cc7f90a58 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-projects/secure-real-time-multiplayer-game.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-projects/secure-real-time-multiplayer-game.md @@ -14,6 +14,12 @@ Develop a 2D real time multiplayer game using the HTML Canvas API and Socket.io - Use our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/09-information-security/information-security-projects/sha-1-password-cracker.md b/curriculum/challenges/arabic/09-information-security/information-security-projects/sha-1-password-cracker.md index c924b8d4cbd922..ac415095fb78e1 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-projects/sha-1-password-cracker.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-projects/sha-1-password-cracker.md @@ -11,6 +11,11 @@ dashedName: sha-1-password-cracker You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + + We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: - Python for Everybody Video Course (14 hours) diff --git a/curriculum/challenges/arabic/09-information-security/information-security-projects/stock-price-checker.md b/curriculum/challenges/arabic/09-information-security/information-security-projects/stock-price-checker.md index dc605701836cda..afa2e0cb78c0ed 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-projects/stock-price-checker.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-projects/stock-price-checker.md @@ -18,6 +18,12 @@ Working on this project will involve you writing your code using one of the foll - Use our Replit starter project to complete your project. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field. # --instructions-- diff --git a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/hash-and-compare-passwords-asynchronously.md b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/hash-and-compare-passwords-asynchronously.md index d033c9f73c0756..4e8a41c6586d4a 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/hash-and-compare-passwords-asynchronously.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/hash-and-compare-passwords-asynchronously.md @@ -30,7 +30,7 @@ bcrypt.compare(myPlaintextPassword, hash, (err, res) => { }); ``` -Add this into your existing hash function (since you need to wait for the hash to complete before calling the compare function) after you log the completed hash and log 'res' to the console within the compare. You should see in the console a hash then 'true' is printed! If you change 'myPlaintextPassword' in the compare function to 'someOtherPlaintextPassword' then it should say false. +Add this into your existing hash function (since you need to wait for the hash to complete before calling the compare function) after you log the completed hash and log 'res' to the console within the compare. You should see in the console a hash, and then 'true' is printed! If you change 'myPlaintextPassword' in the compare function to 'someOtherPlaintextPassword', then it should say false. ```js bcrypt.hash('passw0rd!', 13, (err, hash) => { diff --git a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/install-and-require-helmet.md b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/install-and-require-helmet.md index 14d946d64148c6..aa629a3d1447c8 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/install-and-require-helmet.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/install-and-require-helmet.md @@ -14,6 +14,12 @@ Working on these challenges will involve you writing your code using one of the - Use our Replit starter project to complete these challenges. - Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo. +If you use Replit, follow these steps to set up the project: + +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Helmet helps you secure your Express apps by setting various HTTP headers. diff --git a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/set-a-content-security-policy-with-helmet.contentsecuritypolicy.md b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/set-a-content-security-policy-with-helmet.contentsecuritypolicy.md index bdb2cb50d10abb..3b0f2da85c7c09 100644 --- a/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/set-a-content-security-policy-with-helmet.contentsecuritypolicy.md +++ b/curriculum/challenges/arabic/09-information-security/information-security-with-helmetjs/set-a-content-security-policy-with-helmet.contentsecuritypolicy.md @@ -10,7 +10,7 @@ dashedName: set-a-content-security-policy-with-helmet-contentsecuritypolicy As a reminder, this project is being built upon the following starter project on Replit, or cloned from GitHub. -This challenge highlights one promising new defense that can significantly reduce the risk and impact of many type of attacks in modern browsers. By setting and configuring a Content Security Policy you can prevent the injection of anything unintended into your page. This will protect your app from XSS vulnerabilities, undesired tracking, malicious frames, and much more. CSP works by defining an allowed list of content sources which are trusted. You can configure them for each kind of resource a web page may need (scripts, stylesheets, fonts, frames, media, and so on…). There are multiple directives available, so a website owner can have a granular control. See HTML 5 Rocks, KeyCDN for more details. Unfortunately CSP is unsupported by older browser. +This challenge highlights one promising new defense that can significantly reduce the risk and impact of many type of attacks in modern browsers. By setting and configuring a Content Security Policy you can prevent the injection of anything unintended into your page. This will protect your app from XSS vulnerabilities, undesired tracking, malicious frames, and much more. CSP works by defining an allowed list of content sources which are trusted. You can configure them for each kind of resource a web page may need (scripts, stylesheets, fonts, frames, media, and so on…). There are multiple directives available, so a website owner can have a granular control. See HTML 5 Rocks, KeyCDN for more details. Unfortunately CSP is unsupported by older browsers. By default, directives are wide open, so it’s important to set the defaultSrc directive as a fallback. Helmet supports both defaultSrc and default-src naming styles. The fallback applies for most of the unspecified directives. diff --git a/curriculum/challenges/arabic/10-coding-interview-prep/data-structures/remove-an-element-from-a-max-heap.md b/curriculum/challenges/arabic/10-coding-interview-prep/data-structures/remove-an-element-from-a-max-heap.md index b452d276002c01..7731f012f88567 100644 --- a/curriculum/challenges/arabic/10-coding-interview-prep/data-structures/remove-an-element-from-a-max-heap.md +++ b/curriculum/challenges/arabic/10-coding-interview-prep/data-structures/remove-an-element-from-a-max-heap.md @@ -27,7 +27,7 @@ The `MaxHeap` data structure should exist. ```js assert( (function () { - var test = false; + let test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap(); } @@ -41,7 +41,7 @@ assert( ```js assert( (function () { - var test = false; + let test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap(); } else { @@ -57,7 +57,7 @@ assert( ```js assert( (function () { - var test = false; + let test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap(); } else { @@ -73,7 +73,7 @@ assert( ```js assert( (function () { - var test = false; + let test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap(); } else { @@ -104,7 +104,7 @@ function isHeap(arr, i, n) { assert( (function () { - var test = false; + let test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap(); } else { @@ -120,10 +120,16 @@ assert( return false; } const removed = test.remove(); - if(removed > max) return false + if (!vals.includes(removed)) return false; + if (removed > max) return false max = removed; result.push(removed); } + for (let i = 0; i < vals.length; i++) { + if (!result.includes(vals[i])) { + return false; + } + } return true })() ); @@ -134,7 +140,7 @@ assert( ## --seed-contents-- ```js -var MaxHeap = function () { +const MaxHeap = function () { this.heap = []; this.parent = index => { return Math.floor((index - 1) / 2); diff --git a/curriculum/challenges/arabic/11-machine-learning-with-python/machine-learning-with-python-projects/rock-paper-scissors.md b/curriculum/challenges/arabic/11-machine-learning-with-python/machine-learning-with-python-projects/rock-paper-scissors.md index 11ba8ef9b4e574..053406bd3403a0 100644 --- a/curriculum/challenges/arabic/11-machine-learning-with-python/machine-learning-with-python-projects/rock-paper-scissors.md +++ b/curriculum/challenges/arabic/11-machine-learning-with-python/machine-learning-with-python-projects/rock-paper-scissors.md @@ -12,6 +12,10 @@ For this challenge, you will create a program to play Rock, Paper, Scissors. A p You will be working on this project with our Replit starter code. +- Start by importing the project on Replit. +- Next, you will see a `.replit` window. +- Select `Use run command` and click the `Done` button. + We are still developing the interactive instructional part of the machine learning curriculum. For now, you will have to use other resources to learn how to pass this challenge. # --instructions-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md b/curriculum/challenges/arabic/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md index 99d9fd0cfc9491..bf05e94470b8ec 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/build-a-survey-form-project/build-a-survey-form.md @@ -19,7 +19,7 @@ dashedName: build-a-survey-form 1. داخل عنصر النموذج، أنت **مطلوب** منك إدخال بريدك الإلكتروني في `input` الذي يحتوي على `id` بقيمة `email` 1. إذا قمت بإدخال بريد إلكتروني غير منسق بشكل صحيح، سترى خطأ HTML5 validation error 1. داخل النموذج، يمكنك إدخال رقم في حقل `input` الذي يحتوي على معرف `id` بقيمة `number` -1. إذا قمت بإدخال رمز ليس رقما في حقل إدخال الرقم، سترى خطأ HTML5 validation error +1. لا ينبغي أن يقبل input رقم غير حقيقي، إما عن طريق منعك من الكتابة عليها أو عن طريق عرض خطأ في التحقق من صحة HTML5 (اعتمادا على متصفحك). 1. إذا قمت بإدخال أرقام خارج نطاق حقل إدخال الرقم، التي تم تعريفها بواسطة سمات `min` و `max`، سترى خطأ HTML5 validation error 1. بالنسبة لحقول الاسم والبريد الإلكتروني وإدخال الأرقام ، يمكنك رؤية عناصر `label` المقابلة في النموذج، التي تصف الغرض من كل حقل بالـ id's التالية: `id="name-label"` و `id="email-label"` و `id="number-label"` 1. بالنسبة لحقول الاسم والبريد الإلكتروني والرقم، يمكنك أن ترى الـ placeholder text الذي يعطي وصفا أو تعليمات لكل حقل diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md index 9e450b924b7645..ef2f241128c699 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613297a923965e0703b64796.md @@ -1,6 +1,6 @@ --- id: 613297a923965e0703b64796 -title: الخطوة الثانية +title: الخطوة 2 challengeType: 0 dashedName: step-2 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md index 8733579a2d404a..f7f79efd9f24f3 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61329b210dac0b08047fd6ab.md @@ -1,6 +1,6 @@ --- id: 61329b210dac0b08047fd6ab -title: الخطوة ٣ +title: الخطوة 3 challengeType: 0 dashedName: step-3 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md index 6c0554d882dbcd..236756f1181254 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133acc353338c0bba9cb553.md @@ -1,6 +1,6 @@ --- id: 6133acc353338c0bba9cb553 -title: الخطوة ٥ +title: الخطوة 5 challengeType: 0 dashedName: step-5 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md index 142626b527bafd..2ef7947512dc97 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6133d11ef548f51f876149e3.md @@ -1,6 +1,6 @@ --- id: 6133d11ef548f51f876149e3 -title: الخطوة ٦ +title: الخطوة 6 challengeType: 0 dashedName: step-6 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md index 96149bec6727fb..53861ecc849232 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e2546d0594208229ada50.md @@ -1,6 +1,6 @@ --- id: 613e2546d0594208229ada50 -title: الخطوة ٧ +title: الخطوة 7 challengeType: 0 dashedName: step-7 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md index e619ec59befc7c..1d6c7b5301ab63 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/613e275749ebd008e74bb62e.md @@ -1,6 +1,6 @@ --- id: 613e275749ebd008e74bb62e -title: الخطوة ٨ +title: الخطوة 8 challengeType: 0 dashedName: step-8 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md index 1756bf4e399122..903a9554405fad 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140827cff96e906bd38fc2b.md @@ -1,6 +1,6 @@ --- id: 6140827cff96e906bd38fc2b -title: الخطوة ٩ +title: الخطوة 9 challengeType: 0 dashedName: step-9 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md index 5b70a2fc6efb04..2ceaa8c40cbcf7 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6140883f74224508174794c0.md @@ -1,6 +1,6 @@ --- id: 6140883f74224508174794c0 -title: الخطوة ١٠ +title: الخطوة 10 challengeType: 0 dashedName: step-10 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md index 12e71fb4efb2b2..34b6634147e1cf 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408e4ae3e35d08feb260eb.md @@ -1,6 +1,6 @@ --- id: 61408e4ae3e35d08feb260eb -title: الخطوة ١١ +title: الخطوة 11 challengeType: 0 dashedName: step-11 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md index 874a5ba78efc96..6925c6827266fc 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61408f155e798909b6908712.md @@ -1,6 +1,6 @@ --- id: 61408f155e798909b6908712 -title: الخطوة ١٢ +title: الخطوة 12 challengeType: 0 dashedName: step-12 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md index 73854a5a328265..c1dc11d1481b2b 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614090d5a22b6f0a5a6b464c.md @@ -1,6 +1,6 @@ --- id: 614090d5a22b6f0a5a6b464c -title: الخطوة ١٣ +title: الخطوة 13 challengeType: 0 dashedName: step-13 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md index dc9d279f93a3ac..9a3b8519bf0d93 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fabd6f75610664e908fd.md @@ -1,6 +1,6 @@ --- id: 6141fabd6f75610664e908fd -title: الخطوة ١٤ +title: الخطوة 14 challengeType: 0 dashedName: step-14 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md index 8934c5566756e1..f2fc524bf70116 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6141fed65b61320743da5894.md @@ -1,6 +1,6 @@ --- id: 6141fed65b61320743da5894 -title: خطوة ١٥ +title: الخطوة 15 challengeType: 0 dashedName: step-15 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md index 5d973a8a5a9a97..14a22bb7136df7 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md @@ -1,6 +1,6 @@ --- id: 614202874ca576084fca625f -title: الخطوة ١٦ +title: الخطوة 16 challengeType: 0 dashedName: step-16 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md index 386b4dd83d19a0..38bca467f6f5d8 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614206033d366c090ca7dd42.md @@ -1,6 +1,6 @@ --- id: 614206033d366c090ca7dd42 -title: الخطوة ١٧ +title: الخطوة 17 challengeType: 0 dashedName: step-17 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md index ef109b3ec5fbc4..b8d73ab85d0f24 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/61435e3c0679a306c20f1acc.md @@ -1,6 +1,6 @@ --- id: 61435e3c0679a306c20f1acc -title: الخطوة ١٨ +title: الخطوة 18 challengeType: 0 dashedName: step-18 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md index 3fc12168741641..116f3e59fa93fe 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143610161323a081b249c19.md @@ -1,6 +1,6 @@ --- id: 6143610161323a081b249c19 -title: الخطوة ١٩ +title: الخطوة 19 challengeType: 0 dashedName: step-19 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md index 7c7811ac594c99..e142dd6f683f04 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143639d5eddc7094161648c.md @@ -1,6 +1,6 @@ --- id: 6143639d5eddc7094161648c -title: الخطوة ٢٠ +title: الخطوة 20 challengeType: 0 dashedName: step-20 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md index 479da772cbf455..1e1d4428b53d15 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143908b6aafb00a659ca189.md @@ -1,6 +1,6 @@ --- id: 6143908b6aafb00a659ca189 -title: الخطوة ٢١ +title: الخطوة 21 challengeType: 0 dashedName: step-21 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md index 660e00ac2183f4..4c76d78f016eec 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143920c8eafb00b735746ce.md @@ -1,6 +1,6 @@ --- id: 6143920c8eafb00b735746ce -title: الخطوة ٢٢ +title: الخطوة 22 challengeType: 0 dashedName: step-22 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md index b35e4d4bbf8f3f..12bfdd2c0a25e5 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143931a113bb80c45546287.md @@ -1,6 +1,6 @@ --- id: 6143931a113bb80c45546287 -title: الخطوة ٢٣ +title: الخطوة 23 challengeType: 0 dashedName: step-23 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md index 8ae3e5c361bebc..45d20ecf1469a1 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614394fb41985e0d2012a93e.md @@ -1,6 +1,6 @@ --- id: 614394fb41985e0d2012a93e -title: الخطوة ٢٤ +title: الخطوة 24 challengeType: 0 dashedName: step-24 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md index 45ec5b15c3b97b..a2a4c1e4e85e02 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143956ed76ed60e012faa51.md @@ -1,6 +1,6 @@ --- id: 6143956ed76ed60e012faa51 -title: خطوة ٢٥ +title: الخطوة 25 challengeType: 0 dashedName: step-25 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md index e63aedd46feefd..a70615ad6e990b 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614396f7ae83f20ea6f9f4b3.md @@ -1,6 +1,6 @@ --- id: 614396f7ae83f20ea6f9f4b3 -title: الخطوة ٢٦ +title: الخطوة 26 challengeType: 0 dashedName: step-26 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md index f8eb195500284f..48dbc8a3638cb2 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6143cb26f7edff2dc28f7da5.md @@ -1,6 +1,6 @@ --- id: 6143cb26f7edff2dc28f7da5 -title: خطوة ٢٧ +title: الخطوة 27 challengeType: 0 dashedName: step-27 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md index f798c25ea85669..a93fef3f29c8f5 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144e818fd5ea704fe56081d.md @@ -1,6 +1,6 @@ --- id: 6144e818fd5ea704fe56081d -title: الخطوة ٢٨ +title: الخطوة 28 challengeType: 0 dashedName: step-28 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md index 3562e1ed1d63ca..2f7ad2b3029f1a 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6144f8dc6849e405dd8bb829.md @@ -1,6 +1,6 @@ --- id: 6144f8dc6849e405dd8bb829 -title: الخطوة ٢٩ +title: الخطوة 29 challengeType: 0 dashedName: step-29 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md index 45f7601bff6034..a5a8afa923b344 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145e6eeaa66c605eb087fe9.md @@ -1,6 +1,6 @@ --- id: 6145e6eeaa66c605eb087fe9 -title: الخطوة ٣٠ +title: الخطوة 30 challengeType: 0 dashedName: step-30 --- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md index 4eb04ace0442e5..6efdb63b87e498 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f685797bd30df9784e8c.md @@ -35,10 +35,10 @@ assert.exists(document.querySelector('section:last-of-type + button') || documen assert.exists(document.querySelector('button[type="submit"]') || document.querySelector('form > input[type="submit"]')); ``` -يجب أن يعرض submit النص `Submit`. +يجب أن يعرض زر الإرسال (submit) نص `Send`. ```js -assert.equal(document.querySelector('button[type="submit"]')?.textContent ?? document.querySelector('input[type="submit"]')?.value, 'Submit'); +assert.equal(document.querySelector('button[type="submit"]')?.textContent ?? document.querySelector('input[type="submit"]')?.value, 'Send'); ``` # --seed-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md index b08fdc8ff30228..7e212d75f5a054 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f829ac6a920ebf5797d7.md @@ -138,7 +138,7 @@ assert.exists(document.querySelector('footer > address'));
    - + --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md index 3cdcf08901d47f..a241fb4217f5d1 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145f8f8bcd4370f6509078e.md @@ -137,7 +137,7 @@ assert.equal(document.querySelector('address')?.innerText, 'freeCodeCamp\nSan Fr - + --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md index 54a057025e3a5d..df2e6c0be50cc5 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fb5018cb5b100cb2a88c.md @@ -145,7 +145,7 @@ assert.equal(document.querySelector('address')?.innerHTML?.match(/freeCodeCamp/g - + --fcc-editable-region-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md index 64afb451a1c81d..a5fe55ac2ec2af 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6145fc3707fc3310c277f5c8.md @@ -170,7 +170,7 @@ assert.equal(display, 'block'); - +