@omega.js/web 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +98 -0
- package/README.md +640 -0
- package/bin/omega +2 -0
- package/bin/omega-web +2 -0
- package/bin/omg +2 -0
- package/core/_includes/admin/sections/sidebar.json +100 -0
- package/core/_includes/admin/sections/topbar.json +11 -0
- package/core/_includes/backend/sections/sidebar.json +39 -0
- package/core/_includes/backend/sections/topbar.json +16 -0
- package/core/_includes/core/body.html +102 -0
- package/core/_includes/core/foot.html +536 -0
- package/core/_includes/core/head.html +423 -0
- package/core/_includes/core/pricing/price-per-unit.html +33 -0
- package/core/_includes/core/showcase/entry-body.html +94 -0
- package/core/_includes/core/showcase/index-body.html +43 -0
- package/core/_includes/core/showcase/nav.html +60 -0
- package/core/_includes/frontend/sections/footer.json +74 -0
- package/core/_includes/frontend/sections/nav.json +70 -0
- package/core/_includes/global/sections/account.json +31 -0
- package/core/_includes/modules/engagement/giscus.html +26 -0
- package/core/_layouts/blueprint/404.html +10 -0
- package/core/_layouts/blueprint/about.html +10 -0
- package/core/_layouts/blueprint/account/index.html +11 -0
- package/core/_layouts/blueprint/admin/calendar/index.html +590 -0
- package/core/_layouts/blueprint/admin/dashboard/index.html +301 -0
- package/core/_layouts/blueprint/admin/firebase/index.html +214 -0
- package/core/_layouts/blueprint/admin/posts/editor.html +157 -0
- package/core/_layouts/blueprint/admin/posts/index.html +126 -0
- package/core/_layouts/blueprint/admin/stackblitz/index.html +30 -0
- package/core/_layouts/blueprint/admin/studio/index.html +85 -0
- package/core/_layouts/blueprint/admin/users/index.html +272 -0
- package/core/_layouts/blueprint/admin/users/new.html +82 -0
- package/core/_layouts/blueprint/admin/verts/index.html +204 -0
- package/core/_layouts/blueprint/alternatives/alternative.html +15 -0
- package/core/_layouts/blueprint/alternatives/index.html +10 -0
- package/core/_layouts/blueprint/app.html +10 -0
- package/core/_layouts/blueprint/auth/reset.html +19 -0
- package/core/_layouts/blueprint/auth/signin.html +19 -0
- package/core/_layouts/blueprint/auth/signup.html +19 -0
- package/core/_layouts/blueprint/auth/token.html +19 -0
- package/core/_layouts/blueprint/blog/categories/category.html +8 -0
- package/core/_layouts/blueprint/blog/categories/index.html +11 -0
- package/core/_layouts/blueprint/blog/index.html +10 -0
- package/core/_layouts/blueprint/blog/post.html +5 -0
- package/core/_layouts/blueprint/blog/tags/index.html +11 -0
- package/core/_layouts/blueprint/blog/tags/tag.html +8 -0
- package/core/_layouts/blueprint/careers.md +13 -0
- package/core/_layouts/blueprint/collection/category.html +9 -0
- package/core/_layouts/blueprint/collection/document.html +9 -0
- package/core/_layouts/blueprint/collection/index.html +9 -0
- package/core/_layouts/blueprint/connections/callback.html +11 -0
- package/core/_layouts/blueprint/contact.html +14 -0
- package/core/_layouts/blueprint/dashboard/index.html +10 -0
- package/core/_layouts/blueprint/download.html +20 -0
- package/core/_layouts/blueprint/extension/index.html +14 -0
- package/core/_layouts/blueprint/extension/installed.html +11 -0
- package/core/_layouts/blueprint/feedback.html +10 -0
- package/core/_layouts/blueprint/index.html +16 -0
- package/core/_layouts/blueprint/legal/cookies.md +57 -0
- package/core/_layouts/blueprint/legal/privacy.md +109 -0
- package/core/_layouts/blueprint/legal/terms.md +155 -0
- package/core/_layouts/blueprint/payment/checkout.html +15 -0
- package/core/_layouts/blueprint/payment/confirmation.html +14 -0
- package/core/_layouts/blueprint/portal/email-preferences.html +15 -0
- package/core/_layouts/blueprint/pricing.html +20 -0
- package/core/_layouts/blueprint/status.html +10 -0
- package/core/_layouts/blueprint/team/index.html +10 -0
- package/core/_layouts/blueprint/team/member.html +5 -0
- package/core/_layouts/blueprint/updates/index.html +10 -0
- package/core/_layouts/blueprint/updates/update.html +10 -0
- package/core/_layouts/core/root.html +45 -0
- package/core/_layouts/modules/utilities/redirect.html +129 -0
- package/core/css/_studio.scss +237 -0
- package/core/css/components/_index.scss +146 -0
- package/core/css/core/_.scss +0 -0
- package/core/css/core/_alert.scss +87 -0
- package/core/css/core/_animations.scss +343 -0
- package/core/css/core/_bindings.scss +116 -0
- package/core/css/core/_blog-search.scss +57 -0
- package/core/css/core/_chatsy.scss +61 -0
- package/core/css/core/_consent.scss +424 -0
- package/core/css/core/_custom-font-awesome.scss +146 -0
- package/core/css/core/_exit-popup.scss +42 -0
- package/core/css/core/_generated-badge.scss +33 -0
- package/core/css/core/_initialize.scss +29 -0
- package/core/css/core/_lazy-loading.scss +104 -0
- package/core/css/core/_social-sharing.scss +41 -0
- package/core/css/core/_tones.scss +32 -0
- package/core/css/core/_utilities.scss +157 -0
- package/core/css/main.scss +54 -0
- package/core/css/motion/_index.scss +368 -0
- package/core/css/pages/404/index.scss +0 -0
- package/core/css/pages/admin/calendar/index.scss +692 -0
- package/core/css/pages/admin/firebase/index.scss +33 -0
- package/core/css/pages/admin/index.scss +9 -0
- package/core/css/pages/admin/users/index.scss +9 -0
- package/core/css/pages/admin/verts/index.scss +9 -0
- package/core/css/pages/alternatives/[alternative]/index.scss +0 -0
- package/core/css/pages/blog/[slug].scss +55 -0
- package/core/css/pages/dashboard/account/index.scss +242 -0
- package/core/css/pages/download/index.scss +480 -0
- package/core/css/pages/extension/installed/index.scss +317 -0
- package/core/css/pages/feedback/index.scss +31 -0
- package/core/css/pages/payment/confirmation/index.scss +14 -0
- package/core/css/pages/pricing/index.scss +0 -0
- package/core/css/pages/status/index.scss +162 -0
- package/core/css/pages/test/libraries/layers/index.scss +28 -0
- package/core/css/pages/updates/[update].scss +46 -0
- package/core/css/pages/updates/index.scss +13 -0
- package/core/css/shell/_index.scss +207 -0
- package/core/css/tokens/_index.scss +166 -0
- package/core/icons/flags/ar.svg +1 -0
- package/core/icons/flags/bd.svg +1 -0
- package/core/icons/flags/ca.svg +1 -0
- package/core/icons/flags/ch.svg +1 -0
- package/core/icons/flags/cn.svg +1 -0
- package/core/icons/flags/co.svg +1 -0
- package/core/icons/flags/cw.svg +1 -0
- package/core/icons/flags/cz.svg +1 -0
- package/core/icons/flags/de.svg +1 -0
- package/core/icons/flags/dk.svg +1 -0
- package/core/icons/flags/eg.svg +1 -0
- package/core/icons/flags/es.svg +1 -0
- package/core/icons/flags/fi.svg +1 -0
- package/core/icons/flags/fr.svg +1 -0
- package/core/icons/flags/gb.svg +1 -0
- package/core/icons/flags/gq.svg +1 -0
- package/core/icons/flags/gr.svg +1 -0
- package/core/icons/flags/gt.svg +1 -0
- package/core/icons/flags/hn.svg +1 -0
- package/core/icons/flags/id.svg +1 -0
- package/core/icons/flags/ie.svg +1 -0
- package/core/icons/flags/in.svg +1 -0
- package/core/icons/flags/ir.svg +1 -0
- package/core/icons/flags/it.svg +1 -0
- package/core/icons/flags/jp.svg +1 -0
- package/core/icons/flags/kp.svg +1 -0
- package/core/icons/flags/kr.svg +1 -0
- package/core/icons/flags/ly.svg +1 -0
- package/core/icons/flags/ma.svg +1 -0
- package/core/icons/flags/mu.svg +1 -0
- package/core/icons/flags/mx.svg +1 -0
- package/core/icons/flags/ng.svg +1 -0
- package/core/icons/flags/pa.svg +1 -0
- package/core/icons/flags/ph.svg +1 -0
- package/core/icons/flags/pk.svg +1 -0
- package/core/icons/flags/pt.svg +1 -0
- package/core/icons/flags/ru.svg +1 -0
- package/core/icons/flags/sa.svg +1 -0
- package/core/icons/flags/sd.svg +1 -0
- package/core/icons/flags/se.svg +1 -0
- package/core/icons/flags/th.svg +1 -0
- package/core/icons/flags/tm.svg +1 -0
- package/core/icons/flags/tr.svg +1 -0
- package/core/icons/flags/us.svg +1 -0
- package/core/icons/flags/uy.svg +1 -0
- package/core/icons/flags/vn.svg +1 -0
- package/core/icons/flags/za.svg +1 -0
- package/core/images/exit-popup/subscriber-1.jpg +0 -0
- package/core/images/exit-popup/subscriber-2.jpg +0 -0
- package/core/images/exit-popup/subscriber-3.jpg +0 -0
- package/core/images/exit-popup/subscriber-4.jpg +0 -0
- package/core/images/placeholder/photo-1.jpg +0 -0
- package/core/images/placeholder/photo-2.jpg +0 -0
- package/core/images/placeholder/photo-3.jpg +0 -0
- package/core/js/core/analytics-loader.js +253 -0
- package/core/js/core/app-shell.js +136 -0
- package/core/js/core/appearance.js +195 -0
- package/core/js/core/auth.js +457 -0
- package/core/js/core/complete.js +72 -0
- package/core/js/core/consent.js +384 -0
- package/core/js/core/dev-icon-audit.js +63 -0
- package/core/js/core/dev-palette.js +670 -0
- package/core/js/core/dev-sections.js +53 -0
- package/core/js/core/exit-popup.js +276 -0
- package/core/js/core/initialize.js +8 -0
- package/core/js/core/language-switcher.js +167 -0
- package/core/js/core/lazy-loading.js +479 -0
- package/core/js/core/motion.js +28 -0
- package/core/js/core/query-strings.js +146 -0
- package/core/js/core/service-worker.js +28 -0
- package/core/js/core/social-sharing.js +293 -0
- package/core/js/first-paint.js +35 -0
- package/core/js/layouts/modules/utilities/redirect.js +122 -0
- package/core/js/libs/admin-helpers.js +62 -0
- package/core/js/libs/alert-dismiss.js +35 -0
- package/core/js/libs/analytics.js +368 -0
- package/core/js/libs/auth/email.js +144 -0
- package/core/js/libs/auth/errors.js +119 -0
- package/core/js/libs/auth/forms.js +206 -0
- package/core/js/libs/auth/index.js +181 -0
- package/core/js/libs/auth/oauth.js +394 -0
- package/core/js/libs/auth/orphan.js +110 -0
- package/core/js/libs/auth/password-toggle.js +44 -0
- package/core/js/libs/auth/session-params.js +266 -0
- package/core/js/libs/auth/tracking.js +41 -0
- package/core/js/libs/charts.js +516 -0
- package/core/js/libs/consent-region.js +127 -0
- package/core/js/libs/dev.js +150 -0
- package/core/js/libs/graph.js +201 -0
- package/core/js/libs/initialize-tooltips.js +31 -0
- package/core/js/libs/logger.js +38 -0
- package/core/js/libs/omega-copy.js +89 -0
- package/core/js/libs/path-prefix.js +44 -0
- package/core/js/libs/payment-config.js +76 -0
- package/core/js/libs/recaptcha.js +94 -0
- package/core/js/libs/sale-name.js +295 -0
- package/core/js/libs/showcase-frames.js +37 -0
- package/core/js/libs/srcset.js +69 -0
- package/core/js/libs/tracking-consent.js +161 -0
- package/core/js/main.js +144 -0
- package/core/js/pages/404/index.js +57 -0
- package/core/js/pages/admin/calendar/calendar-core.js +701 -0
- package/core/js/pages/admin/calendar/calendar-events.js +853 -0
- package/core/js/pages/admin/calendar/calendar-renderer.js +807 -0
- package/core/js/pages/admin/calendar/campaign-preview.js +105 -0
- package/core/js/pages/admin/calendar/index.js +40 -0
- package/core/js/pages/admin/firebase/index.js +727 -0
- package/core/js/pages/admin/index.js +531 -0
- package/core/js/pages/admin/posts/editor/index.js +230 -0
- package/core/js/pages/admin/posts/index.js +237 -0
- package/core/js/pages/admin/studio/index.js +538 -0
- package/core/js/pages/admin/users/index.js +669 -0
- package/core/js/pages/admin/users/new/index.js +65 -0
- package/core/js/pages/admin/verts/index.js +407 -0
- package/core/js/pages/alternatives/[alternative]/index.js +17 -0
- package/core/js/pages/app/index.js +135 -0
- package/core/js/pages/blog/[slug].js +132 -0
- package/core/js/pages/blog/_search.mjs +108 -0
- package/core/js/pages/blog/index.js +193 -0
- package/core/js/pages/blog/page/[num]/index.js +7 -0
- package/core/js/pages/connections/callback/index.js +148 -0
- package/core/js/pages/contact/index.js +170 -0
- package/core/js/pages/cookies.js +2 -0
- package/core/js/pages/dashboard/account/index.js +366 -0
- package/core/js/pages/dashboard/account/modules/orders.js +82 -0
- package/core/js/pages/dashboard/account/sections/api-keys.js +149 -0
- package/core/js/pages/dashboard/account/sections/billing.js +1667 -0
- package/core/js/pages/dashboard/account/sections/connections.js +333 -0
- package/core/js/pages/dashboard/account/sections/data-request.js +225 -0
- package/core/js/pages/dashboard/account/sections/delete.js +80 -0
- package/core/js/pages/dashboard/account/sections/notifications.js +167 -0
- package/core/js/pages/dashboard/account/sections/orders.js +151 -0
- package/core/js/pages/dashboard/account/sections/profile.js +200 -0
- package/core/js/pages/dashboard/account/sections/referrals.js +217 -0
- package/core/js/pages/dashboard/account/sections/refund.js +253 -0
- package/core/js/pages/dashboard/account/sections/security.js +726 -0
- package/core/js/pages/dashboard/account/sections/team.js +247 -0
- package/core/js/pages/download/index.js +418 -0
- package/core/js/pages/extension/index.js +164 -0
- package/core/js/pages/extension/installed/index.js +135 -0
- package/core/js/pages/feedback/index.js +193 -0
- package/core/js/pages/legal/_document.js +91 -0
- package/core/js/pages/payment/checkout/index.js +420 -0
- package/core/js/pages/payment/checkout/modules/api.js +139 -0
- package/core/js/pages/payment/checkout/modules/dev-section.js +175 -0
- package/core/js/pages/payment/checkout/modules/discount.js +69 -0
- package/core/js/pages/payment/checkout/modules/pricing.js +73 -0
- package/core/js/pages/payment/checkout/modules/state.js +339 -0
- package/core/js/pages/payment/checkout/modules/tracking.js +54 -0
- package/core/js/pages/payment/confirmation/index.js +91 -0
- package/core/js/pages/payment/confirmation/modules/celebration.js +45 -0
- package/core/js/pages/payment/confirmation/modules/state.js +112 -0
- package/core/js/pages/payment/confirmation/modules/tracking.js +133 -0
- package/core/js/pages/payment/confirmation/modules/verify.js +142 -0
- package/core/js/pages/portal/email-preferences/index.js +183 -0
- package/core/js/pages/pricing/index.js +425 -0
- package/core/js/pages/privacy.js +2 -0
- package/core/js/pages/reset/index.js +12 -0
- package/core/js/pages/signin/index.js +22 -0
- package/core/js/pages/signup/index.js +23 -0
- package/core/js/pages/status/index.js +687 -0
- package/core/js/pages/terms.js +2 -0
- package/core/js/pages/test/components/[category]/[name]/index.js +26 -0
- package/core/js/pages/test/libraries/appearance/index.js +220 -0
- package/core/js/pages/test/libraries/form-manager/index.js +328 -0
- package/core/js/pages/test/libraries/layers/index.js +16 -0
- package/core/js/pages/test/libraries/verts/index.js +68 -0
- package/core/js/pages/test/sections/[category]/[name]/index.js +28 -0
- package/core/js/pages/test/styleguide/index.js +35 -0
- package/core/js/pages/token/index.js +203 -0
- package/core/logos/brandmarks/original/apple-app-store.svg +1 -0
- package/core/logos/brandmarks/original/apple.svg +6 -0
- package/core/logos/brandmarks/original/bitbucket.svg +14 -0
- package/core/logos/brandmarks/original/bitcoin.svg +1 -0
- package/core/logos/brandmarks/original/bluesky.svg +7 -0
- package/core/logos/brandmarks/original/bootstrap.svg +43 -0
- package/core/logos/brandmarks/original/brave.svg +1 -0
- package/core/logos/brandmarks/original/chrome.svg +1 -0
- package/core/logos/brandmarks/original/discord.svg +1 -0
- package/core/logos/brandmarks/original/dropbox.svg +10 -0
- package/core/logos/brandmarks/original/edge.svg +1 -0
- package/core/logos/brandmarks/original/facebook-f.svg +1 -0
- package/core/logos/brandmarks/original/facebook.svg +8 -0
- package/core/logos/brandmarks/original/figma.svg +10 -0
- package/core/logos/brandmarks/original/firefox.svg +1 -0
- package/core/logos/brandmarks/original/github.svg +6 -0
- package/core/logos/brandmarks/original/gitlab.svg +17 -0
- package/core/logos/brandmarks/original/google-a-s.svg +1 -0
- package/core/logos/brandmarks/original/google-chrome-webstore.svg +49 -0
- package/core/logos/brandmarks/original/google-play-store.svg +1 -0
- package/core/logos/brandmarks/original/google-web-search.svg +1 -0
- package/core/logos/brandmarks/original/google.svg +1 -0
- package/core/logos/brandmarks/original/gulp.svg +4 -0
- package/core/logos/brandmarks/original/html-5.svg +1 -0
- package/core/logos/brandmarks/original/instagram.svg +1 -0
- package/core/logos/brandmarks/original/javascript.svg +1 -0
- package/core/logos/brandmarks/original/jira.svg +18 -0
- package/core/logos/brandmarks/original/kick.svg +7 -0
- package/core/logos/brandmarks/original/linkedin.svg +1 -0
- package/core/logos/brandmarks/original/linux.svg +28 -0
- package/core/logos/brandmarks/original/messenger.svg +16 -0
- package/core/logos/brandmarks/original/microsoft.svg +1 -0
- package/core/logos/brandmarks/original/npm.svg +8 -0
- package/core/logos/brandmarks/original/opera.svg +1 -0
- package/core/logos/brandmarks/original/patreon.svg +6 -0
- package/core/logos/brandmarks/original/pinterest.svg +6 -0
- package/core/logos/brandmarks/original/reddit.svg +1 -0
- package/core/logos/brandmarks/original/safari.svg +31 -0
- package/core/logos/brandmarks/original/sass.svg +3 -0
- package/core/logos/brandmarks/original/signal.svg +6 -0
- package/core/logos/brandmarks/original/skype.svg +47 -0
- package/core/logos/brandmarks/original/slack.svg +33 -0
- package/core/logos/brandmarks/original/soundcloud.svg +1 -0
- package/core/logos/brandmarks/original/spotify.svg +5 -0
- package/core/logos/brandmarks/original/steam.svg +6 -0
- package/core/logos/brandmarks/original/telegram.svg +14 -0
- package/core/logos/brandmarks/original/tiktok.svg +1 -0
- package/core/logos/brandmarks/original/trello.svg +16 -0
- package/core/logos/brandmarks/original/tumblr.svg +1 -0
- package/core/logos/brandmarks/original/twitch.svg +6 -0
- package/core/logos/brandmarks/original/twitter.svg +6 -0
- package/core/logos/brandmarks/original/unity.svg +6 -0
- package/core/logos/brandmarks/original/x.svg +7 -0
- package/core/logos/brandmarks/original/yahoo-y.svg +1 -0
- package/core/logos/brandmarks/original/youtube-square.svg +1 -0
- package/core/logos/brandmarks/original/youtube.svg +1 -0
- package/core/logos/combomarks/dark/airbnb.svg +30 -0
- package/core/logos/combomarks/dark/slack.svg +38 -0
- package/core/logos/combomarks/dark/spotify.svg +35 -0
- package/core/logos/combomarks/dark/twilio.svg +26 -0
- package/core/logos/combomarks/dark/weebly.svg +35 -0
- package/core/logos/combomarks/gray/airbnb.svg +33 -0
- package/core/logos/combomarks/gray/alphabet.svg +23 -0
- package/core/logos/combomarks/gray/amazon.svg +38 -0
- package/core/logos/combomarks/gray/boring-company.svg +91 -0
- package/core/logos/combomarks/gray/burberry.svg +239 -0
- package/core/logos/combomarks/gray/embark.svg +21 -0
- package/core/logos/combomarks/gray/fitbit.svg +61 -0
- package/core/logos/combomarks/gray/fred-perry.svg +94 -0
- package/core/logos/combomarks/gray/google.svg +27 -0
- package/core/logos/combomarks/gray/hollister.svg +34 -0
- package/core/logos/combomarks/gray/hubspot.svg +27 -0
- package/core/logos/combomarks/gray/kaplan.svg +33 -0
- package/core/logos/combomarks/gray/lenovo.svg +27 -0
- package/core/logos/combomarks/gray/levis.svg +25 -0
- package/core/logos/combomarks/gray/mapbox.svg +37 -0
- package/core/logos/combomarks/gray/netflix.svg +15 -0
- package/core/logos/combomarks/gray/new-balance.svg +32 -0
- package/core/logos/combomarks/gray/nike.svg +17 -0
- package/core/logos/combomarks/gray/paypal.svg +41 -0
- package/core/logos/combomarks/gray/puma.svg +82 -0
- package/core/logos/combomarks/gray/samsung.svg +26 -0
- package/core/logos/combomarks/gray/shopify.svg +36 -0
- package/core/logos/combomarks/gray/slack.svg +42 -0
- package/core/logos/combomarks/gray/spotify.svg +38 -0
- package/core/logos/combomarks/gray/stripe.svg +24 -0
- package/core/logos/combomarks/gray/tnf.svg +30 -0
- package/core/logos/combomarks/gray/twilio.svg +29 -0
- package/core/logos/combomarks/gray/uber.svg +24 -0
- package/core/logos/combomarks/gray/weebly.svg +38 -0
- package/core/logos/combomarks/original/airbnb.svg +33 -0
- package/core/logos/combomarks/original/alphabet.svg +23 -0
- package/core/logos/combomarks/original/amazon.svg +38 -0
- package/core/logos/combomarks/original/asana.svg +8 -0
- package/core/logos/combomarks/original/boring-company.svg +91 -0
- package/core/logos/combomarks/original/discord.svg +6 -0
- package/core/logos/combomarks/original/embark.svg +24 -0
- package/core/logos/combomarks/original/fitbit.svg +60 -0
- package/core/logos/combomarks/original/github.svg +6 -0
- package/core/logos/combomarks/original/gitlab.svg +20 -0
- package/core/logos/combomarks/original/google.svg +28 -0
- package/core/logos/combomarks/original/hubspot.svg +29 -0
- package/core/logos/combomarks/original/instagram.svg +7 -0
- package/core/logos/combomarks/original/kickstarter.svg +6 -0
- package/core/logos/combomarks/original/lenovo.svg +24 -0
- package/core/logos/combomarks/original/linkedin.svg +6 -0
- package/core/logos/combomarks/original/mapbox.svg +39 -0
- package/core/logos/combomarks/original/mastodon.svg +7 -0
- package/core/logos/combomarks/original/medium.svg +6 -0
- package/core/logos/combomarks/original/meta.svg +22 -0
- package/core/logos/combomarks/original/microsoft.svg +13 -0
- package/core/logos/combomarks/original/monday.svg +12 -0
- package/core/logos/combomarks/original/netflix.svg +15 -0
- package/core/logos/combomarks/original/notion.svg +9 -0
- package/core/logos/combomarks/original/paypal.svg +41 -0
- package/core/logos/combomarks/original/reddit.svg +13 -0
- package/core/logos/combomarks/original/samsung.svg +25 -0
- package/core/logos/combomarks/original/shopify.svg +35 -0
- package/core/logos/combomarks/original/slack.svg +47 -0
- package/core/logos/combomarks/original/spotify.svg +37 -0
- package/core/logos/combomarks/original/stackoverflow.svg +28 -0
- package/core/logos/combomarks/original/stripe.svg +24 -0
- package/core/logos/combomarks/original/tiktok.svg +12 -0
- package/core/logos/combomarks/original/tumblr.svg +6 -0
- package/core/logos/combomarks/original/uber.svg +24 -0
- package/core/logos/combomarks/original/weebly.svg +34 -0
- package/core/logos/combomarks/original/whatsapp.svg +20 -0
- package/core/logos/combomarks/original/youtube.svg +10 -0
- package/core/logos/combomarks/original/zoom.svg +7 -0
- package/core/logos/combomarks/white/airbnb.svg +33 -0
- package/core/logos/combomarks/white/alphabet.svg +23 -0
- package/core/logos/combomarks/white/amazon.svg +38 -0
- package/core/logos/combomarks/white/boring-company.svg +91 -0
- package/core/logos/combomarks/white/embark.svg +21 -0
- package/core/logos/combomarks/white/fitbit.svg +61 -0
- package/core/logos/combomarks/white/google.svg +27 -0
- package/core/logos/combomarks/white/hubspot.svg +27 -0
- package/core/logos/combomarks/white/kaplan.svg +33 -0
- package/core/logos/combomarks/white/lenovo.svg +27 -0
- package/core/logos/combomarks/white/mapbox.svg +37 -0
- package/core/logos/combomarks/white/netflix.svg +15 -0
- package/core/logos/combomarks/white/paypal.svg +40 -0
- package/core/logos/combomarks/white/samsung.svg +26 -0
- package/core/logos/combomarks/white/shopify.svg +36 -0
- package/core/logos/combomarks/white/slack.svg +42 -0
- package/core/logos/combomarks/white/spotify.svg +38 -0
- package/core/logos/combomarks/white/stripe.svg +24 -0
- package/core/logos/combomarks/white/twilio.svg +29 -0
- package/core/logos/combomarks/white/uber.svg +24 -0
- package/core/logos/combomarks/white/weebly.svg +38 -0
- package/defaults/pages/404.md +4 -0
- package/defaults/pages/about.md +4 -0
- package/defaults/pages/admin/calendar/index.html +4 -0
- package/defaults/pages/admin/firebase/index.html +4 -0
- package/defaults/pages/admin/index.md +4 -0
- package/defaults/pages/admin/posts/editor.html +4 -0
- package/defaults/pages/admin/posts/index.html +4 -0
- package/defaults/pages/admin/stackblitz/index.html +4 -0
- package/defaults/pages/admin/studio/index.html +4 -0
- package/defaults/pages/admin/users/index.html +4 -0
- package/defaults/pages/admin/users/new.html +4 -0
- package/defaults/pages/admin/verts/index.html +4 -0
- package/defaults/pages/ads-txt.html +11 -0
- package/defaults/pages/alternatives/index.md +4 -0
- package/defaults/pages/app.md +4 -0
- package/defaults/pages/auth/reset.md +4 -0
- package/defaults/pages/auth/signin.md +4 -0
- package/defaults/pages/auth/signup.md +4 -0
- package/defaults/pages/auth/token.md +4 -0
- package/defaults/pages/blog/categories/category.html +21 -0
- package/defaults/pages/blog/categories.md +4 -0
- package/defaults/pages/blog/index-json.html +27 -0
- package/defaults/pages/blog/tags/tag.html +21 -0
- package/defaults/pages/blog/tags.md +4 -0
- package/defaults/pages/blog.md +22 -0
- package/defaults/pages/careers.md +4 -0
- package/defaults/pages/connections/callback.md +4 -0
- package/defaults/pages/contact.md +4 -0
- package/defaults/pages/dashboard/account.md +4 -0
- package/defaults/pages/dashboard/index.md +12 -0
- package/defaults/pages/download.md +4 -0
- package/defaults/pages/extension/index.html +4 -0
- package/defaults/pages/extension/installed.html +4 -0
- package/defaults/pages/feedback.md +4 -0
- package/defaults/pages/feeds/posts-json.html +40 -0
- package/defaults/pages/feeds/posts-xml.html +38 -0
- package/defaults/pages/humans.html +25 -0
- package/defaults/pages/index.md +4 -0
- package/defaults/pages/legal/cookies.md +4 -0
- package/defaults/pages/legal/privacy.md +4 -0
- package/defaults/pages/legal/terms.md +4 -0
- package/defaults/pages/llms-txt.html +46 -0
- package/defaults/pages/opensearch.html +16 -0
- package/defaults/pages/pages-json.html +42 -0
- package/defaults/pages/payment/checkout.md +4 -0
- package/defaults/pages/payment/confirmation.md +4 -0
- package/defaults/pages/portal/email-preferences.md +4 -0
- package/defaults/pages/pricing.md +4 -0
- package/defaults/pages/redirects/account.md +12 -0
- package/defaults/pages/redirects/admin/dashboard.md +11 -0
- package/defaults/pages/redirects/auth/change-password.md +9 -0
- package/defaults/pages/redirects/auth/forgot.md +9 -0
- package/defaults/pages/redirects/auth/join.md +9 -0
- package/defaults/pages/redirects/auth/login.md +9 -0
- package/defaults/pages/redirects/auth/recover.md +9 -0
- package/defaults/pages/redirects/auth/register.md +9 -0
- package/defaults/pages/redirects/auth/reset-password.md +9 -0
- package/defaults/pages/redirects/billing/cancel.md +9 -0
- package/defaults/pages/redirects/billing/refund.md +9 -0
- package/defaults/pages/robots.html +36 -0
- package/defaults/pages/security-txt.html +11 -0
- package/defaults/pages/sitemap.html +37 -0
- package/defaults/pages/status.md +4 -0
- package/defaults/pages/team/index.md +4 -0
- package/defaults/pages/test/account/dashboard.html +16 -0
- package/defaults/pages/test/index.md +12 -0
- package/defaults/pages/test/libraries/appearance.html +268 -0
- package/defaults/pages/test/libraries/cover.html +50 -0
- package/defaults/pages/test/libraries/error.html +30 -0
- package/defaults/pages/test/libraries/firestore.html +202 -0
- package/defaults/pages/test/libraries/form-manager.html +374 -0
- package/defaults/pages/test/libraries/layers.html +52 -0
- package/defaults/pages/test/libraries/lazy-loading.html +450 -0
- package/defaults/pages/test/libraries/verts.html +149 -0
- package/defaults/pages/test/redirect/external.md +13 -0
- package/defaults/pages/test/redirect/internal.md +13 -0
- package/defaults/pages/test/styleguide/index.html +588 -0
- package/defaults/pages/test/translation/index.md +50 -0
- package/defaults/pages/updates/index.md +4 -0
- package/defaults/sample-posts/2026-01-12-welcome-to-the-blog.md +26 -0
- package/defaults/sample-posts/2026-02-03-a-field-guide-to-good-defaults.md +50 -0
- package/defaults/sample-posts/2026-02-24-shipping-week-notes.md +37 -0
- package/defaults/sample-posts/2026-03-17-the-case-for-one-config.md +36 -0
- package/defaults/sample-posts/2026-04-09-write-release-notes-people-read.md +34 -0
- package/defaults/sample-posts/2026-05-21-dark-mode-done-properly.md +38 -0
- package/defaults/sample-posts/2026-06-02-the-boring-deploy-is-the-good-deploy.md +30 -0
- package/defaults/sample-posts/2026-06-11-naming-things-a-survival-guide.md +30 -0
- package/defaults/sample-posts/2026-06-19-your-pricing-page-is-a-product.md +28 -0
- package/defaults/sample-posts/2026-06-30-email-is-an-api-with-feelings.md +28 -0
- package/defaults/sample-posts/2026-07-08-ship-the-docs-with-the-diff.md +30 -0
- package/defaults/sample-team/avery-quinn.md +22 -0
- package/defaults/sample-team/jordan-reyes.md +25 -0
- package/defaults/sample-team/riley-nakamura.md +22 -0
- package/defaults/sample-team/sam-okafor.md +22 -0
- package/defaults/sample-updates/v1.0.0.md +28 -0
- package/defaults/sample-updates/v1.1.0.md +27 -0
- package/defaults/sample-updates/v1.2.0.md +27 -0
- package/defaults/sample-updates/v1.3.0.md +28 -0
- package/defaults/showcase/components.html +62 -0
- package/defaults/showcase/entry.html +76 -0
- package/defaults/showcase/frame.html +62 -0
- package/defaults/showcase/index.html +59 -0
- package/dist/assets.js +1349 -0
- package/dist/brand-tokens.js +195 -0
- package/dist/build.js +192 -0
- package/dist/cachebreak-html.js +71 -0
- package/dist/cli-run.js +25 -0
- package/dist/cli.js +47 -0
- package/dist/collections.js +183 -0
- package/dist/commands/audit.js +470 -0
- package/dist/commands/build.js +197 -0
- package/dist/commands/clean.js +18 -0
- package/dist/commands/customize.js +125 -0
- package/dist/commands/deploy.js +441 -0
- package/dist/commands/dev.js +1067 -0
- package/dist/commands/install.js +31 -0
- package/dist/commands/lib/deploy-precheck.js +43 -0
- package/dist/commands/lib/ensure-target.js +115 -0
- package/dist/commands/migrate.js +86 -0
- package/dist/commands/purge.js +31 -0
- package/dist/commands/test.js +237 -0
- package/dist/commands/translate.js +57 -0
- package/dist/commands/update.js +22 -0
- package/dist/commands/version.js +11 -0
- package/dist/config-sections.js +245 -0
- package/dist/consumer-scan.js +118 -0
- package/dist/consumer.js +49 -0
- package/dist/customize.js +328 -0
- package/dist/decisions.js +153 -0
- package/dist/dist-audit.js +417 -0
- package/dist/dynamic-pages.js +357 -0
- package/dist/engine.js +1402 -0
- package/dist/firebase-auth-helpers.js +198 -0
- package/dist/font-metrics.js +420 -0
- package/dist/frontmatter-liquid.js +253 -0
- package/dist/github-secrets.js +80 -0
- package/dist/hero-animations.js +170 -0
- package/dist/imagemin.js +261 -0
- package/dist/index.js +41 -0
- package/dist/inline-icons.js +65 -0
- package/dist/language-flags.js +55 -0
- package/dist/layers.js +80 -0
- package/dist/layouts.js +44 -0
- package/dist/limit-collections.js +199 -0
- package/dist/link-resolver.js +303 -0
- package/dist/markdown-images.js +85 -0
- package/dist/merge.js +20 -0
- package/dist/migrate/codemod.js +172 -0
- package/dist/migrate/config-convert.js +448 -0
- package/dist/migrate/consumer-assets.js +130 -0
- package/dist/migrate/index.js +223 -0
- package/dist/migrate/lint.js +108 -0
- package/dist/migrate/rules.js +1929 -0
- package/dist/minify-html.js +148 -0
- package/dist/mode-helpers.js +96 -0
- package/dist/omega-bin.js +7 -0
- package/dist/overrides.js +190 -0
- package/dist/path-prefix.js +167 -0
- package/dist/paths.js +37 -0
- package/dist/pricing.js +301 -0
- package/dist/purge.js +95 -0
- package/dist/redirect-page.js +45 -0
- package/dist/sample-content.js +210 -0
- package/dist/scaffold.js +123 -0
- package/dist/sections.js +810 -0
- package/dist/service-worker.js +200 -0
- package/dist/social-pages.js +142 -0
- package/dist/srcset.js +67 -0
- package/dist/static-assets.js +154 -0
- package/dist/target-shortlinks.js +123 -0
- package/dist/theme-vocabulary.js +76 -0
- package/dist/translate/collect-text-nodes.js +93 -0
- package/dist/translate/default-routes.js +152 -0
- package/dist/translate/generate-defaults.js +297 -0
- package/dist/translate/index.js +568 -0
- package/dist/translate/packaged-defaults.js +127 -0
- package/dist/translate/sitemap.js +108 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/actions-secrets.js +145 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bare-requires.js +153 -0
- package/dist/vendor/devkit/bundle.js +292 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-precheck.js +54 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/env-watch.js +132 -0
- package/dist/vendor/devkit/framework-deps.js +46 -0
- package/dist/vendor/devkit/icons.js +178 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local-https.js +360 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/reads.js +274 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
- package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
- package/dist/vendor/devkit/target-secrets.js +165 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/translate/cache.js +84 -0
- package/dist/vendor/devkit/translate/engine.js +243 -0
- package/dist/vendor/devkit/translate/index.js +49 -0
- package/dist/vendor/devkit/translate/languages.js +134 -0
- package/dist/vendor/devkit/translate/providers.js +188 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/template-kit/data/language-flags.js +54 -0
- package/dist/vendor/template-kit/data/languages.js +195 -0
- package/dist/vendor/template-kit/data/social-urls.js +26 -0
- package/dist/vendor/template-kit/filters.js +227 -0
- package/dist/vendor/template-kit/index.js +28 -0
- package/dist/vendor/template-kit/jekyll-compat.js +268 -0
- package/dist/vendor/template-kit/register-liquid.js +0 -0
- package/dist/vendor/template-kit/tags/collections.js +191 -0
- package/dist/vendor/template-kit/tags/conditionals.js +101 -0
- package/dist/vendor/template-kit/tags/content.js +175 -0
- package/dist/vendor/template-kit/tags/index.js +33 -0
- package/dist/vendor/template-kit/tags/media.js +376 -0
- package/dist/vendor/template-kit/variable-resolver.js +163 -0
- package/docs/ads-system.md +109 -0
- package/docs/classy-v2/DIRECTION.md +92 -0
- package/docs/classy-v2/draft-1.html +1932 -0
- package/docs/classy-v2/draft-2.html +1956 -0
- package/docs/frontmatter.md +153 -0
- package/docs/index.md +254 -0
- package/docs/libs.md +298 -0
- package/docs/omega-sections-spec.md +159 -0
- package/docs/page-contract.md +112 -0
- package/docs/sections.md +845 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/template-kit.md +128 -0
- package/docs/test-framework.md +163 -0
- package/package.json +122 -0
- package/runtime/boot.js +149 -0
- package/runtime/icons.js +77 -0
- package/runtime/manager.js +36 -0
- package/scaffold/.github/workflows/build.yml +139 -0
- package/scaffold/.nvmrc +1 -0
- package/scaffold/AGENTS.md +55 -0
- package/scaffold/CLAUDE.md +1 -0
- package/scaffold/_.gitattributes +4 -0
- package/scaffold/_.gitignore +27 -0
- package/scaffold/config/omega.json5 +20 -0
- package/scaffold/src/assets/css/pages/.gitkeep +0 -0
- package/scaffold/src/assets/images/.gitkeep +0 -0
- package/scaffold/src/assets/js/pages/.gitkeep +0 -0
- package/scaffold/src/pages/.gitkeep +0 -0
- package/scaffold/src/pages/example.md.txt +94 -0
- package/scaffold/src/service-worker.js +16 -0
- package/sw/entry.js +19 -0
- package/sw/manager.js +281 -0
- package/themes/_template/README.md +115 -0
- package/themes/_template/_config.scss +60 -0
- package/themes/_template/_theme.js +14 -0
- package/themes/_template/_theme.scss +28 -0
- package/themes/_template/css/base/_root.scss +19 -0
- package/themes/_template/css/components/_components.scss +23 -0
- package/themes/base/README.md +5 -0
- package/themes/base/_components/data/org-chart/component.html +33 -0
- package/themes/base/_components/data/org-chart/component.json5 +33 -0
- package/themes/base/_components/data/org-chart/component.scss +183 -0
- package/themes/base/_components/heading/masthead/component.html +22 -0
- package/themes/base/_components/heading/masthead/component.json5 +30 -0
- package/themes/base/_components/heading/section-head/component.html +18 -0
- package/themes/base/_components/heading/section-head/component.json5 +27 -0
- package/themes/base/_components/pricing/features/component.html +29 -0
- package/themes/base/_components/pricing/features/component.json5 +30 -0
- package/themes/base/_hero/orbit/index.html +30 -0
- package/themes/base/_hero/orbit/script.js +33 -0
- package/themes/base/_hero/orbit/style.scss +133 -0
- package/themes/base/_includes/admin/sections/sidebar.html +3 -0
- package/themes/base/_includes/admin/sections/topbar.html +3 -0
- package/themes/base/_includes/backend/sections/sidebar.html +3 -0
- package/themes/base/_includes/backend/sections/topbar.html +3 -0
- package/themes/base/_includes/frontend/components/connection-card.html +49 -0
- package/themes/base/_includes/frontend/components/post-card.html +54 -0
- package/themes/base/_includes/frontend/sections/account-connections.html +42 -0
- package/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
- package/themes/base/_includes/frontend/sections/footer.html +154 -0
- package/themes/base/_includes/frontend/sections/nav.html +276 -0
- package/themes/base/_includes/global/sections/account.html +72 -0
- package/themes/base/_includes/global/sections/app-sidebar.html +248 -0
- package/themes/base/_includes/global/sections/app-topbar.html +228 -0
- package/themes/base/_includes/global/sections/page-header.html +99 -0
- package/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
- package/themes/base/_layouts/admin/core/minimal.html +23 -0
- package/themes/base/_layouts/backend/core/base.html +57 -0
- package/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
- package/themes/base/_layouts/backend/core/minimal.html +32 -0
- package/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
- package/themes/base/_layouts/frontend/core/base.html +31 -0
- package/themes/base/_layouts/frontend/core/cover.html +40 -0
- package/themes/base/_layouts/frontend/core/minimal.html +47 -0
- package/themes/base/_layouts/frontend/pages/404.html +54 -0
- package/themes/base/_layouts/frontend/pages/about.html +144 -0
- package/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
- package/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
- package/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
- package/themes/base/_layouts/frontend/pages/app.html +142 -0
- package/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
- package/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
- package/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
- package/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
- package/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
- package/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
- package/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
- package/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
- package/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
- package/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
- package/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
- package/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
- package/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
- package/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
- package/themes/base/_layouts/frontend/pages/contact.html +214 -0
- package/themes/base/_layouts/frontend/pages/download.html +793 -0
- package/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
- package/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
- package/themes/base/_layouts/frontend/pages/feedback.html +171 -0
- package/themes/base/_layouts/frontend/pages/index.html +66 -0
- package/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
- package/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
- package/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
- package/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
- package/themes/base/_layouts/frontend/pages/pricing.html +596 -0
- package/themes/base/_layouts/frontend/pages/status.html +361 -0
- package/themes/base/_layouts/frontend/pages/team/index.html +210 -0
- package/themes/base/_layouts/frontend/pages/team/member.html +125 -0
- package/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
- package/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
- package/themes/base/_sections/about/hero/section.html +68 -0
- package/themes/base/_sections/about/hero/section.json5 +58 -0
- package/themes/base/_sections/about/letter/section.html +60 -0
- package/themes/base/_sections/about/letter/section.json5 +56 -0
- package/themes/base/_sections/about/photo-band/section.html +24 -0
- package/themes/base/_sections/about/photo-band/section.json5 +23 -0
- package/themes/base/_sections/about/principles/section.html +17 -0
- package/themes/base/_sections/about/principles/section.json5 +34 -0
- package/themes/base/_sections/about/timeline/section.html +20 -0
- package/themes/base/_sections/about/timeline/section.json5 +34 -0
- package/themes/base/_sections/marketing/bento/section.html +91 -0
- package/themes/base/_sections/marketing/bento/section.json5 +152 -0
- package/themes/base/_sections/marketing/cta/section.html +44 -0
- package/themes/base/_sections/marketing/cta/section.json5 +47 -0
- package/themes/base/_sections/marketing/faq/section.html +52 -0
- package/themes/base/_sections/marketing/faq/section.json5 +68 -0
- package/themes/base/_sections/marketing/hero/section.html +349 -0
- package/themes/base/_sections/marketing/hero/section.json5 +335 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
- package/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
- package/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
- package/themes/base/_sections/marketing/product-demo/section.html +62 -0
- package/themes/base/_sections/marketing/product-demo/section.js +44 -0
- package/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
- package/themes/base/_sections/marketing/prose/section.html +22 -0
- package/themes/base/_sections/marketing/prose/section.json5 +41 -0
- package/themes/base/_sections/marketing/showcase/section.html +35 -0
- package/themes/base/_sections/marketing/showcase/section.json5 +52 -0
- package/themes/base/_sections/marketing/stats/section.html +32 -0
- package/themes/base/_sections/marketing/stats/section.json5 +44 -0
- package/themes/base/_sections/marketing/testimonials/section.html +54 -0
- package/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
- package/themes/base/_sections/marketing/trusted-by/section.html +30 -0
- package/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
- package/themes/base/_sections/verts/unit/section.html +7 -0
- package/themes/base/_sections/verts/unit/section.js +22 -0
- package/themes/base/_sections/verts/unit/section.json5 +24 -0
- package/themes/base/_sections/verts/unit/section.scss +24 -0
- package/themes/base/_theme.js +13 -0
- package/themes/base/_theme.scss +4 -0
- package/themes/bootstrap/_theme.js +16 -0
- package/themes/bootstrap/_theme.scss +11 -0
- package/themes/bootstrap/js/index.esm.js +19 -0
- package/themes/bootstrap/js/index.umd.js +34 -0
- package/themes/bootstrap/js/src/alert.js +87 -0
- package/themes/bootstrap/js/src/base-component.js +86 -0
- package/themes/bootstrap/js/src/button.js +72 -0
- package/themes/bootstrap/js/src/carousel.js +474 -0
- package/themes/bootstrap/js/src/collapse.js +297 -0
- package/themes/bootstrap/js/src/dom/data.js +55 -0
- package/themes/bootstrap/js/src/dom/event-handler.js +317 -0
- package/themes/bootstrap/js/src/dom/manipulator.js +71 -0
- package/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
- package/themes/bootstrap/js/src/dropdown.js +458 -0
- package/themes/bootstrap/js/src/modal.js +378 -0
- package/themes/bootstrap/js/src/offcanvas.js +282 -0
- package/themes/bootstrap/js/src/popover.js +97 -0
- package/themes/bootstrap/js/src/scrollspy.js +296 -0
- package/themes/bootstrap/js/src/tab.js +315 -0
- package/themes/bootstrap/js/src/toast.js +224 -0
- package/themes/bootstrap/js/src/tooltip.js +632 -0
- package/themes/bootstrap/js/src/util/backdrop.js +151 -0
- package/themes/bootstrap/js/src/util/component-functions.js +35 -0
- package/themes/bootstrap/js/src/util/config.js +65 -0
- package/themes/bootstrap/js/src/util/focustrap.js +115 -0
- package/themes/bootstrap/js/src/util/index.js +306 -0
- package/themes/bootstrap/js/src/util/sanitizer.js +117 -0
- package/themes/bootstrap/js/src/util/scrollbar.js +114 -0
- package/themes/bootstrap/js/src/util/swipe.js +146 -0
- package/themes/bootstrap/js/src/util/template-factory.js +160 -0
- package/themes/bootstrap/overrides/_accordion.scss +21 -0
- package/themes/bootstrap/overrides/_avatars.scss +51 -0
- package/themes/bootstrap/overrides/_blog-images.scss +45 -0
- package/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
- package/themes/bootstrap/overrides/_color-shades.scss +25 -0
- package/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
- package/themes/bootstrap/overrides/_index.scss +30 -0
- package/themes/bootstrap/overrides/_links.scss +26 -0
- package/themes/bootstrap/overrides/_soft-colors.scss +99 -0
- package/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
- package/themes/bootstrap/overrides/_spinners.scss +22 -0
- package/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
- package/themes/bootstrap/scss/_accordion.scss +153 -0
- package/themes/bootstrap/scss/_alert.scss +68 -0
- package/themes/bootstrap/scss/_badge.scss +38 -0
- package/themes/bootstrap/scss/_breadcrumb.scss +40 -0
- package/themes/bootstrap/scss/_button-group.scss +147 -0
- package/themes/bootstrap/scss/_buttons.scss +216 -0
- package/themes/bootstrap/scss/_card.scss +238 -0
- package/themes/bootstrap/scss/_carousel.scss +226 -0
- package/themes/bootstrap/scss/_close.scss +66 -0
- package/themes/bootstrap/scss/_containers.scss +41 -0
- package/themes/bootstrap/scss/_dropdown.scss +250 -0
- package/themes/bootstrap/scss/_forms.scss +9 -0
- package/themes/bootstrap/scss/_functions.scss +302 -0
- package/themes/bootstrap/scss/_grid.scss +39 -0
- package/themes/bootstrap/scss/_helpers.scss +12 -0
- package/themes/bootstrap/scss/_images.scss +42 -0
- package/themes/bootstrap/scss/_list-group.scss +199 -0
- package/themes/bootstrap/scss/_maps.scss +174 -0
- package/themes/bootstrap/scss/_mixins.scss +42 -0
- package/themes/bootstrap/scss/_modal.scss +240 -0
- package/themes/bootstrap/scss/_nav.scss +197 -0
- package/themes/bootstrap/scss/_navbar.scss +289 -0
- package/themes/bootstrap/scss/_offcanvas.scss +147 -0
- package/themes/bootstrap/scss/_pagination.scss +109 -0
- package/themes/bootstrap/scss/_placeholders.scss +51 -0
- package/themes/bootstrap/scss/_popover.scss +196 -0
- package/themes/bootstrap/scss/_progress.scss +68 -0
- package/themes/bootstrap/scss/_reboot.scss +611 -0
- package/themes/bootstrap/scss/_root.scss +187 -0
- package/themes/bootstrap/scss/_spinners.scss +85 -0
- package/themes/bootstrap/scss/_tables.scss +171 -0
- package/themes/bootstrap/scss/_toasts.scss +73 -0
- package/themes/bootstrap/scss/_tooltip.scss +119 -0
- package/themes/bootstrap/scss/_transitions.scss +27 -0
- package/themes/bootstrap/scss/_type.scss +106 -0
- package/themes/bootstrap/scss/_utilities.scss +806 -0
- package/themes/bootstrap/scss/_variables-dark.scss +102 -0
- package/themes/bootstrap/scss/_variables.scss +1753 -0
- package/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
- package/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
- package/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
- package/themes/bootstrap/scss/bootstrap.scss +52 -0
- package/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
- package/themes/bootstrap/scss/forms/_form-check.scss +189 -0
- package/themes/bootstrap/scss/forms/_form-control.scss +214 -0
- package/themes/bootstrap/scss/forms/_form-range.scss +91 -0
- package/themes/bootstrap/scss/forms/_form-select.scss +80 -0
- package/themes/bootstrap/scss/forms/_form-text.scss +11 -0
- package/themes/bootstrap/scss/forms/_input-group.scss +132 -0
- package/themes/bootstrap/scss/forms/_labels.scss +36 -0
- package/themes/bootstrap/scss/forms/_validation.scss +12 -0
- package/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
- package/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
- package/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
- package/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
- package/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
- package/themes/bootstrap/scss/helpers/_position.scss +36 -0
- package/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
- package/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
- package/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
- package/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
- package/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
- package/themes/bootstrap/scss/helpers/_vr.scss +8 -0
- package/themes/bootstrap/scss/mixins/_alert.scss +18 -0
- package/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
- package/themes/bootstrap/scss/mixins/_banner.scss +7 -0
- package/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
- package/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
- package/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
- package/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
- package/themes/bootstrap/scss/mixins/_caret.scss +69 -0
- package/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
- package/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
- package/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
- package/themes/bootstrap/scss/mixins/_container.scss +11 -0
- package/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
- package/themes/bootstrap/scss/mixins/_forms.scss +163 -0
- package/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
- package/themes/bootstrap/scss/mixins/_grid.scss +151 -0
- package/themes/bootstrap/scss/mixins/_image.scss +16 -0
- package/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
- package/themes/bootstrap/scss/mixins/_lists.scss +7 -0
- package/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
- package/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
- package/themes/bootstrap/scss/mixins/_resize.scss +6 -0
- package/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
- package/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
- package/themes/bootstrap/scss/mixins/_transition.scss +26 -0
- package/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
- package/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
- package/themes/bootstrap/scss/tests/jasmine.js +16 -0
- package/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
- package/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
- package/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
- package/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
- package/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
- package/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
- package/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
- package/themes/bootstrap/scss/utilities/_api.scss +47 -0
- package/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
- package/themes/classy/README.md +89 -0
- package/themes/classy/_config.scss +245 -0
- package/themes/classy/_theme.js +31 -0
- package/themes/classy/_theme.scss +57 -0
- package/themes/classy/css/app/_panels.scss +183 -0
- package/themes/classy/css/base/_fonts.scss +79 -0
- package/themes/classy/css/base/_no-raise.scss +49 -0
- package/themes/classy/css/base/_root.scss +113 -0
- package/themes/classy/css/base/_typography.scss +154 -0
- package/themes/classy/css/base/_utilities.scss +284 -0
- package/themes/classy/css/components/_alerts.scss +51 -0
- package/themes/classy/css/components/_badges.scss +46 -0
- package/themes/classy/css/components/_buttons.scss +175 -0
- package/themes/classy/css/components/_cards.scss +41 -0
- package/themes/classy/css/components/_dropdowns.scss +48 -0
- package/themes/classy/css/components/_forms.scss +171 -0
- package/themes/classy/css/components/_receipt.scss +45 -0
- package/themes/classy/css/layout/_footer.scss +298 -0
- package/themes/classy/css/layout/_general.scss +209 -0
- package/themes/classy/css/layout/_nav.scss +154 -0
- package/themes/classy/css/layout/_shell.scss +458 -0
- package/themes/classy/css/marketing/_bento.scss +238 -0
- package/themes/classy/css/marketing/_content.scss +1328 -0
- package/themes/classy/css/marketing/_downloads.scss +246 -0
- package/themes/classy/css/marketing/_hero.scss +311 -0
- package/themes/classy/css/marketing/_sections.scss +649 -0
- package/themes/classy/css/pages/404/index.scss +67 -0
- package/themes/classy/css/pages/_auth.scss +235 -0
- package/themes/classy/css/pages/admin/firebase/index.scss +22 -0
- package/themes/classy/css/pages/blog/[slug].scss +56 -0
- package/themes/classy/css/pages/cookies.scss +2 -0
- package/themes/classy/css/pages/dashboard/account/index.scss +31 -0
- package/themes/classy/css/pages/feedback/index.scss +39 -0
- package/themes/classy/css/pages/legal/_document.scss +192 -0
- package/themes/classy/css/pages/payment/checkout/index.scss +585 -0
- package/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
- package/themes/classy/css/pages/privacy.scss +2 -0
- package/themes/classy/css/pages/status/index.scss +164 -0
- package/themes/classy/css/pages/terms.scss +2 -0
- package/themes/classy/css/pages/updates/index.scss +128 -0
- package/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
- package/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
- package/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
- package/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
- package/themes/classy/js/hero-demo-form.js +56 -0
- package/themes/neobrutalism/README.md +118 -0
- package/themes/neobrutalism/_config.scss +139 -0
- package/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
- package/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
- package/themes/neobrutalism/_theme.js +24 -0
- package/themes/neobrutalism/_theme.scss +61 -0
- package/themes/neobrutalism/css/base/_mixins.scss +46 -0
- package/themes/neobrutalism/css/base/_root.scss +169 -0
- package/themes/neobrutalism/css/base/_typography.scss +61 -0
- package/themes/neobrutalism/css/base/_utilities.scss +89 -0
- package/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
- package/themes/neobrutalism/css/components/_buttons.scss +148 -0
- package/themes/neobrutalism/css/components/_cards.scss +47 -0
- package/themes/neobrutalism/css/components/_forms.scss +88 -0
- package/themes/neobrutalism/css/components/_marketing.scss +244 -0
- package/themes/neobrutalism/css/layout/_general.scss +213 -0
- package/themes/neobrutalism/css/layout/_navigation.scss +171 -0
- package/themes/neobrutalism/css/pages/index.scss +203 -0
- package/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
- package/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
- package/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
- package/themes/newsflash/README.md +117 -0
- package/themes/newsflash/_components/heading/lede/component.html +14 -0
- package/themes/newsflash/_components/heading/lede/component.json5 +23 -0
- package/themes/newsflash/_components/heading/rule-head/component.html +17 -0
- package/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
- package/themes/newsflash/_components/news/byline/component.html +12 -0
- package/themes/newsflash/_components/news/byline/component.json5 +18 -0
- package/themes/newsflash/_components/news/story-card/component.html +25 -0
- package/themes/newsflash/_components/news/story-card/component.json5 +21 -0
- package/themes/newsflash/_config.scss +147 -0
- package/themes/newsflash/_layouts/frontend/core/base.html +51 -0
- package/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
- package/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
- package/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
- package/themes/newsflash/_sections/marketing/desks/section.html +39 -0
- package/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
- package/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
- package/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
- package/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
- package/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
- package/themes/newsflash/_theme.js +24 -0
- package/themes/newsflash/_theme.scss +70 -0
- package/themes/newsflash/css/base/_fonts.scss +80 -0
- package/themes/newsflash/css/base/_mixins.scss +51 -0
- package/themes/newsflash/css/base/_root.scss +257 -0
- package/themes/newsflash/css/base/_typography.scss +49 -0
- package/themes/newsflash/css/base/_utilities.scss +122 -0
- package/themes/newsflash/css/components/_badges.scss +65 -0
- package/themes/newsflash/css/components/_billing-toggle.scss +61 -0
- package/themes/newsflash/css/components/_buttons.scss +139 -0
- package/themes/newsflash/css/components/_cards.scss +47 -0
- package/themes/newsflash/css/components/_editorial.scss +173 -0
- package/themes/newsflash/css/components/_forms.scss +75 -0
- package/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/themes/newsflash/css/components/_panels.scss +156 -0
- package/themes/newsflash/css/components/_ticker.scss +67 -0
- package/themes/newsflash/css/layout/_general.scss +330 -0
- package/themes/newsflash/css/layout/_navigation.scss +168 -0
- package/themes/newsflash/css/pages/404/index.scss +79 -0
- package/themes/newsflash/css/pages/blog/[slug].scss +186 -0
- package/themes/newsflash/css/pages/blog/index.scss +17 -0
- package/themes/newsflash/css/pages/index.scss +157 -0
- package/themes/newsflash/css/pages/pricing/index.scss +55 -0
- package/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
- package/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
- package/themes/newsflash/js/pages/blog/[slug].js +29 -0
- package/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
- package/translations/es/pages/404.json +86 -0
- package/translations/es/pages/account.json +36 -0
- package/translations/es/pages/app.json +44 -0
- package/translations/es/pages/cancel.json +36 -0
- package/translations/es/pages/change-password.json +36 -0
- package/translations/es/pages/connections/callback.json +41 -0
- package/translations/es/pages/dashboard/account.json +475 -0
- package/translations/es/pages/dashboard.json +36 -0
- package/translations/es/pages/forgot.json +36 -0
- package/translations/es/pages/join.json +36 -0
- package/translations/es/pages/login.json +36 -0
- package/translations/es/pages/payment/checkout.json +83 -0
- package/translations/es/pages/payment/confirmation.json +62 -0
- package/translations/es/pages/portal/email-preferences.json +46 -0
- package/translations/es/pages/recover.json +36 -0
- package/translations/es/pages/refund.json +36 -0
- package/translations/es/pages/register.json +36 -0
- package/translations/es/pages/reset-password.json +36 -0
- package/translations/es/pages/reset.json +42 -0
- package/translations/es/pages/signin.json +45 -0
- package/translations/es/pages/signup.json +60 -0
- package/translations/es/pages/token.json +39 -0
- package/translations/fa/pages/404.json +86 -0
- package/translations/fa/pages/account.json +36 -0
- package/translations/fa/pages/app.json +44 -0
- package/translations/fa/pages/cancel.json +36 -0
- package/translations/fa/pages/change-password.json +36 -0
- package/translations/fa/pages/connections/callback.json +41 -0
- package/translations/fa/pages/dashboard/account.json +475 -0
- package/translations/fa/pages/dashboard.json +36 -0
- package/translations/fa/pages/forgot.json +36 -0
- package/translations/fa/pages/join.json +36 -0
- package/translations/fa/pages/login.json +36 -0
- package/translations/fa/pages/payment/checkout.json +83 -0
- package/translations/fa/pages/payment/confirmation.json +62 -0
- package/translations/fa/pages/portal/email-preferences.json +46 -0
- package/translations/fa/pages/recover.json +36 -0
- package/translations/fa/pages/refund.json +36 -0
- package/translations/fa/pages/register.json +36 -0
- package/translations/fa/pages/reset-password.json +36 -0
- package/translations/fa/pages/reset.json +42 -0
- package/translations/fa/pages/signin.json +45 -0
- package/translations/fa/pages/signup.json +60 -0
- package/translations/fa/pages/token.json +39 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Site translation — post-build: reads built pages from dist/, translates
|
|
3
|
+
* every text unit through @omega.js/devkit/translate (per-string committed
|
|
4
|
+
* cache in <consumer>/translations/, provider from config), and writes
|
|
5
|
+
* /{lang}/... copies with localized <html lang|dir>, canonical/og tags,
|
|
6
|
+
* rewritten internal links, and hreflang alternates stitched into both the
|
|
7
|
+
* copies and the originals (only the languages actually produced — hreflang
|
|
8
|
+
* never lies; a provider failure skips its page-language pair whole rather
|
|
9
|
+
* than shipping a mixed-language copy). No GitHub-branch cache, no separate
|
|
10
|
+
* credentials: the cache is part of the repo, and the default claude provider
|
|
11
|
+
* rides the local Claude Code install.
|
|
12
|
+
*
|
|
13
|
+
* The framework's OWN default pages are excluded from all of that — from the
|
|
14
|
+
* PROVIDER, that is (#605). They still get their copies, from the translations
|
|
15
|
+
* packaged with @omega.js/web (#621, ./packaged-defaults.js): the same chrome
|
|
16
|
+
* on every brand is translated once, in the framework, and read back here for
|
|
17
|
+
* free.
|
|
18
|
+
*
|
|
19
|
+
* dist/sitemap.xml is rewritten afterwards (./sitemap.js) so the produced
|
|
20
|
+
* copies are listed with the same hreflang story the pages carry.
|
|
21
|
+
*/
|
|
22
|
+
const path = require('node:path');
|
|
23
|
+
const jetpack = require('fs-jetpack');
|
|
24
|
+
const cheerio = require('cheerio');
|
|
25
|
+
const {
|
|
26
|
+
resolveProvider,
|
|
27
|
+
resolveTranslationSettings,
|
|
28
|
+
translateStrings,
|
|
29
|
+
languageName,
|
|
30
|
+
ogLocale,
|
|
31
|
+
isRTL,
|
|
32
|
+
hashKey,
|
|
33
|
+
loadCache,
|
|
34
|
+
saveCache,
|
|
35
|
+
LANGUAGE_NAMES,
|
|
36
|
+
} = require('../vendor/devkit/translate/index.js');
|
|
37
|
+
const { collectTextNodes } = require('./collect-text-nodes.js');
|
|
38
|
+
const { defaultExcludedRoutes } = require('./default-routes.js');
|
|
39
|
+
const { packagedLanguages, loadPackaged, resolvePackaged, pageNamespace } = require('./packaged-defaults.js');
|
|
40
|
+
const { updateSitemap } = require('./sitemap.js');
|
|
41
|
+
const { readPathPrefixStamp, stripPathPrefix } = require('../path-prefix.js');
|
|
42
|
+
const { PATHS } = require('../paths.js');
|
|
43
|
+
|
|
44
|
+
// System folders never translated. The framework's default PAGES are derived
|
|
45
|
+
// from the defaults tree instead (./default-routes.js) — these are the folders
|
|
46
|
+
// whose contents the build generates or the brand fills, so no default page
|
|
47
|
+
// declares them.
|
|
48
|
+
const SYSTEM_EXCLUDED_FOLDERS = ['admin', 'test', 'team', 'updates', '__/auth'];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A built file's route: 'about/index.html' → 'about', 'index.html' → ''.
|
|
52
|
+
* @param {string} relPath - path relative to the output dir
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
function routeOf(relPath) {
|
|
56
|
+
return relPath
|
|
57
|
+
.replace(/\\/g, '/')
|
|
58
|
+
.replace(/(^|\/)index\.html$/, '')
|
|
59
|
+
.replace(/\.html$/, '')
|
|
60
|
+
.replace(/\/+$/, '');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The routes a brand excluded by hand, normalized ('/blog/' → 'blog').
|
|
65
|
+
* @param {object} config - resolved config (translation.exclude)
|
|
66
|
+
* @returns {string[]}
|
|
67
|
+
*/
|
|
68
|
+
function userExcludedRoutes(config) {
|
|
69
|
+
return (config.translation?.exclude || []).map((entry) => String(entry).replace(/^\/+|\/+$/g, ''));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Build the route-exclusion test from config + the framework's own sets. Every
|
|
74
|
+
* KNOWN language code is excluded as a folder (not just the configured ones) so
|
|
75
|
+
* copies from a previous run never get re-collected as source pages.
|
|
76
|
+
* `translation.exclude` is for BRAND pages only (#605): the framework's default
|
|
77
|
+
* pages exclude themselves, derived from the defaults tree, and each one guards
|
|
78
|
+
* its subtree too (nothing under /app or /payment is marketing copy). Excluded
|
|
79
|
+
* here means excluded from PROVIDER calls — the framework's own default pages
|
|
80
|
+
* still get copies, from the translations packaged with it (#621, the
|
|
81
|
+
* default-page pass below).
|
|
82
|
+
* @param {object} config - resolved config (translation.exclude, socials)
|
|
83
|
+
* @returns {Function} (route: string) → boolean
|
|
84
|
+
*/
|
|
85
|
+
function buildExclusionTest(config) {
|
|
86
|
+
const userExcludes = userExcludedRoutes(config);
|
|
87
|
+
const frameworkRoutes = [...defaultExcludedRoutes()];
|
|
88
|
+
|
|
89
|
+
const files = new Set([
|
|
90
|
+
...frameworkRoutes,
|
|
91
|
+
...Object.keys(config.socials || {}),
|
|
92
|
+
...userExcludes,
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
const folders = [...SYSTEM_EXCLUDED_FOLDERS, ...frameworkRoutes, ...Object.keys(LANGUAGE_NAMES), ...userExcludes];
|
|
96
|
+
|
|
97
|
+
return (route) => {
|
|
98
|
+
if (files.has(route)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return folders.some((folder) => route === folder || route.startsWith(`${folder}/`));
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Rewrite same-site links on a translated page to their /{lang}/ versions.
|
|
108
|
+
* On a MOUNTED site (#355) the hrefs already carry the base path: the route
|
|
109
|
+
* is read underneath it, and the language segment goes back on AFTER it.
|
|
110
|
+
* @param {object} $ - cheerio root
|
|
111
|
+
* @param {string} lang - target language
|
|
112
|
+
* @param {string} baseUrl - site origin
|
|
113
|
+
* @param {Function} isExcluded - route exclusion test
|
|
114
|
+
* @param {string} pathPrefix - the base path the site is served under ('' at the domain root)
|
|
115
|
+
*/
|
|
116
|
+
function rewriteLinks($, lang, baseUrl, isExcluded, pathPrefix) {
|
|
117
|
+
$('a[href]').each((_, el) => {
|
|
118
|
+
const href = $(el).attr('href');
|
|
119
|
+
|
|
120
|
+
if (!href || href.startsWith('#') || href.startsWith('javascript:') || href.startsWith('mailto:') || href.startsWith('tel:')) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const url = new URL(href, baseUrl);
|
|
126
|
+
|
|
127
|
+
if (url.origin !== new URL(baseUrl).origin) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const sitePath = stripPathPrefix(url.pathname, pathPrefix);
|
|
132
|
+
const route = sitePath.replace(/^\/+|\/+$/g, '');
|
|
133
|
+
if (isExcluded(route)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
url.pathname = `${pathPrefix}/${lang}${sitePath}`;
|
|
138
|
+
|
|
139
|
+
// Preserve relative-style hrefs as root-relative paths
|
|
140
|
+
$(el).attr('href', href.startsWith('http') ? url.toString() : `${url.pathname}${url.search}${url.hash}`);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
// Unparseable href — leave it alone
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Insert hreflang + og:locale:alternate tags for the given languages
|
|
149
|
+
* (idempotent — existing tags are kept, missing ones added).
|
|
150
|
+
* @param {object} $ - cheerio root
|
|
151
|
+
* @param {string[]} languages - translated languages for THIS page
|
|
152
|
+
* @param {string} defaultLang - source language code
|
|
153
|
+
* @param {string} route - the page's route
|
|
154
|
+
* @param {string} baseUrl - site origin (on a MOUNTED site brand.url carries
|
|
155
|
+
* the base path already — absolute URLs are never prefixed a second time)
|
|
156
|
+
* @returns {boolean} whether anything was inserted
|
|
157
|
+
*/
|
|
158
|
+
function insertAlternates($, languages, defaultLang, route, baseUrl) {
|
|
159
|
+
const urlFor = (lang) => `${baseUrl}/${lang}${route ? `/${route}` : ''}`;
|
|
160
|
+
let changed = false;
|
|
161
|
+
|
|
162
|
+
const anchor = $('head link[rel="alternate"][hreflang]').last();
|
|
163
|
+
for (const lang of languages) {
|
|
164
|
+
if ($(`head link[rel="alternate"][hreflang="${lang}"]`).length) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const tag = `<link rel="alternate" href="${urlFor(lang)}" hreflang="${lang}"/>`;
|
|
169
|
+
if (anchor.length) {
|
|
170
|
+
anchor.after(`\n${tag}`);
|
|
171
|
+
} else {
|
|
172
|
+
$('head').append(`\n${tag}`);
|
|
173
|
+
}
|
|
174
|
+
changed = true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const ogLocaleTag = $('head meta[property="og:locale"]');
|
|
178
|
+
if (ogLocaleTag.length) {
|
|
179
|
+
const currentLocale = ogLocaleTag.attr('content');
|
|
180
|
+
for (const lang of [defaultLang, ...languages]) {
|
|
181
|
+
const locale = ogLocale(lang);
|
|
182
|
+
if (locale === currentLocale || $(`head meta[property="og:locale:alternate"][content="${locale}"]`).length) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
ogLocaleTag.after(`\n<meta property="og:locale:alternate" content="${locale}"/>`);
|
|
187
|
+
changed = true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return changed;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Build one translated copy on a fresh DOM: apply the translations
|
|
196
|
+
* positionally over the collector's walk, then localize the document chrome
|
|
197
|
+
* and rewrite the internal links.
|
|
198
|
+
* @param {object} options
|
|
199
|
+
* @param {string} options.sourceHtml - the built source page
|
|
200
|
+
* @param {Array<string|undefined>} options.translated - translations aligned with
|
|
201
|
+
* collectTextNodes order; undefined leaves that node in the source language
|
|
202
|
+
* @param {string} options.lang - target language
|
|
203
|
+
* @param {string} options.route - the page's route
|
|
204
|
+
* @param {string} options.baseUrl - site origin (carries the base path when mounted)
|
|
205
|
+
* @param {Function} options.isExcluded - route exclusion test
|
|
206
|
+
* @param {string} options.pathPrefix - the base path the site is served under
|
|
207
|
+
* @returns {object} cheerio root, ready for alternates + write
|
|
208
|
+
*/
|
|
209
|
+
function renderCopy(options) {
|
|
210
|
+
const { sourceHtml, translated, lang, route, baseUrl, isExcluded, pathPrefix } = options;
|
|
211
|
+
const $ = cheerio.load(sourceHtml);
|
|
212
|
+
|
|
213
|
+
collectTextNodes($).forEach((n, i) => {
|
|
214
|
+
const value = translated[i];
|
|
215
|
+
if (value === undefined) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (n.type === 'data') {
|
|
220
|
+
n.reference.data = value;
|
|
221
|
+
} else if (n.type === 'text') {
|
|
222
|
+
n.node.text(value);
|
|
223
|
+
} else if (n.type === 'attr') {
|
|
224
|
+
n.node.attr(n.attr, value);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Localize the document chrome
|
|
229
|
+
const pageUrl = `${baseUrl}/${lang}${route ? `/${route}` : ''}`;
|
|
230
|
+
$('html').attr('lang', lang);
|
|
231
|
+
$('html').attr('dir', isRTL(lang) ? 'rtl' : 'ltr');
|
|
232
|
+
$('link[rel="canonical"]').attr('href', pageUrl);
|
|
233
|
+
$('meta[property="og:url"]').attr('content', pageUrl);
|
|
234
|
+
$('meta[property="og:locale"]').attr('content', ogLocale(lang));
|
|
235
|
+
|
|
236
|
+
rewriteLinks($, lang, baseUrl, isExcluded, pathPrefix);
|
|
237
|
+
|
|
238
|
+
return $;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Where a language copy lands.
|
|
243
|
+
*
|
|
244
|
+
* Canonical URLs are extensionless (about.html ↔ /about), so the language HOME
|
|
245
|
+
* must land as <lang>.html for /es to resolve as a FILE. An es/index.html
|
|
246
|
+
* forces GitHub Pages' directory redirect (/es → /es/), which fights the zone's
|
|
247
|
+
* strip-trailing-slash rule into a 301 loop (live find, launch night
|
|
248
|
+
* 2026-07-19).
|
|
249
|
+
* @param {string} relPath - the source page's path relative to the output dir
|
|
250
|
+
* @param {string} lang - target language
|
|
251
|
+
* @returns {string} path relative to the output dir
|
|
252
|
+
*/
|
|
253
|
+
function copyTargetRel(relPath, lang) {
|
|
254
|
+
return relPath === 'index.html' ? `${lang}.html` : path.join(lang, relPath);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Produce /{lang}/ copies of the framework's OWN default pages from the
|
|
259
|
+
* translations PACKAGED with @omega.js/web (#621).
|
|
260
|
+
*
|
|
261
|
+
* These routes stay excluded from provider calls — the auth, account, payment
|
|
262
|
+
* and portal chrome never costs a brand a token — but the copy the framework
|
|
263
|
+
* wrote is copy the framework already translated, so the copies ship anyway,
|
|
264
|
+
* offline, from the committed package cache. A string the package does not
|
|
265
|
+
* carry (copy the consumer overrode, a page the framework has not regenerated
|
|
266
|
+
* for) stays in the source language and is COUNTED, never guessed at; a route
|
|
267
|
+
* the package carries nothing for at all (the legal boilerplate, by design)
|
|
268
|
+
* gets no copy, so hreflang keeps telling the truth.
|
|
269
|
+
* @param {object} options
|
|
270
|
+
* @param {string} options.outDir - built site dir
|
|
271
|
+
* @param {string[]} options.files - default-route pages, relative to outDir
|
|
272
|
+
* @param {object} options.settings - resolved translation settings
|
|
273
|
+
* @param {string} options.brand - the consuming brand's name (sentinel swap)
|
|
274
|
+
* @param {string} options.baseUrl - site origin
|
|
275
|
+
* @param {Function} options.isExcluded - route exclusion test
|
|
276
|
+
* @param {string} options.pathPrefix - the base path the site is served under
|
|
277
|
+
* @param {string} options.packagedRoot - the packaged translations root
|
|
278
|
+
* @param {object} options.logger - devkit logger
|
|
279
|
+
* @returns {{ produced: Map<string, string[]>, pages: number, strings: number, misses: number }}
|
|
280
|
+
*/
|
|
281
|
+
function translateDefaultPages(options) {
|
|
282
|
+
const { outDir, files, settings, brand, baseUrl, isExcluded, pathPrefix, packagedRoot, logger } = options;
|
|
283
|
+
const produced = new Map();
|
|
284
|
+
const outcome = { produced, pages: 0, strings: 0, misses: 0 };
|
|
285
|
+
|
|
286
|
+
if (!brand) {
|
|
287
|
+
logger.warn('Default pages: brand.name is not set, so the packaged translations cannot be brand-swapped — default pages stay untranslated');
|
|
288
|
+
return outcome;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// What the package actually ships is the FOLDERS it ships, never a list.
|
|
292
|
+
const shipped = packagedLanguages(packagedRoot);
|
|
293
|
+
const missing = settings.languages.filter((lang) => !shipped.includes(lang));
|
|
294
|
+
const languages = settings.languages.filter((lang) => shipped.includes(lang));
|
|
295
|
+
|
|
296
|
+
if (missing.length) {
|
|
297
|
+
logger.log(`Default pages: @omega.js/web ships no translations for ${missing.join(', ')} — those copies stay in ${settings.default}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (!languages.length) {
|
|
301
|
+
return outcome;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
for (const relPath of files) {
|
|
305
|
+
const route = routeOf(relPath);
|
|
306
|
+
const sourceHtml = jetpack.read(path.join(outDir, relPath));
|
|
307
|
+
const strings = collectTextNodes(cheerio.load(sourceHtml)).map((n) => n.text);
|
|
308
|
+
const producedLangs = [];
|
|
309
|
+
const copies = [];
|
|
310
|
+
|
|
311
|
+
for (const lang of languages) {
|
|
312
|
+
const { translated, hits, misses } = resolvePackaged({
|
|
313
|
+
strings,
|
|
314
|
+
brand,
|
|
315
|
+
cache: loadPackaged(packagedRoot, lang, route),
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
if (!hits) {
|
|
319
|
+
logger.log(`⊘ [${lang}] /${route} — no packaged translations for this default page`);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
logger.log(`✓ [${lang}] /${route} — ${hits} packaged string(s)${misses ? `, ${misses} not packaged (left in ${settings.default})` : ''}`);
|
|
324
|
+
outcome.strings += hits;
|
|
325
|
+
outcome.misses += misses;
|
|
326
|
+
|
|
327
|
+
copies.push({
|
|
328
|
+
targetRel: copyTargetRel(relPath, lang),
|
|
329
|
+
$: renderCopy({ sourceHtml, translated, lang, route, baseUrl, isExcluded, pathPrefix }),
|
|
330
|
+
});
|
|
331
|
+
producedLangs.push(lang);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
for (const { targetRel, $ } of copies) {
|
|
335
|
+
insertAlternates($, producedLangs, settings.default, route, baseUrl);
|
|
336
|
+
jetpack.write(path.join(outDir, targetRel), $.html());
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (producedLangs.length) {
|
|
340
|
+
produced.set(relPath, producedLangs);
|
|
341
|
+
outcome.pages++;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return outcome;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Translate the built site into every configured language.
|
|
350
|
+
* @param {object} options
|
|
351
|
+
* @param {string} options.root - consumer project root (translations/ cache home)
|
|
352
|
+
* @param {string} options.outDir - built site dir (dist)
|
|
353
|
+
* @param {object} options.config - resolved config (translation, brand, socials, url)
|
|
354
|
+
* @param {object} [options.logger] - devkit logger (silent when omitted)
|
|
355
|
+
* @param {Function} [options.send] - provider send override (tests)
|
|
356
|
+
* @param {string} [options.only] - translate only the page whose route/relPath matches
|
|
357
|
+
* @param {boolean} [options.cachedOnly] - never call the provider: pages with
|
|
358
|
+
* any cold (uncached) string are skipped whole (listed in stats.skippedCold)
|
|
359
|
+
* instead of shipping mixed-language copies — `omega build` runs this way;
|
|
360
|
+
* explicit `omega translate` owns live-LLM translation (friction #24)
|
|
361
|
+
* @param {string} [options.packagedRoot] - the default-page translations
|
|
362
|
+
* packaged with @omega.js/web (#621); default: the ones in this install
|
|
363
|
+
* @returns {Promise<object>} stats: { skipped?, pages, languages, newStrings,
|
|
364
|
+
* cachedStrings, failures (page-language pairs skipped whole), usage,
|
|
365
|
+
* skippedCold, defaultPages, packagedStrings, packagedMisses }
|
|
366
|
+
*/
|
|
367
|
+
async function translateSite(options) {
|
|
368
|
+
const { root, outDir, config } = options;
|
|
369
|
+
const logger = options.logger || { log: () => {}, warn: () => {}, error: () => {} };
|
|
370
|
+
|
|
371
|
+
const settings = resolveTranslationSettings(config);
|
|
372
|
+
if (!settings.enabled) {
|
|
373
|
+
return { skipped: true };
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const provider = options.send
|
|
377
|
+
? { name: 'custom', model: '', send: options.send }
|
|
378
|
+
: resolveProvider({ provider: settings.provider, model: settings.model });
|
|
379
|
+
|
|
380
|
+
const baseUrl = (config.url || config.brand?.url || 'http://localhost').replace(/\/+$/, '');
|
|
381
|
+
const brand = config.brand?.name;
|
|
382
|
+
const cacheRoot = path.join(root, 'translations');
|
|
383
|
+
const isExcluded = buildExclusionTest(config);
|
|
384
|
+
|
|
385
|
+
// Collect translatable pages
|
|
386
|
+
const allHtml = jetpack.find(outDir, { matching: '**/*.html' })
|
|
387
|
+
.map((file) => path.relative(outDir, file));
|
|
388
|
+
|
|
389
|
+
const onlyFilter = (relPath) => relPath === options.only || routeOf(relPath) === options.only.replace(/^\/+|\/+$/g, '');
|
|
390
|
+
const allFiles = allHtml.filter((relPath) => !isExcluded(routeOf(relPath)));
|
|
391
|
+
const files = options.only ? allFiles.filter(onlyFilter) : allFiles;
|
|
392
|
+
|
|
393
|
+
// The framework's OWN default pages (#621): excluded above from provider
|
|
394
|
+
// calls, collected here for the packaged-cache pass. A system folder, a
|
|
395
|
+
// language folder from a previous run, and a route the brand excluded by
|
|
396
|
+
// hand are all still out — the pass only ever reaches pages the framework
|
|
397
|
+
// itself wrote.
|
|
398
|
+
const guardedFolders = [...SYSTEM_EXCLUDED_FOLDERS, ...Object.keys(LANGUAGE_NAMES), ...userExcludedRoutes(config)];
|
|
399
|
+
const defaultRoutes = defaultExcludedRoutes();
|
|
400
|
+
const allDefaultFiles = allHtml.filter((relPath) => {
|
|
401
|
+
const route = routeOf(relPath);
|
|
402
|
+
|
|
403
|
+
return defaultRoutes.has(route)
|
|
404
|
+
&& !guardedFolders.some((folder) => route === folder || route.startsWith(`${folder}/`));
|
|
405
|
+
});
|
|
406
|
+
const defaultFiles = options.only ? allDefaultFiles.filter(onlyFilter) : allDefaultFiles;
|
|
407
|
+
|
|
408
|
+
// Base path (#355): the build stamped the mount point on every page it
|
|
409
|
+
// emitted, so the pass reads it off the site itself — no caller plumbing,
|
|
410
|
+
// and `omega translate` run on its own gets it too. dist IS the mount root,
|
|
411
|
+
// so only the URLs carry it; the copies' file paths never do (#359).
|
|
412
|
+
const prefixSource = files[0] || defaultFiles[0];
|
|
413
|
+
const pathPrefix = prefixSource ? readPathPrefixStamp(jetpack.read(path.join(outDir, prefixSource))) : '';
|
|
414
|
+
|
|
415
|
+
logger.log(`Translating ${files.length} pages into ${settings.languages.length} language(s): ${settings.languages.join(', ')} (provider: ${provider.name}${provider.model ? `/${provider.model}` : ''})`);
|
|
416
|
+
|
|
417
|
+
const stats = { pages: 0, languages: settings.languages, newStrings: 0, cachedStrings: 0, failures: [], usage: { input: 0, output: 0 }, skippedCold: [], defaultPages: 0, packagedStrings: 0, packagedMisses: 0 };
|
|
418
|
+
const translatedRoutes = new Map(); // relPath → langs successfully produced
|
|
419
|
+
const total = files.length * settings.languages.length;
|
|
420
|
+
let done = 0;
|
|
421
|
+
|
|
422
|
+
for (const relPath of files) {
|
|
423
|
+
const route = routeOf(relPath);
|
|
424
|
+
const sourceHtml = jetpack.read(path.join(outDir, relPath));
|
|
425
|
+
const namespace = pageNamespace(route);
|
|
426
|
+
|
|
427
|
+
// Source strings (collected once per page from a throwaway DOM)
|
|
428
|
+
const strings = collectTextNodes(cheerio.load(sourceHtml)).map((n) => n.text);
|
|
429
|
+
const producedLangs = [];
|
|
430
|
+
const copies = [];
|
|
431
|
+
|
|
432
|
+
for (const lang of settings.languages) {
|
|
433
|
+
done++;
|
|
434
|
+
const logTag = `[${done}/${total}] [${lang}] /${route}`;
|
|
435
|
+
|
|
436
|
+
// Cache lookup per string
|
|
437
|
+
const cache = loadCache(cacheRoot, lang, namespace);
|
|
438
|
+
const translated = new Array(strings.length);
|
|
439
|
+
const missIndices = [];
|
|
440
|
+
|
|
441
|
+
strings.forEach((text, i) => {
|
|
442
|
+
const hit = cache[hashKey(text)];
|
|
443
|
+
if (hit !== undefined) {
|
|
444
|
+
translated[i] = hit;
|
|
445
|
+
stats.cachedStrings++;
|
|
446
|
+
} else {
|
|
447
|
+
missIndices.push(i);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Cold strings under cachedOnly: skip the whole page-language pair —
|
|
452
|
+
// a partially translated page is worse than none, and hreflang stays
|
|
453
|
+
// honest because only produced copies get alternates
|
|
454
|
+
if (options.cachedOnly && missIndices.length) {
|
|
455
|
+
stats.skippedCold.push(`${lang} /${route}`);
|
|
456
|
+
logger.log(`⊘ ${logTag} — ${missIndices.length} cold string(s), skipped`);
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Translate the misses
|
|
461
|
+
if (missIndices.length) {
|
|
462
|
+
try {
|
|
463
|
+
const { result, usage } = await translateStrings({
|
|
464
|
+
strings: missIndices.map((i) => strings[i]),
|
|
465
|
+
language: lang,
|
|
466
|
+
languageName: languageName(lang),
|
|
467
|
+
brand,
|
|
468
|
+
send: provider.send,
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
missIndices.forEach((origIndex, j) => {
|
|
472
|
+
translated[origIndex] = result[j];
|
|
473
|
+
cache[hashKey(strings[origIndex])] = result[j];
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
stats.newStrings += missIndices.length;
|
|
477
|
+
stats.usage.input += usage.input;
|
|
478
|
+
stats.usage.output += usage.output;
|
|
479
|
+
logger.log(`✓ ${logTag} — ${missIndices.length} new + ${strings.length - missIndices.length} cached`);
|
|
480
|
+
} catch (e) {
|
|
481
|
+
// Skip the whole page-language pair, exactly like a cold cache
|
|
482
|
+
// under cachedOnly: a half-translated copy is worse than none, and
|
|
483
|
+
// it would ship silently behind full language chrome
|
|
484
|
+
stats.failures.push(`${lang} /${route}: ${e.message}`);
|
|
485
|
+
logger.warn(`✗ ${logTag} — ${e.message} — page skipped (no ${lang} copy)`);
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
} else {
|
|
489
|
+
logger.log(`✓ ${logTag} — all ${strings.length} strings cached`);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
saveCache(cacheRoot, lang, namespace, cache, strings);
|
|
493
|
+
|
|
494
|
+
copies.push({
|
|
495
|
+
targetRel: copyTargetRel(relPath, lang),
|
|
496
|
+
$: renderCopy({ sourceHtml, translated, lang, route, baseUrl, isExcluded, pathPrefix }),
|
|
497
|
+
});
|
|
498
|
+
producedLangs.push(lang);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Copies land after the page's whole language pass so their alternates
|
|
502
|
+
// name only the languages actually produced — a skipped pair (cold cache
|
|
503
|
+
// or provider failure) is never advertised (hreflang never lies)
|
|
504
|
+
for (const { targetRel, $ } of copies) {
|
|
505
|
+
insertAlternates($, producedLangs, settings.default, route, baseUrl);
|
|
506
|
+
jetpack.write(path.join(outDir, targetRel), $.html());
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (producedLangs.length) {
|
|
510
|
+
translatedRoutes.set(relPath, producedLangs);
|
|
511
|
+
stats.pages++;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// The framework's own default pages, from the cache packaged with
|
|
516
|
+
// @omega.js/web (#621) — zero provider calls, so this runs on every pass,
|
|
517
|
+
// cachedOnly included. Their copies join translatedRoutes, which is what
|
|
518
|
+
// gives them hreflang alternates and sitemap entries like any other page.
|
|
519
|
+
const defaults = translateDefaultPages({
|
|
520
|
+
outDir,
|
|
521
|
+
files: defaultFiles,
|
|
522
|
+
settings,
|
|
523
|
+
brand,
|
|
524
|
+
baseUrl,
|
|
525
|
+
isExcluded,
|
|
526
|
+
pathPrefix,
|
|
527
|
+
packagedRoot: options.packagedRoot || PATHS.translations,
|
|
528
|
+
logger,
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
stats.defaultPages = defaults.pages;
|
|
532
|
+
stats.packagedStrings = defaults.strings;
|
|
533
|
+
stats.packagedMisses = defaults.misses;
|
|
534
|
+
defaults.produced.forEach((langs, relPath) => translatedRoutes.set(relPath, langs));
|
|
535
|
+
|
|
536
|
+
if (defaults.pages) {
|
|
537
|
+
logger.log(`Default pages: ${defaults.pages} translated from the packaged cache (${defaults.strings} strings${defaults.misses ? `, ${defaults.misses} not packaged` : ''})`);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Stitch alternates into the ORIGINALS — only for pages actually translated
|
|
541
|
+
for (const [relPath, langs] of translatedRoutes) {
|
|
542
|
+
const file = path.join(outDir, relPath);
|
|
543
|
+
const $ = cheerio.load(jetpack.read(file));
|
|
544
|
+
|
|
545
|
+
if (insertAlternates($, langs, settings.default, routeOf(relPath), baseUrl)) {
|
|
546
|
+
jetpack.write(file, $.html());
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// The sitemap tells the same story: the produced copies join it with their
|
|
551
|
+
// hreflang alternates, and a skipped pair is listed nowhere
|
|
552
|
+
const sitemapUrls = updateSitemap({
|
|
553
|
+
outDir,
|
|
554
|
+
baseUrl,
|
|
555
|
+
defaultLang: settings.default,
|
|
556
|
+
produced: new Map([...translatedRoutes].map(([relPath, langs]) => [routeOf(relPath), langs])),
|
|
557
|
+
logger,
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
if (sitemapUrls !== null) {
|
|
561
|
+
stats.sitemapUrls = sitemapUrls;
|
|
562
|
+
logger.log(`Sitemap: ${sitemapUrls} translated URL(s) with hreflang alternates`);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return stats;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
module.exports = { translateSite, routeOf, collectTextNodes, SYSTEM_EXCLUDED_FOLDERS };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default-page translations PACKAGED with @omega.js/web (#621).
|
|
3
|
+
*
|
|
4
|
+
* Every brand renders the SAME framework chrome on its auth, account, payment
|
|
5
|
+
* and portal screens, so before #605 every brand paid a provider to translate
|
|
6
|
+
* the identical strings, and after it those pages shipped in English. The
|
|
7
|
+
* framework translates them ONCE (./generate-defaults.js), commits the result
|
|
8
|
+
* inside the package, and every consumer reads it: default routes stay out of
|
|
9
|
+
* PROVIDER calls and still get their /{lang}/ copies.
|
|
10
|
+
*
|
|
11
|
+
* Layout: `<pkg>/translations/{lang}/pages/{route}.json` — the SAME
|
|
12
|
+
* `{lang}/{namespace}.json` shape as a consumer's own committed cache, loaded
|
|
13
|
+
* by the same devkit loader, so a packaged file is reviewable, hand-fixable
|
|
14
|
+
* and pruned exactly like one.
|
|
15
|
+
*
|
|
16
|
+
* The one difference is the KEY. A consumer's cache hashes the string as its
|
|
17
|
+
* own site rendered it, brand name and all; the packaged one is brand-NEUTRAL
|
|
18
|
+
* — the generator replaces its fixture brand with the SENTINEL before hashing,
|
|
19
|
+
* and the read-through replaces the consumer's own brand name with the same
|
|
20
|
+
* token before the lookup, then puts it back on the way out. "Sign in to
|
|
21
|
+
* OmegaBrandFixture" and "Sign in to MiniCo" are one packaged entry.
|
|
22
|
+
*/
|
|
23
|
+
const jetpack = require('fs-jetpack');
|
|
24
|
+
const { hashKey, loadCache, LANGUAGE_NAMES } = require('../vendor/devkit/translate/index.js');
|
|
25
|
+
const { PATHS } = require('../paths.js');
|
|
26
|
+
|
|
27
|
+
// The brand-name placeholder inside a packaged translation. Deliberately
|
|
28
|
+
// unmistakable: it must survive a round trip through a translation model
|
|
29
|
+
// (the generator names it in the prompt's extra rules) and it must never
|
|
30
|
+
// collide with real page copy.
|
|
31
|
+
const SENTINEL = '__OMEGA_BRAND__';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The cache namespace a page route is stored under — the packaged cache and a
|
|
35
|
+
* consumer's own cache spell it the same way.
|
|
36
|
+
* @param {string} route - route in routeOf() shape ('' for the home page)
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function pageNamespace(route) {
|
|
40
|
+
return `pages/${route || 'home'}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Replace a brand's name with the sentinel, so the string hashes the same for
|
|
45
|
+
* every brand that renders it.
|
|
46
|
+
* @param {string} text - the rendered source string
|
|
47
|
+
* @param {string} brand - the brand name as it appears in the render
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
50
|
+
function normalizeBrand(text, brand) {
|
|
51
|
+
return brand ? text.split(brand).join(SENTINEL) : text;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Put a brand's name back where the sentinel stands.
|
|
56
|
+
* @param {string} text - a packaged translation
|
|
57
|
+
* @param {string} brand - the consuming brand's name
|
|
58
|
+
* @returns {string}
|
|
59
|
+
*/
|
|
60
|
+
function denormalizeBrand(text, brand) {
|
|
61
|
+
return text.split(SENTINEL).join(brand);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The languages @omega.js/web ships default-page translations for — read off
|
|
66
|
+
* the packaged tree, never a list (adding a language is adding its folder).
|
|
67
|
+
* @param {string} [root] - packaged translations root (tests override it)
|
|
68
|
+
* @returns {string[]} known language codes, sorted
|
|
69
|
+
*/
|
|
70
|
+
function packagedLanguages(root) {
|
|
71
|
+
return (jetpack.list(root || PATHS.translations) || [])
|
|
72
|
+
.filter((entry) => Object.hasOwn(LANGUAGE_NAMES, entry))
|
|
73
|
+
.sort();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Load one route's packaged map for one language.
|
|
78
|
+
* @param {string} root - packaged translations root
|
|
79
|
+
* @param {string} lang - language code
|
|
80
|
+
* @param {string} route - route in routeOf() shape
|
|
81
|
+
* @returns {object} sentinel-keyed hash → translation ({} when the package
|
|
82
|
+
* ships nothing for this route/language)
|
|
83
|
+
*/
|
|
84
|
+
function loadPackaged(root, lang, route) {
|
|
85
|
+
return loadCache(root, lang, pageNamespace(route));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Resolve a page's source strings against a packaged map.
|
|
90
|
+
* @param {object} options
|
|
91
|
+
* @param {string[]} options.strings - the page's source strings, in collector order
|
|
92
|
+
* @param {string} options.brand - the consuming brand's name
|
|
93
|
+
* @param {object} options.cache - the packaged map for this route/language
|
|
94
|
+
* @returns {{ translated: Array<string|undefined>, hits: number, misses: number }}
|
|
95
|
+
* translated is positionally aligned with strings; a miss is undefined, which
|
|
96
|
+
* the caller leaves in the source language
|
|
97
|
+
*/
|
|
98
|
+
function resolvePackaged(options) {
|
|
99
|
+
const { strings, brand, cache } = options;
|
|
100
|
+
const translated = new Array(strings.length);
|
|
101
|
+
let hits = 0;
|
|
102
|
+
|
|
103
|
+
strings.forEach((text, i) => {
|
|
104
|
+
// A brand named after a word the chrome itself uses ("Sign", "Apply")
|
|
105
|
+
// normalizes strings that never mention the brand — every occurrence goes,
|
|
106
|
+
// brand-name or not — so a normalized miss tries the RAW key too: a string
|
|
107
|
+
// with no brand in it was packaged under exactly that plain hash.
|
|
108
|
+
const value = cache[hashKey(normalizeBrand(text, brand))] ?? cache[hashKey(text)];
|
|
109
|
+
|
|
110
|
+
if (value !== undefined) {
|
|
111
|
+
translated[i] = denormalizeBrand(value, brand);
|
|
112
|
+
hits++;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return { translated, hits, misses: strings.length - hits };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = {
|
|
120
|
+
SENTINEL,
|
|
121
|
+
pageNamespace,
|
|
122
|
+
normalizeBrand,
|
|
123
|
+
denormalizeBrand,
|
|
124
|
+
packagedLanguages,
|
|
125
|
+
loadPackaged,
|
|
126
|
+
resolvePackaged,
|
|
127
|
+
};
|