Merge origin/development (863174825) into studio/p-assembly
This commit is contained in:
commit
269226318d
39 changed files with 288 additions and 80 deletions
3
library/i18n/locales/ar/wallPrint.json
Normal file
3
library/i18n/locales/ar/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "هذا الملصق مخصّص للمطبعة: في نافذة الطباعة اختر «حفظ بتنسيق PDF»، ثم أرسل الملف إلى المطبعة."
|
||||
}
|
||||
3
library/i18n/locales/de/wallPrint.json
Normal file
3
library/i18n/locales/de/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Dieses Poster ist für eine Druckerei gedacht: Wählen Sie im Druckdialog „Als PDF speichern“ und senden Sie die Datei dann an die Druckerei."
|
||||
}
|
||||
3
library/i18n/locales/en/wallPrint.json
Normal file
3
library/i18n/locales/en/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "This poster is for a print shop: in the print dialog, choose “Save as PDF”, then send the file to the print shop."
|
||||
}
|
||||
3
library/i18n/locales/es/wallPrint.json
Normal file
3
library/i18n/locales/es/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Este póster es para una imprenta: en el diálogo de impresión, elija «Guardar como PDF» y luego envíe el archivo a la imprenta."
|
||||
}
|
||||
3
library/i18n/locales/fr/wallPrint.json
Normal file
3
library/i18n/locales/fr/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Cette affiche est destinée à un imprimeur : dans la fenêtre d’impression, choisissez « Enregistrer au format PDF », puis envoyez le fichier à l’imprimeur."
|
||||
}
|
||||
3
library/i18n/locales/hi/wallPrint.json
Normal file
3
library/i18n/locales/hi/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "यह पोस्टर प्रिंटिंग प्रेस के लिए है: प्रिंट विंडो में “PDF के रूप में सहेजें” चुनें, फिर फ़ाइल प्रिंटिंग प्रेस को भेजें।"
|
||||
}
|
||||
3
library/i18n/locales/it/wallPrint.json
Normal file
3
library/i18n/locales/it/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Questo poster è pensato per una tipografia: nella finestra di stampa scegli «Salva come PDF», poi invia il file alla tipografia."
|
||||
}
|
||||
3
library/i18n/locales/pt/wallPrint.json
Normal file
3
library/i18n/locales/pt/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Este pôster é para uma gráfica: na janela de impressão, escolha “Salvar como PDF” e depois envie o arquivo para a gráfica."
|
||||
}
|
||||
3
library/i18n/locales/ro/wallPrint.json
Normal file
3
library/i18n/locales/ro/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Acest poster este pentru o tipografie: în fereastra de tipărire, alegeți „Salvați ca PDF”, apoi trimiteți fișierul la tipografie."
|
||||
}
|
||||
3
library/i18n/locales/ru/wallPrint.json
Normal file
3
library/i18n/locales/ru/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "Этот плакат предназначен для типографии: в окне печати выберите «Сохранить как PDF», затем отправьте файл в типографию."
|
||||
}
|
||||
3
library/i18n/locales/zh/wallPrint.json
Normal file
3
library/i18n/locales/zh/wallPrint.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"printShopHint": "此海报需由印刷店印制:在打印对话框中选择“另存为 PDF”,然后将文件发送给印刷店。"
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@
|
|||
"fix:sri": "node internal/fix-sri.mjs",
|
||||
"gallery": "node internal/generate-gallery.mjs",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:capability-derived check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:zoning-declared check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:script-flags check:capability-exemplars check:packet-fixture check:packet-browser check:provider-switch check:locale-reachable check:url-resolver check:manifest-covers check:one-palette check:pin-dim-slider check:legend-source check:clustering-modes check:composite-embed-knobs check:composite-locale-leaks check:linked-vocabulary check:wp-embed check:dashboard-geocoder-provider check:leaf-engine-per-provider check:auto-engine check:engine-contract check:map-props-unit check:composites-mount check:composite-interop check:no-free-identifiers check:map-fly-reduced-motion check:mst-clustering check:list-prop-unit check:profiles-mount check:cdn-pins check:no-eval check:popup-escaping check:i18n-treeshake check:pinned-umd check:one-palette:self-test check:no-cross-plugin-imports check:no-cross-plugin-imports:self-test check:map-attribution check:studio-rail check:approx-pin-note check:embedder-keys check:provider-for check:legend-logical-insets check:legend-logical-insets:self-test check:optional-t-equivalence check:text-highlight check:religion-label-not-value check:i18n-stopped-scope check:no-silent-engine check:no-silent-engine:self-test check:regions-uses-library check:shadow-css-parses check:square-map-controls check:preset-config-merge check:instance-config-keys check:frozen-labels check:plural-forms check:region-fill-repaint check:region-paint-single-source check:poster-print-fallback check:posters-exportable check:country-names check:reduced-motion check:no-dead-library check:universal-props check:readme-size check:tree-relative check:leaf-hints check:snippet-engine check:snippet-engine:self-test check:embed-base check:link-coverage check:no-public-binds check:shared-reached check:tree-weight check:no-fleet-names:self-test",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-design-catalogue check:no-fleet-names",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:doc-scripts check:setup-order check:package-json-unique-keys check:no-repo-pb-hooks check:no-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion check:poster-action-print check:targets check:targets:self-test check:browser-gates-guarded check:pin-selection check:facet-shape check:hardcoded-english:self-test check:list-selection check:selector-fields check:upg-zone-joins check:gospel-set-charts check:gospel-set-fit check:describe-group check:one-scroll-container check:packet-charts check:composite-token-url check:language-tree-layout check:i18n-keys-exist check:i18n-never-translated check:packet-variants check:profile-table check:element-bootstrap check:embed-url-absolute check:frame-target check:language-tree-model check:map-menu-anchor check:selection-kinds check:tiered-points check:whiteboard-projection check:mercator-slice check:ring-vocabulary check:map-props-unit check:mobile-gating check:provide-shadowing check:legend-top-offset check:cdn-cache check:plural-forms check:select-zone-race check:script-registry check:map-control-overlap check:poster-attribution check:board-map-options check:gospel-whiteboard check:packet-map-missing-loud check:poster-layout-optin check:ported-globals-identical check:ring-bands check:packet-a1-structure check:india-states check:batch-selection-export check:zone-title-tier-a check:evangelical-share check:map-labels check:packet-offline check:help-reachable check:gated-not-in-tree check:window-globals-released check:legend-data-contract check:no-internal-role-nouns check:poster-fetch-guard check:people-group-records check:sentence-slots check:popup-href-escaped check:popup-pan-controls check:country-map-refetch check:pane-config-reforward check:viewport-meta check:viewport-meta:self-test check:label-key-coverage check:poster-browser-equiv check:poster-render-pinned check:country-sheet-one-path check:country-sheet-one-path:self-test check:posterverse-shelf check:host-locale-fetch check:print-frame-reclaim check:click-sheet check:coverage-consistent:chained check:coverage-consistent:poison check:dashboard-filter-a11y check:filter-multivalue check:hover-channel check:kit-options-reachable check:layout-key-namespaced check:legend-mirrors check:map-unmount-race check:no-conflict-markers check:series-isolation check:snapshot-guard check:stale-sweep-claim check:surfaces-read-the-tier check:translator-contacts check:wall-wysiwyg check:wall-print-watch check:wall-no-bg-photos check:wall-pan check:template-i18n check:list-pattern-doc check:shadow-style-labels-unique check:grid-image-loading check:retry-fetch check:panel-sheets check:poster-wall-host-seams check:poster-design-catalogue check:wall-photo-weight check:no-fleet-names",
|
||||
"gen:iso3-to-alpha2": "node library/scripts/generate-iso3-to-alpha2.mjs",
|
||||
"internet:adm1": "node plugin-designs/cities-internet/scripts/build-adm1-internet.mjs",
|
||||
"library-index": "node internal/generate-library-index.mjs",
|
||||
|
|
@ -400,6 +400,7 @@
|
|||
"check:wall-print-watch": "node plugin-designs/wall-of-people-groups/scripts/check-wall-print-watch.mjs",
|
||||
"check:wall-no-bg-photos": "node plugin-designs/wall-of-people-groups/scripts/check-wall-no-bg-photos.mjs",
|
||||
"check:wall-pan": "node plugin-designs/wall-of-people-groups/scripts/check-wall-pan.mjs",
|
||||
"check:wall-photo-weight": "node plugin-designs/wall-of-people-groups/scripts/check-wall-photo-weight.mjs",
|
||||
"check:template-i18n": "node plugin-designs/template-bundle/scripts/check-template-i18n.mjs",
|
||||
"check:snippets-draw": "node internal/check-snippets-draw.mjs",
|
||||
"check:snippets-draw:mapbox": "node internal/check-snippets-draw.mjs --mapbox",
|
||||
|
|
@ -425,6 +426,7 @@
|
|||
"check:wall-print-watch": "the Wall's HD poster print never prints silently incomplete: with fake timers and a fake frame, the watch counts photos as they load, counts the ones that could not, and reports both. Two-sided on planted printWatch copies. Headless.",
|
||||
"check:wall-no-bg-photos": "the Wall's store downloads no photos on its own (it used to test all 932, 132 MB, on every visit): the REAL store runs through Vite against the committed fixtures/pray-list-sample.json with fetch stubbed and every Image request counted. Two-sided with the old background test planted. Headless, no network.",
|
||||
"check:wall-pan": "the Wall pans and zooms with the pointer 1:1: the REAL WallCanvas methods (through Vite) with d3-zoom's transform arithmetic, over 12 fits and zooms: a pan moves every card exactly as far as the pointer, a zoom keeps the point under the pointer, toWorld inverts toScreen, and a fling never loses the wall. Two-sided: the old transform-inside-the-fit formulas are planted and caught. Headless.",
|
||||
"check:wall-photo-weight": "the Wall's poster loads its photos at print size: the 77 IMB photos (1024 px, ~1.5 MB each, 114 MB of the print's 133 MB) map to their host's 320 px copies on either host, with the original as the onerror fallback, every other photo untouched, and the print HTML and the screen canvas both go through photoUrl.js. Two-sided (the old full-size URLs are caught). Headless.",
|
||||
"check:template-i18n": "the starter template every new plugin copies renders its text from the catalogue: profile B, server-rendered with the REAL template.json in en, ar and zh, takes its heading, note and sentence from the page's language. Two-sided with the English catalogue served as Arabic. Headless (SSR).",
|
||||
"check:coverage-consistent:chained": "every clause of check:coverage-consistent EXCEPT the link-verification age (VERIFY_MAX_AGE_DAYS set out of reach): the chains run what depends on the code and data, and leave what depends on the calendar to the on-demand run, so the gates cannot turn red on a date with no change.",
|
||||
"check:viewport-meta": "every generated page declares <meta name=\"viewport\"> with width=device-width. Without it a browser lays the page out at the 980px desktop fallback even when the viewport is set to 390, so a mobile probe silently measures a viewport no phone has and still passes (measured: innerWidth 980 without the tag, 390 with it). width=device-width is required specifically, because a meta carrying only initial-scale still lays out at 980. Checked on the BUILT tree, not the generator template. Fixed-size print sheets are exempt by their stated shape (a .stage with a three-digit px width), and a page that must render at a fixed desktop width carries a viewport-meta-ok: reason. 8 self-tests. Source-only, headless.",
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ const csv = M.buildCsv(
|
|||
const lines = csv.split('\r\n')
|
||||
ok(lines[0] === 'A,B' && lines[lines.length - 1].startsWith('# test') && (POISON ? false : true), 'CSV header first, provenance last')
|
||||
ok(lines[1].startsWith('"\'=HYPERLINK') && lines[1].endsWith('"Arabic, Mesopotamian"'), 'CSV neutralises = and quotes an embedded comma')
|
||||
// A spreadsheet can strip a leading TAB or CR and then read the = after it as a formula (OWASP's list), so those
|
||||
// two lead characters are neutralised too, the same as the library's useCsvExport.
|
||||
const tabCell = M.buildCsv([{ a: '\t=cmd' }], [{ key: 'a', header: 'A' }]).split('\r\n')[1]
|
||||
ok(tabCell === "'\t=cmd", `CSV neutralises a leading TAB (got ${JSON.stringify(tabCell)})`)
|
||||
const crCell = M.buildCsv([{ a: '\r=cmd' }], [{ key: 'a', header: 'A' }]).slice('A\r\n'.length)
|
||||
ok(crCell === '"\'\r=cmd"', `CSV neutralises a leading CR, then quotes it (got ${JSON.stringify(crCell)})`)
|
||||
|
||||
// 9. platforms: the preset is "nothing in own language, 60%+ online" (the 220), and the app chart counts
|
||||
// each COUNTRY once, with countries outside Apple's feed kept as "not measured", never dropped
|
||||
|
|
|
|||
|
|
@ -301,7 +301,9 @@ export function sortRows(rows, { key, dir = 1 } = {}) {
|
|||
export function buildCsv(rows, columns, { provenance = '' } = {}) {
|
||||
const esc = (v) => {
|
||||
let s = v === null || v === undefined ? '' : String(v)
|
||||
if (/^[=+\-@]/.test(s)) s = "'" + s
|
||||
// A leading = + - @ TAB or CR is neutralised: a spreadsheet can strip a leading TAB/CR and then read the =
|
||||
// after it as a formula (OWASP's list). The same guard as the library's useCsvExport.
|
||||
if (/^[=+\-@\t\r]/.test(s)) s = "'" + s
|
||||
if (/[",\n\r]/.test(s)) s = '"' + s.replace(/"/g, '""') + '"'
|
||||
return s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
:title="headingText"
|
||||
:nav-label="tr('sec.posters')"
|
||||
:header="false"
|
||||
:home-href="homeHref || cfg.homeHref || ''"
|
||||
:home-label="homeLabel || cfg.homeLabel || ''"
|
||||
:groups="navGroups"
|
||||
:active="activeKey"
|
||||
@update:active="onSelect">
|
||||
|
|
@ -106,6 +108,10 @@ export default defineComponent({
|
|||
provider: { type: String, default: '' },
|
||||
// Which tab opens first, by row id (src/tabs.js). Also ?tab= on the page URL.
|
||||
tab: { type: String, default: '' },
|
||||
// The host's "Back to homepage" link, drawn by VerticalTabsLayout directly above Collapse (the top of
|
||||
// the drawer on a phone). Also accepted as profile-config.homeHref / homeLabel. No URL, no link.
|
||||
homeHref: { type: String, default: '' },
|
||||
homeLabel: { type: String, default: '' },
|
||||
},
|
||||
emits: ['tab-change'],
|
||||
setup() {
|
||||
|
|
@ -156,7 +162,7 @@ export default defineComponent({
|
|||
uiDir() { return this.uiLocale === 'ar' ? 'rtl' : 'ltr' },
|
||||
layoutLabels() {
|
||||
const out = {}
|
||||
for (const k of ['toggleList', 'openViews', 'expandList', 'collapseList', 'collapse']) out[k] = this.tr(k)
|
||||
for (const k of ['toggleList', 'openViews', 'expandList', 'collapseList', 'collapse', 'home']) out[k] = this.tr(k)
|
||||
return out
|
||||
},
|
||||
effectiveProvider() {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export function checkShelf({ SECTIONS, TABS, NEVER, resolveTabs, manifest, meta,
|
|||
// E. strings
|
||||
const en = STRINGS.en || {}
|
||||
const used = ['lab', 'experimentalSub', 'loading', 'loadFailed', 'manifestHint', 'backToTop',
|
||||
'toggleList', 'openViews', 'expandList', 'collapseList', 'collapse',
|
||||
'toggleList', 'openViews', 'expandList', 'collapseList', 'collapse', 'home',
|
||||
...SECTIONS.map((s) => s.i18n), ...TABS.map((t) => 'tab.' + t.id),
|
||||
...TABS.filter((t) => t.section !== 'experimental').map((t) => 'sub.' + t.id)]
|
||||
for (const k of used) if (!(k in en)) errs.push(`E: the shell reads "${k}", which English does not define`)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ export const STRINGS = {
|
|||
loading: 'Loading {label}…', loadFailed: 'Could not load {label}.',
|
||||
manifestHint: 'This tab is composed from manifest.json — build the tree, or serve the built tree, to load it.',
|
||||
backToTop: 'Back to top',
|
||||
home: 'Back to homepage',
|
||||
toggleList: 'Toggle list', openViews: 'Open the list of views', expandList: 'Expand list', collapseList: 'Collapse list', collapse: 'Collapse',
|
||||
},
|
||||
es: {
|
||||
|
|
@ -37,6 +38,7 @@ export const STRINGS = {
|
|||
loading: 'Cargando {label}…', loadFailed: 'No se pudo cargar {label}.',
|
||||
manifestHint: 'Esta pestaña se compone a partir de manifest.json: compila el árbol o sirve el árbol compilado para cargarla.',
|
||||
backToTop: 'Volver arriba',
|
||||
home: 'Volver a la página de inicio',
|
||||
toggleList: 'Mostrar u ocultar la lista', openViews: 'Abrir la lista de vistas', expandList: 'Expandir la lista', collapseList: 'Contraer la lista', collapse: 'Contraer',
|
||||
},
|
||||
fr: {
|
||||
|
|
@ -50,6 +52,7 @@ export const STRINGS = {
|
|||
loading: 'Chargement de {label}…', loadFailed: 'Impossible de charger {label}.',
|
||||
manifestHint: "Cet onglet est composé à partir de manifest.json : construisez l'arborescence ou servez l'arborescence construite pour le charger.",
|
||||
backToTop: 'Retour en haut',
|
||||
home: 'Retour à l’accueil',
|
||||
toggleList: 'Afficher ou masquer la liste', openViews: 'Ouvrir la liste des vues', expandList: 'Déplier la liste', collapseList: 'Replier la liste', collapse: 'Replier',
|
||||
},
|
||||
de: {
|
||||
|
|
@ -63,6 +66,7 @@ export const STRINGS = {
|
|||
loading: '{label} wird geladen…', loadFailed: '{label} konnte nicht geladen werden.',
|
||||
manifestHint: 'Dieser Tab wird aus manifest.json zusammengesetzt – bauen Sie den Baum oder stellen Sie den gebauten Baum bereit, um ihn zu laden.',
|
||||
backToTop: 'Nach oben',
|
||||
home: 'Zurück zur Startseite',
|
||||
toggleList: 'Liste ein-/ausblenden', openViews: 'Ansichtsliste öffnen', expandList: 'Liste ausklappen', collapseList: 'Liste einklappen', collapse: 'Einklappen',
|
||||
},
|
||||
pt: {
|
||||
|
|
@ -76,6 +80,7 @@ export const STRINGS = {
|
|||
loading: 'Carregando {label}…', loadFailed: 'Não foi possível carregar {label}.',
|
||||
manifestHint: 'Esta aba é composta a partir do manifest.json — compile a árvore ou sirva a árvore compilada para carregá-la.',
|
||||
backToTop: 'Voltar ao topo',
|
||||
home: 'Voltar à página inicial',
|
||||
toggleList: 'Mostrar ou ocultar a lista', openViews: 'Abrir a lista de visualizações', expandList: 'Expandir a lista', collapseList: 'Recolher a lista', collapse: 'Recolher',
|
||||
},
|
||||
it: {
|
||||
|
|
@ -89,6 +94,7 @@ export const STRINGS = {
|
|||
loading: 'Caricamento di {label}…', loadFailed: 'Impossibile caricare {label}.',
|
||||
manifestHint: "Questa scheda è composta da manifest.json: compila l'albero o pubblica l'albero compilato per caricarla.",
|
||||
backToTop: 'Torna su',
|
||||
home: 'Torna alla home page',
|
||||
toggleList: 'Mostra o nascondi l’elenco', openViews: 'Apri l’elenco delle viste', expandList: 'Espandi l’elenco', collapseList: 'Comprimi l’elenco', collapse: 'Comprimi',
|
||||
},
|
||||
ro: {
|
||||
|
|
@ -102,6 +108,7 @@ export const STRINGS = {
|
|||
loading: 'Se încarcă {label}…', loadFailed: '{label} nu a putut fi încărcat.',
|
||||
manifestHint: 'Această filă este compusă din manifest.json — construiți arborele sau serviți arborele construit pentru a o încărca.',
|
||||
backToTop: 'Sus',
|
||||
home: 'Înapoi la pagina principală',
|
||||
toggleList: 'Afișează sau ascunde lista', openViews: 'Deschide lista de vizualizări', expandList: 'Extinde lista', collapseList: 'Restrânge lista', collapse: 'Restrânge',
|
||||
},
|
||||
ru: {
|
||||
|
|
@ -115,6 +122,7 @@ export const STRINGS = {
|
|||
loading: 'Загрузка: {label}…', loadFailed: 'Не удалось загрузить: {label}.',
|
||||
manifestHint: 'Эта вкладка собирается из manifest.json — соберите дерево или разместите собранное дерево, чтобы загрузить её.',
|
||||
backToTop: 'Наверх',
|
||||
home: 'На главную страницу',
|
||||
toggleList: 'Показать или скрыть список', openViews: 'Открыть список представлений', expandList: 'Развернуть список', collapseList: 'Свернуть список', collapse: 'Свернуть',
|
||||
},
|
||||
ar: {
|
||||
|
|
@ -128,6 +136,7 @@ export const STRINGS = {
|
|||
loading: 'جارٍ تحميل {label}…', loadFailed: 'تعذّر تحميل {label}.',
|
||||
manifestHint: 'تُبنى علامة التبويب هذه من manifest.json — ابنِ الشجرة أو قدّم الشجرة المبنية لتحميلها.',
|
||||
backToTop: 'إلى الأعلى',
|
||||
home: 'العودة إلى الصفحة الرئيسية',
|
||||
toggleList: 'إظهار القائمة أو إخفاؤها', openViews: 'فتح قائمة العروض', expandList: 'توسيع القائمة', collapseList: 'طي القائمة', collapse: 'طي',
|
||||
},
|
||||
hi: {
|
||||
|
|
@ -141,6 +150,7 @@ export const STRINGS = {
|
|||
loading: '{label} लोड हो रहा है…', loadFailed: '{label} लोड नहीं हो सका।',
|
||||
manifestHint: 'यह टैब manifest.json से बनता है — इसे लोड करने के लिए ट्री बनाएँ या बना हुआ ट्री सर्व करें।',
|
||||
backToTop: 'ऊपर जाएँ',
|
||||
home: 'होमपेज पर वापस जाएँ',
|
||||
toggleList: 'सूची दिखाएँ या छिपाएँ', openViews: 'दृश्यों की सूची खोलें', expandList: 'सूची फैलाएँ', collapseList: 'सूची संक्षिप्त करें', collapse: 'संक्षिप्त करें',
|
||||
},
|
||||
zh: {
|
||||
|
|
@ -154,6 +164,7 @@ export const STRINGS = {
|
|||
loading: '正在加载{label}…', loadFailed: '无法加载{label}。',
|
||||
manifestHint: '此标签页由 manifest.json 组成——请构建目录树或提供已构建的目录树以加载它。',
|
||||
backToTop: '回到顶部',
|
||||
home: '返回首页',
|
||||
toggleList: '显示或隐藏列表', openViews: '打开视图列表', expandList: '展开列表', collapseList: '折叠列表', collapse: '折叠',
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* check-wall-photo-weight — the Wall's poster loads its photos at the size it prints them. Headless.
|
||||
*
|
||||
* The 77 IMB photos (peoplegroupspublic.blob.core.windows.net, images.peoplegroups.org) are 1024 px originals of
|
||||
* ~1.5 MB: 114 MB of the print's 133 MB, measured 2026-09-30, a minute or more before the print dialog can open
|
||||
* on a home connection. photoUrl.js loads a 320 px copy from the host's own resizer instead (19-20 MB in all).
|
||||
* This pins, on the REAL modules:
|
||||
* - an IMB photo on EITHER host maps to images.peoplegroups.org/cdn-cgi/image/width=320 for the same file;
|
||||
* - every other photo (Joshua Project, doxa) is untouched, and a non-URL stays as it is;
|
||||
* - fullPhoto() gives the original back for a resized URL, and null for anything else;
|
||||
* - the PRINT HTML (buildBlessPosterHtml) uses the resized copy, with the original as its onerror fallback,
|
||||
* and leaves the other photos alone; the screen canvas loads through the same lightPhoto().
|
||||
* Two-sided: lightPhoto replaced by the identity (the old behaviour) must fail the mapping and the print arms.
|
||||
* EXIT 0 pass · 1 fail
|
||||
*/
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
|
||||
const DIR = resolve(dirname(fileURLToPath(import.meta.url)), '../src')
|
||||
const P = await import(pathToFileURL(join(DIR, 'photoUrl.js')).href)
|
||||
const B = await import(pathToFileURL(join(DIR, 'blessPoster.js')).href)
|
||||
const canvasSrc = readFileSync(join(DIR, 'wallCanvas.js'), 'utf8')
|
||||
|
||||
const IMB = ['https://peoplegroupspublic.blob.core.windows.net/imbpeople-featured-images/PG016542.jpg',
|
||||
'https://images.peoplegroups.org/imbpeople-featured-images/PG023972.jpg']
|
||||
const OTHER = ['https://media.joshuaproject.net/public/assets/media/profiles/photos/p10120.jpg',
|
||||
'https://joshuaproject.net/assets/media/profiles/photos/p20298.jpg', 'https://s3.doxa.life/no-photo-images/asia.jpg']
|
||||
const WANT = (file) => `https://images.peoplegroups.org/cdn-cgi/image/width=320,format=jpeg/imbpeople-featured-images/${file}`
|
||||
|
||||
function run(light, full) {
|
||||
const errs = []
|
||||
for (const u of IMB) {
|
||||
const file = u.split('/').pop()
|
||||
if (light(u) !== WANT(file)) errs.push(`map: ${u} → ${light(u)}, want the 320 px copy`)
|
||||
if (full(light(u)) !== `https://images.peoplegroups.org/imbpeople-featured-images/${file}`) errs.push(`full: no original for ${u}`)
|
||||
}
|
||||
for (const u of OTHER) { if (light(u) !== u) errs.push(`map: ${u} was rewritten`); if (full(u) !== null) errs.push(`full: ${u} is not a resized URL`) }
|
||||
if (light('') !== '' || light('not a url') !== 'not a url') errs.push('map: a non-URL was changed')
|
||||
// the print HTML, through the real engine, with this light()
|
||||
const groups = [{ name: 'A', imageUrl: IMB[0] }, { name: 'B', imageUrl: OTHER[0] }, { name: 'C', imageUrl: '' }]
|
||||
const html = B.buildBlessPosterHtml(groups, '3x4ft', {})
|
||||
const imgs = [...html.matchAll(/<img src="([^"]+)"([^>]*)>/g)]
|
||||
if (imgs.length !== 2) errs.push(`print: ${imgs.length} photos in the document, want 2`)
|
||||
else {
|
||||
if (imgs[0][1] !== light(IMB[0]) || !imgs[0][1].includes('/cdn-cgi/image/width=320')) errs.push(`print: the IMB photo prints from ${imgs[0][1]}`)
|
||||
if (!/data-full="https:\/\/images\.peoplegroups\.org\/imbpeople-featured-images\/PG016542\.jpg"/.test(imgs[0][2]) || !/onerror=/.test(imgs[0][2])) errs.push('print: the resized photo has no fallback to its original')
|
||||
if (imgs[1][1] !== OTHER[0] || /data-full/.test(imgs[1][2])) errs.push('print: a Joshua Project photo was changed')
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
const fails = []
|
||||
fails.push(...run(P.lightPhoto, P.fullPhoto))
|
||||
// the canvas loads through the same helper (both draw paths) and retries the original
|
||||
if ((canvasSrc.match(/lightPhoto\(g\.imageUrl\)/g) || []).length < 2) fails.push('canvas: wallCanvas.js does not load every card photo through lightPhoto()')
|
||||
if (!/fullPhoto\(u\)/.test(canvasSrc)) fails.push('canvas: a failed resized photo is not retried from its original')
|
||||
// SELF-TEST: the old behaviour (originals) must fail the mapping arm; the print arm reads the real engine, so
|
||||
// it is checked by running the engine's output against an identity map
|
||||
const planted = run((u) => u, () => null)
|
||||
if (!planted.some((e) => e.startsWith('map:'))) fails.push('SELF-TEST: originals (identity) were not caught by the mapping arm')
|
||||
if (!planted.some((e) => e.startsWith('print:') || e.startsWith('full:'))) fails.push('SELF-TEST: the print/fallback arms did not react to the identity map')
|
||||
|
||||
if (fails.length) { console.log('WALL-PHOTO-WEIGHT: FAIL'); for (const f of fails) console.log(' - ' + f); process.exitCode = 1 }
|
||||
else console.log('WALL-PHOTO-WEIGHT: PASS — IMB photos on both hosts load as 320 px copies with their originals as the fallback, every other photo is untouched, and the print and the canvas both go through photoUrl.js; the old full-size behaviour is caught.')
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
* SAME layout for the screen (screenPoster: what the wall shows is what prints). No Vue.
|
||||
*/
|
||||
import { blessingFor, POSTER, THEMES } from './blessings.js'
|
||||
import { lightPhoto, fullPhoto } from './photoUrl.js'
|
||||
// The sheets, their glue bands and the print marks: the shared panel geometry (also India's large posters).
|
||||
import { planPanels, screenLayout, panelChromeHtml, panelCss } from '../../../library/components/poster/panelSheets.js'
|
||||
|
||||
|
|
@ -252,7 +253,10 @@ function posterParts(groups, presetId, texts, withCards = true) {
|
|||
const railLabel = (text) => `<span style="font-size:${f(railFs(text))}">${esc(text)}</span>`
|
||||
const card = (c) => {
|
||||
const g = groups[c.i], v = blessingFor(c.i)
|
||||
const img = g.imageUrl ? `<img src="${esc(g.imageUrl)}" alt="">` : '<div class="noimg"></div>'
|
||||
// The photo at print size (photoUrl.js); a resized copy that fails falls back to the original, so a change on
|
||||
// the photo host costs weight, never a photo.
|
||||
const light = lightPhoto(g.imageUrl), full = fullPhoto(light)
|
||||
const img = g.imageUrl ? `<img src="${esc(light)}" alt=""${full ? ` data-full="${esc(full)}" onerror="this.onerror=null;this.src=this.dataset.full"` : ''}>` : '<div class="noimg"></div>'
|
||||
// Below MIN_READABLE_PT the verse would print as grey noise: that size shows name + photo only.
|
||||
const verse = plan.text.readable ? `<div class="vs" dir="auto">${esc(v.text)}</div><div class="rf" dir="auto">${esc(v.ref)}</div>` : ''
|
||||
const nf = cardText(plan, g.name || '').name
|
||||
|
|
|
|||
|
|
@ -30,8 +30,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Every Bless size is 2-8 ft, paper no desktop printer takes: say up front that it goes to a print shop
|
||||
as a PDF, before the reader meets a print dialog showing a 3 ft page. -->
|
||||
<p v-if="mode === 'bless'" class="print-hint" role="note">{{ $t('wallPrint.printShopHint') }}</p>
|
||||
<div ref="canvas" class="wall-canvas"></div>
|
||||
<div v-if="toast" class="wall-toast" role="status">{{ toast }}</div>
|
||||
<!-- While the poster prepares (its photos load before the print dialog can open, a minute or more on a slow
|
||||
connection), the shared print card says so in the middle of the screen: the count and a clock, so a
|
||||
long wait never reads as nothing happening. -->
|
||||
<map-print-progress :visible="printing" :kind="$t('wall.printPoster')" :title="printTitle" :progress="printPercent" />
|
||||
|
||||
<div v-if="loading" class="loading-overlay">
|
||||
<div class="spinner"></div>
|
||||
|
|
@ -56,9 +63,11 @@ import { buildBlessPosterHtml, screenPoster, PRESETS, DEFAULT_PRESET } from '../
|
|||
import { openPrintFrame, printDocument, isPhonePrint } from '@map/composables/printInPlace.js'
|
||||
import { watchPrintFrame } from '../printWatch.js'
|
||||
import { useHostedHelp } from '@map/composables/useHostedHelp.js'
|
||||
import MapPrintProgress from '@map/components/poster/MapPrintProgress.vue'
|
||||
// Wall of People Groups: a zoomable canvas wall (wallCanvas.js), Bless or Social cards, and the poster print.
|
||||
export default {
|
||||
name: 'PeopleGroupsWall',
|
||||
components: { MapPrintProgress },
|
||||
// The page's profile-config, for its people-group LIST (library/lists/); handed to the store.
|
||||
inject: { profileConfig: { default: null } },
|
||||
// The wall's "?" asks its HOST for the wall's help (doxa:help); it shows only where a host answers.
|
||||
|
|
@ -75,6 +84,8 @@ export default {
|
|||
posterPresets: Object.entries(PRESETS).map(([id, p]) => ({ id, label: '\u2066' + p.label + (p.sheets > 1 ? ' · ' + p.sheets + '×' : '') + '\u2069' })),
|
||||
printing: false, // the HD poster print is loading photos (drives the button's busy state)
|
||||
printProgress: null, // { n, total, failed }: the print frame's photos, counted while they load
|
||||
printStarted: 0, // when the current print was asked for (the progress card's clock)
|
||||
printClock: 0, // seconds since then, ticked once a second while printing
|
||||
toast: '', // a short status line over the wall (e.g. "Copied!"), cleared by flash()
|
||||
cardWidth: 50,
|
||||
cardHeight: 70,
|
||||
|
|
@ -103,6 +114,16 @@ export default {
|
|||
return this.$store?.error || null;
|
||||
},
|
||||
|
||||
// The progress card: "Preparing the poster: n of total photos · m:ss" (the count once the frame reports it).
|
||||
printTitle() {
|
||||
const s = this.printClock, clock = Math.floor(s / 60) + ':' + String(s % 60).padStart(2, '0')
|
||||
const p = this.printProgress
|
||||
return p ? this.$t('wall.printPreparing', { n: p.n.toLocaleString('en-US'), total: p.total.toLocaleString('en-US') }) + ' · ' + clock : clock
|
||||
},
|
||||
printPercent() {
|
||||
const p = this.printProgress
|
||||
return { percent: p && p.total ? (100 * p.n) / p.total : 0 }
|
||||
},
|
||||
printLabel() {
|
||||
const p = this.printing && this.printProgress
|
||||
return p ? this.$t('wall.printPreparing', { n: p.n.toLocaleString('en-US'), total: p.total.toLocaleString('en-US') }) : this.$t('wall.printPoster');
|
||||
|
|
@ -121,6 +142,7 @@ export default {
|
|||
beforeUnmount() {
|
||||
// Release the canvas, its listeners and every cached photo (the fleet's leak rule).
|
||||
this._wc?.destroy(); this._wc = null;
|
||||
clearInterval(this._printTick); this._printTick = null;
|
||||
try { const host = this.$el?.getRootNode?.()?.host; if (host) delete host.__wallLod; } catch (_) { /* no host */ }
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -166,6 +188,7 @@ export default {
|
|||
const groups = (this.peopleGroups || []).map((d) => ({ name: d.name || d.post_title || '', imageUrl: d.imageUrl || '' }));
|
||||
if (!groups.length) return;
|
||||
this.printing = true;
|
||||
this.startPrintClock();
|
||||
const texts = this.posterTexts(groups.length);
|
||||
// A PHONE PRINTS THE PAGE (printInPlace.printDocument): there is no frame to watch, and printDocument
|
||||
// itself waits for the photos before it prints.
|
||||
|
|
@ -189,6 +212,15 @@ export default {
|
|||
},
|
||||
});
|
||||
},
|
||||
// The progress card's clock: from the click until the print is done (stops itself once printing ends).
|
||||
startPrintClock() {
|
||||
clearInterval(this._printTick);
|
||||
this.printStarted = Date.now(); this.printClock = 0;
|
||||
this._printTick = setInterval(() => {
|
||||
if (!this.printing) { clearInterval(this._printTick); this._printTick = null; return; }
|
||||
this.printClock = Math.floor((Date.now() - this.printStarted) / 1000);
|
||||
}, 1000);
|
||||
},
|
||||
// The wall in Bless mode IS the poster (WYSIWYG): the same sheets, cards, title, chart and footer that
|
||||
// print, from the same blessPoster layout. Re-planned when the groups, the size or the language change.
|
||||
showPoster() {
|
||||
|
|
|
|||
28
plugin-designs/wall-of-people-groups/src/photoUrl.js
Normal file
28
plugin-designs/wall-of-people-groups/src/photoUrl.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* photoUrl.js — a people group's photo at the size the Wall draws and prints it, not its original.
|
||||
*
|
||||
* Measured on the live list (939 distinct photos, 2026-09-30): the Joshua Project and doxa photos are already
|
||||
* small (150-250 px, 7-64 KB), but the 77 IMB photos (peoplegroupspublic.blob.core.windows.net and
|
||||
* images.peoplegroups.org, one Azure container behind both) are 1024 px originals of ~1.5 MB each: 114 MB of the
|
||||
* print's 133 MB. images.peoplegroups.org resizes on request (/cdn-cgi/image/), and at 320 px the 77 weigh 1.3 MB.
|
||||
* 320 px covers the largest printed photo (5 × 8 ft: ~0.97 in, 291 px at 300 dpi) and the canvas's own cap
|
||||
* (wallCanvas THUMB_PX). Every other URL is returned unchanged.
|
||||
*/
|
||||
|
||||
const IMB_HOSTS = new Set(['peoplegroupspublic.blob.core.windows.net', 'images.peoplegroups.org'])
|
||||
const IMB_PATH = /^\/(imbpeople-featured-images\/[^?#]+)$/
|
||||
export const PHOTO_PX = 320
|
||||
|
||||
/** The URL to load for a photo: a resized copy where the host offers one, else the URL itself. */
|
||||
export function lightPhoto(url) {
|
||||
let u
|
||||
try { u = new URL(url) } catch (_) { return url || '' }
|
||||
const m = IMB_HOSTS.has(u.hostname) && u.pathname.match(IMB_PATH)
|
||||
return m ? `https://images.peoplegroups.org/cdn-cgi/image/width=${PHOTO_PX},format=jpeg/${m[1]}` : url
|
||||
}
|
||||
|
||||
/** For a URL lightPhoto() rewrote, the original to fall back to if the resized copy fails; else null. */
|
||||
export function fullPhoto(light) {
|
||||
const m = String(light || '').match(/^https:\/\/images\.peoplegroups\.org\/cdn-cgi\/image\/[^/]+\/(imbpeople-featured-images\/.+)$/)
|
||||
return m ? `https://images.peoplegroups.org/${m[1]}` : null
|
||||
}
|
||||
|
|
@ -135,6 +135,18 @@ body {
|
|||
}
|
||||
|
||||
/* Wall Canvas */
|
||||
/* The print-shop note under the header (Bless): the poster's own paper and quiet ink. */
|
||||
.print-hint {
|
||||
flex: none;
|
||||
margin: 0;
|
||||
padding: 6px 20px;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
color: #5f5849;
|
||||
background: #f7f4ec;
|
||||
border-bottom: 1px solid #e3dccb;
|
||||
}
|
||||
|
||||
.wall-canvas {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
import { wallD3 } from './wallD3.js'
|
||||
import { wallGrid } from './wallLod.js'
|
||||
import { blessingFor, wrapText } from './blessings.js'
|
||||
import { lightPhoto, fullPhoto } from './photoUrl.js'
|
||||
import { cardText, PAPER, NAME_INK, VERSE_INK, REF_INK, PHOTO_BG } from './blessPoster.js'
|
||||
|
||||
// The print's sans (blessPoster SANS), for the names and references drawn on the canvas.
|
||||
|
|
@ -289,7 +290,7 @@ export class WallCanvas {
|
|||
const verseH = T.verse ? T.verse.lines.length * vFs * ct.verseLine + ct.refGapPt * pt + rFs * 1.2 : 0
|
||||
const m = ct.imgMarginIn * px
|
||||
const imgY = R.y + pad + nameH + m, imgH = Math.max(0, R.h - 2 * pad - nameH - verseH - 2 * m)
|
||||
const url = g.imageUrl, cached = url && this.images.get(url)
|
||||
const url = lightPhoto(g.imageUrl), cached = url && this.images.get(url)
|
||||
if (cached && cached.ok) {
|
||||
cached.used = performance.now()
|
||||
const im = cached.img, ar = pw(im) / ph(im) || 1, box = iw / (imgH || 1)
|
||||
|
|
@ -342,7 +343,7 @@ export class WallCanvas {
|
|||
ctx.fillStyle = '#fff'; ctx.fillRect(x, y, w, h)
|
||||
ctx.lineWidth = 0.5; ctx.strokeStyle = '#dbdbdb'; ctx.strokeRect(x, y, w, h)
|
||||
const imgY = y + h * 0.18, imgH = h * 0.5
|
||||
const url = g.imageUrl
|
||||
const url = lightPhoto(g.imageUrl)
|
||||
const cached = url && this.images.get(url)
|
||||
if (cached && cached.ok) {
|
||||
cached.used = performance.now()
|
||||
|
|
@ -472,7 +473,9 @@ export class WallCanvas {
|
|||
rec.ok = true; this.loading--; this.request(); this.load([])
|
||||
})
|
||||
}
|
||||
img.onerror = () => { this.loading--; this.load([]) }
|
||||
// A resized copy that fails (photoUrl.js) is retried once from the original, under the same key.
|
||||
const full = fullPhoto(u)
|
||||
img.onerror = () => { if (full && img.src !== full) { img.src = full; return } this.loading--; this.load([]) }
|
||||
img.src = u
|
||||
}
|
||||
if (this.images.size > IMG_CACHE) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"type": "monolithic",
|
||||
"label": "Wall of People Groups",
|
||||
"mobile": "desktop-only",
|
||||
"note": "Monolithic composite (capability 3): ONE root .vue nests the zoomable d3 wall, its cards, and the prayer and comments dialogs. index.js registers exactly ONE tag (wall-of-people-groups); none of the inner components is independently embeddable.",
|
||||
"config": {
|
||||
"pinHint": false
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN",
|
||||
"integrity": "sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -676,8 +676,8 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1134,7 +1134,7 @@
|
|||
"bundle": "posterverse",
|
||||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"output": "dx-maps/posterverse/posterverse.js",
|
||||
"integrity": "sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg",
|
||||
"integrity": "sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT",
|
||||
"elements": [
|
||||
"posterverse-app"
|
||||
],
|
||||
|
|
@ -1159,7 +1159,7 @@
|
|||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./posterverse/posterverse/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1537,7 +1537,7 @@
|
|||
"bundle": "wall-of-people-groups",
|
||||
"scriptUrl": "./wall-of-people-groups/wall-of-people-groups.js",
|
||||
"output": "dx-maps/wall-of-people-groups/wall-of-people-groups.js",
|
||||
"integrity": "sha384-EQcPfsC0SN3qR+HvILq9491mHiDQSWOfhK0SVrvNSRaZzQ8hqYlZiy5/fmaiJKNF",
|
||||
"integrity": "sha384-L+Eq7fXGEJ7FNkslOlTi/CQkeKIK45tkAUvi4LYNceCJn4+/sOVvjrmP3sDWiYor",
|
||||
"elements": [
|
||||
"wall-of-people-groups"
|
||||
],
|
||||
|
|
@ -1547,6 +1547,7 @@
|
|||
"profile": "wall-of-people-groups",
|
||||
"stage": "experimental",
|
||||
"label": "Wall of People Groups",
|
||||
"mobile": "desktop-only",
|
||||
"file": "wall-of-people-groups.vue",
|
||||
"description": "Every Doxa people group as a card on one zoomable prayer wall",
|
||||
"element": "wall-of-people-groups",
|
||||
|
|
@ -1556,7 +1557,7 @@
|
|||
"scriptUrl": "./wall-of-people-groups/wall-of-people-groups.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./wall-of-people-groups/wall-of-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./wall-of-people-groups/wall-of-people-groups.js\" integrity=\"sha384-EQcPfsC0SN3qR+HvILq9491mHiDQSWOfhK0SVrvNSRaZzQ8hqYlZiy5/fmaiJKNF\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<wall-of-people-groups profile-config='{\"profile\":\"wall-of-people-groups\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></wall-of-people-groups>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./wall-of-people-groups/wall-of-people-groups.js\" integrity=\"sha384-L+Eq7fXGEJ7FNkslOlTi/CQkeKIK45tkAUvi4LYNceCJn4+/sOVvjrmP3sDWiYor\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<wall-of-people-groups profile-config='{\"profile\":\"wall-of-people-groups\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></wall-of-people-groups>"
|
||||
},
|
||||
"bundle": "wall-of-people-groups"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-FnguKP+Bq4bBTIeZXAcrCZsjqGJgt4NidtTpzk4T8nqwRdsfYvVqDW0va2OBKNKK" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -655,7 +655,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN",
|
||||
"integrity": "sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -676,8 +676,8 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-nicLlUWomTwiEtwoleUi6gQGVFdE5yuf7AeaNi8++vR660dosrGmIfHJVBGKjizN\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- MapLibre engine (the default), fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.js\" integrity=\"sha384-5+cfbwT0iiub6VsQAdn6yz16nr6sDiQoHx6tm4O8OVYXHYOxcffFmCJBL0dgdvGp\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://cdn.jsdelivr.net/npm/maplibre-gl@5.24.0/dist/maplibre-gl.css\" integrity=\"sha384-uTttxo/aOKbdE5RlD/SPzSDoDmNvGlUYPjONi2MN/b7c9HPSvW07OIuyP7uL6jxK\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl\" crossorigin=\"anonymous\"></script>\n<!-- MapLibre draws this map and needs no token. For Mapbox, paste this map's embed.scriptMapbox from manifest.json instead: it sets \"provider\":\"mapbox\" and preloads the Mapbox engine; fill \"tk\" with your token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>",
|
||||
"scriptMapbox": "<!-- Mapbox engine, fetched early -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<link rel=\"preload\" as=\"style\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css\" integrity=\"sha384-rp1X/jJ9MpWPef9OimfXhOaOc4Gzs87yQvF+ajwY6X2H4PTeHNycNlLWiWvj7ehV\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-I6f5yCRr5h/rwI4dKI1ljwLf3Q8ANzROujNZtzE1N/KvriOXz1ecmhKDljJnpLcl\" crossorigin=\"anonymous\"></script>\n<!-- Mapbox draws this map: fill \"tk\" with your Mapbox token. -->\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"provider\":\"mapbox\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1134,7 +1134,7 @@
|
|||
"bundle": "posterverse",
|
||||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"output": "dx-maps/posterverse/posterverse.js",
|
||||
"integrity": "sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg",
|
||||
"integrity": "sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT",
|
||||
"elements": [
|
||||
"posterverse-app"
|
||||
],
|
||||
|
|
@ -1159,7 +1159,7 @@
|
|||
"scriptUrl": "./posterverse/posterverse.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./posterverse/posterverse/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./posterverse/posterverse.js\" integrity=\"sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<posterverse-app profile-config='{\"profile\":\"posterverse\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></posterverse-app>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1537,7 +1537,7 @@
|
|||
"bundle": "wall-of-people-groups",
|
||||
"scriptUrl": "./wall-of-people-groups/wall-of-people-groups.js",
|
||||
"output": "dx-maps/wall-of-people-groups/wall-of-people-groups.js",
|
||||
"integrity": "sha384-EQcPfsC0SN3qR+HvILq9491mHiDQSWOfhK0SVrvNSRaZzQ8hqYlZiy5/fmaiJKNF",
|
||||
"integrity": "sha384-L+Eq7fXGEJ7FNkslOlTi/CQkeKIK45tkAUvi4LYNceCJn4+/sOVvjrmP3sDWiYor",
|
||||
"elements": [
|
||||
"wall-of-people-groups"
|
||||
],
|
||||
|
|
@ -1547,6 +1547,7 @@
|
|||
"profile": "wall-of-people-groups",
|
||||
"stage": "experimental",
|
||||
"label": "Wall of People Groups",
|
||||
"mobile": "desktop-only",
|
||||
"file": "wall-of-people-groups.vue",
|
||||
"description": "Every Doxa people group as a card on one zoomable prayer wall",
|
||||
"element": "wall-of-people-groups",
|
||||
|
|
@ -1556,7 +1557,7 @@
|
|||
"scriptUrl": "./wall-of-people-groups/wall-of-people-groups.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./wall-of-people-groups/wall-of-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./wall-of-people-groups/wall-of-people-groups.js\" integrity=\"sha384-EQcPfsC0SN3qR+HvILq9491mHiDQSWOfhK0SVrvNSRaZzQ8hqYlZiy5/fmaiJKNF\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<wall-of-people-groups profile-config='{\"profile\":\"wall-of-people-groups\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></wall-of-people-groups>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./wall-of-people-groups/wall-of-people-groups.js\" integrity=\"sha384-L+Eq7fXGEJ7FNkslOlTi/CQkeKIK45tkAUvi4LYNceCJn4+/sOVvjrmP3sDWiYor\" crossorigin=\"anonymous\"></script>\n<!-- provider: \"maplibre\" is the default; change it to \"mapbox\" and fill tk to use Mapbox. -->\n<wall-of-people-groups profile-config='{\"profile\":\"wall-of-people-groups\",\"provider\":\"maplibre\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></wall-of-people-groups>"
|
||||
},
|
||||
"bundle": "wall-of-people-groups"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <posterverse-app> custom element. -->
|
||||
<script src="../../posterverse.js" integrity="sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg" crossorigin="anonymous"></script>
|
||||
<script src="../../posterverse.js" integrity="sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <posterverse-app> custom element. -->
|
||||
<script src="../posterverse.js" integrity="sha384-cUPtOfPEnuDQSMNh2SpAT6ndNhpj+lXDHzCW+a4jjjGMLlnhjWEilsirlD9vqYZg" crossorigin="anonymous"></script>
|
||||
<script src="../posterverse.js" integrity="sha384-kAWi98zRQBcoK3x24F/INIfOqevCKR4xsEjrEqFHXGeOEJKAH3AeCTQhwNo23cvT" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <wall-of-people-groups> custom element. -->
|
||||
<script src="../wall-of-people-groups.js" integrity="sha384-xeoAo3ynd4I/sXEFRRCegzqsJr+yCWWpB+Y6CI561wDJ0WxSvw9Vd1LAccOPYUCi" crossorigin="anonymous"></script>
|
||||
<script src="../wall-of-people-groups.js" integrity="sha384-L+Eq7fXGEJ7FNkslOlTi/CQkeKIK45tkAUvi4LYNceCJn4+/sOVvjrmP3sDWiYor" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
(function () {
|
||||
var slot = document.getElementById('slot');
|
||||
var status = document.getElementById('status');
|
||||
var BASE_CONFIG = {"pinHint":false,"profile":"wall-of-people-groups","dataSource":"pray-tools","instanceId":"wall-of-people-groups-wall-of-people-groups","assetsBase":"../../assets"};
|
||||
var BASE_CONFIG = {"pinHint":false,"mobile":"desktop-only","mobileLabel":"Wall of People Groups","profile":"wall-of-people-groups","dataSource":"pray-tools","instanceId":"wall-of-people-groups-wall-of-people-groups","assetsBase":"../../assets"};
|
||||
// MapLibre map pages AND shell pages (app-shell / nested-mfe-spa) need NO token:
|
||||
// the ladder below is skipped entirely and the element mounts immediately.
|
||||
// (A leaf whose engine is MapLibre at RUNTIME joins them — see PROVIDER below.)
|
||||
|
|
|
|||
Loading…
Reference in a new issue