merge main (landing 36 carried the doc's final version)

This commit is contained in:
Doxa Maps 2026-09-28 00:31:41 +00:00
commit 9644ea810f
98 changed files with 971 additions and 412 deletions

View file

@ -2,3 +2,15 @@
# on the host page; never bake into the IIFE bundle.
VITE_MAPBOX_TOKEN=pk.your_dev_token_here
VITE_API_BASE_URL=https://pray.doxa.life
# Follow a shared branch while `bun run dev` runs (internal/dev-sync-plugin.mjs): fetch every N seconds and
# fast-forward when this checkout is on that branch with no local edits; otherwise only report it at
# /api/dev-sync. DX_SYNC_REMOTE is a remote name (origin) or a repo URL; leave it unset to turn this off.
# DX_SYNC_REMOTE=origin
# DX_SYNC_BRANCH=main
# DX_SYNC_INTERVAL=5
# PocketBase for plugins (internal/backend-dev-plugin.mjs): `bun run dev` downloads the pinned binary once
# and serves it at /api/pb, data in .pb/dev. DX_PB_URL uses a shared PocketBase instead of a local one.
# DX_PB_PORT=8090
# DX_PB_URL=

2
.gitignore vendored
View file

@ -148,3 +148,5 @@ data-private/
# Local plugin backends (backend/<name>/) — the compiled binaries are rebuilt from source, never committed.
/backend/bin/
# The local PocketBase's data (`bun run dev`, internal/backend-dev-plugin.mjs): per laptop, never committed.
/.pb/

View file

@ -705,6 +705,8 @@ The studio is a plugin like any other: `plugin-designs/plugin-studio/plugin-stud
their browser within seconds, with no rebuild. Add OIDC settings and it puts a "Sign in with *your
provider*" page in front of everything, open only to the groups you allow. Recipe and settings:
[deployment/cloud/](./deployment/cloud/README.md).
Working from your own laptop alongside the team (following the shared branch, the team's PocketBase):
[documentation/HOWTO-join-the-table.md](./documentation/HOWTO-join-the-table.md).
---

View file

@ -36,6 +36,24 @@ ARG PB_SHA256=9042ec818570e79c3628dadcd0a756c1496d9e1173918ec409d133c02f82e5fa
RUN curl -fsSL -o /tmp/pb.zip "https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip" \
&& echo "${PB_SHA256} /tmp/pb.zip" | sha256sum -c - \
&& unzip -q /tmp/pb.zip pocketbase -d /usr/local/bin && rm /tmp/pb.zip && chmod 755 /usr/local/bin/pocketbase
# PocketBase team sign-in gate (a JS hook), baked here and pinned: the ONLY server-side hook that runs, in pb-dev.
# It lives in the image, never in the pulled repo, so a plugin writer's push can't change what it lets in.
# Changing it = edit these lines AND the SHA-256 below, then redeploy the image (an admin act).
RUN mkdir -p /app/pb_hooks_gate && printf '%s\n' \
'// Team sign-in gate: only members of OIDC_ALLOWED_GROUPS (the groups claim from the identity provider) may sign in here.' \
'// Baked into the image by deployment/cloud/Dockerfile and pinned by SHA-256: never read from the pulled repo.' \
'onRecordAuthWithOAuth2Request((e) => {' \
' const allow = ($os.getenv("OIDC_ALLOWED_GROUPS") || "").split(",").map((s) => s.trim()).filter((s) => s)' \
' const raw = (e.oAuth2User && e.oAuth2User.rawUser) || {}' \
' const groups = []' \
' if (raw.groups) for (let i = 0; i < raw.groups.length; i++) groups.push(String(raw.groups[i]))' \
' if (!allow.length || !groups.some((g) => allow.indexOf(g) >= 0)) {' \
' throw new ForbiddenError("This account is not in a group allowed to use this team backend.")' \
' }' \
' e.next()' \
'}, "users")' \
> /app/pb_hooks_gate/team-gate.pb.js \
&& echo "2987055ba6067fc30d8162608da21c6c2b691fb6897a46d10b7075271a38f13d /app/pb_hooks_gate/team-gate.pb.js" | sha256sum -c -
RUN printf '%s\n' \
'#!/bin/bash' \
'set -u; export GIT_TERMINAL_PROMPT=0' \

View file

@ -51,7 +51,7 @@ With the sign-in on, the container also runs PocketBase and can publish a produc
| Route | Who | What |
|---|---|---|
| `/` | signed-in | the dev server (Plugin Studio, hot reload) |
| `/pb/` | signed-in (its `/_/` dashboard: `OIDC_ADMIN_GROUPS` only) | PocketBase **dev** |
| `/pb/` | signed-in (its `/_/` dashboard: `OIDC_ADMIN_GROUPS` only). With `PB_OIDC_CLIENT_SECRET`, its `/api/` is public and PocketBase signs people in itself (see below); `_superusers` and system collections stay admin-only | PocketBase **dev**, the team's shared backend |
| `/api-prod/api/` | **public** | PocketBase **prod**'s API; its dashboard is never exposed |
| `/cdn/dx-maps/` | **public** | the last published build: `manifest.json` at a stable URL, CORS open for embeds |
| `POST /admin/build` · `GET /admin/status` | `OIDC_ADMIN_GROUPS` only | build and publish the pulled commit |
@ -65,6 +65,7 @@ there. Only then does it swap the new build in.
|---|---|
| `OIDC_ADMIN_GROUPS` | comma-separated groups allowed to build and to open PocketBase's dashboard |
| `PB_SUPERUSER_EMAIL`, `PB_SUPERUSER_PASSWORD` | PocketBase's superuser, set on start in both instances |
| `PB_OIDC_CLIENT_SECRET` (+ `PB_OIDC_CLIENT_ID`, default `dx-maps-pb-dev`) | turns pb-dev into the team backend: laptops use it directly (`DX_PB_URL=https://<host>/pb`), and people sign in to PocketBase through the same OIDC provider, with its own client whose redirect URI is `https://<host>/pb/api/oauth2-redirect`. Only members of `OIDC_ALLOWED_GROUPS` get in (a sign-in hook baked into the image and pinned; the repo's own hooks never run). Password sign-in is off, new collections are superuser-only until a migration opens them, and data never leaves `/data` |
| `PUBLIC_API_BASE` | the public API URL written into the build's `runtime-config.js` (e.g. `https://<host>/api-prod`) |
| `BUILD_MAX_OLD_SPACE_MB` | Node heap cap for a build (default `1536`) |
| `RUDDER_ENGINE` | `1` runs Rudder's voice-to-text engine here, fed by the browser's microphone (about 1 GB more; its runtime and model, ~742 MB, are baked into the image at `/opt/rudder`, and `/data/rudder` wins when it holds a model). The site serves at once; Rudder shows "starting" until its engine is built, then the dev server restarts once to start it. Give the container at least 2 vCPUs, or transcription falls behind speech |

View file

@ -1,8 +1,10 @@
// admin.mjs — the container's internal router (127.0.0.1:5175), behind oauth2-proxy.
// /cdn/* the last good build (/data/cdn/current), PUBLIC (oauth2-proxy skips auth here)
// /api-prod/* PocketBase PROD, PUBLIC; only /api/ passes, never the /_/ dashboard
// /pb/* PocketBase DEV, signed-in; its /_/ dashboard only for OIDC_ADMIN_GROUPS
// /pb/* PocketBase DEV, signed-in; its /_/ dashboard only for OIDC_ADMIN_GROUPS. With PB_OIDC_CLIENT_SECRET,
// its /api/ is PUBLIC (PocketBase signs people in itself), except _superusers and _system collections
// /admin/build POST: start a build (OIDC_ADMIN_GROUPS only); /admin/status GET
// /admin/pb-signin-check a page that signs in to the team PocketBase and shows who it thinks you are
// Groups come from oauth2-proxy's X-Forwarded-Groups, which it sets on signed-in routes only.
import { spawn } from 'node:child_process'
import { existsSync, readFileSync, statSync } from 'node:fs'
@ -26,6 +28,9 @@ async function proxy(req, url, prefix, port) {
Bun.serve({
hostname: '127.0.0.1',
port: 5175,
// No idle cut-off: PocketBase's realtime stream (/pb/api/realtime) sits quiet while someone signs in in the
// popup, and Bun's default (10 s) closed it before the sign-in result could arrive.
idleTimeout: 0,
async fetch(req) {
const url = new URL(req.url)
const p = url.pathname
@ -42,8 +47,13 @@ Bun.serve({
}
if (p.startsWith('/pb/')) {
if (p.startsWith('/pb/_/') && !isAdmin(req)) return text('the PocketBase dashboard is for admins', 403)
// The superuser (and every _system collection) is for admins only. oauth2-proxy never opens these
// paths to the public (its skip routes exclude names starting with _), so the groups header is its own.
if (p.startsWith('/pb/api/collections/_') && !isAdmin(req)) return text('for admins only', 403)
return proxy(req, url, '/pb/', 8090)
}
// A one-click check of the team PocketBase sign-in (behind the site sign-in like every /admin/ path).
if (p === '/admin/pb-signin-check') return new Response(Bun.file('/app/repo/deployment/cloud/pb-signin-check.html'), { headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' } })
if (p === '/admin/status') return Response.json(last)
if (p === '/admin/build') {
if (req.method !== 'POST') return text('POST only', 405)

View file

@ -102,13 +102,34 @@ for inst in dev prod; do
&& echo "[pb-$inst] superuser set" || echo "[pb-$inst] superuser upsert failed"
fi
done
# Server-side JS hooks OFF: point --hooksDir at a path that never exists, so a pb_hooks/ folder
# added to the repo can't run code in either instance (v1 has no per-plugin isolation for hooks).
# Server-side JS hooks from the REPO are OFF: --hooksDir never points into the pulled tree, so a pb_hooks/
# folder pushed by a plugin writer can't run code (v1 has no per-plugin isolation for hooks). prod runs
# none; dev runs only the team sign-in gate BAKED INTO THE IMAGE (Dockerfile, SHA-256 pinned).
NOHOOKS=/var/empty/pb_hooks_disabled
pocketbase serve --http 127.0.0.1:8090 --dir /data/pb-dev --migrationsDir "$MIG" --hooksDir "$NOHOOKS" &
GATE=/app/pb_hooks_gate
DEV_HOOKS=$NOHOOKS; [ -f "$GATE/team-gate.pb.js" ] && DEV_HOOKS=$GATE
pocketbase serve --http 127.0.0.1:8090 --dir /data/pb-dev --migrationsDir "$MIG" --hooksDir "$DEV_HOOKS" &
pocketbase serve --http 127.0.0.1:8091 --dir /data/pb-prod --migrationsDir "$MIG" --hooksDir "$NOHOOKS" &
bun /app/repo/deployment/cloud/admin.mjs &
# TEAM PB: laptops reach pb-dev's API WITHOUT the site sign-in (DX_PB_URL=https://<host>/pb), and PocketBase
# itself signs people in through the same OIDC provider, members of OIDC_ALLOWED_GROUPS only (the baked
# gate). Fails CLOSED: /pb/api/ is opened only when the gate is in place AND the OIDC setup succeeded;
# otherwise pb-dev stays behind the site sign-in, as before. /pb/_/ (dashboard) and _superusers never open.
PB_PUBLIC=()
if [ -n "${PB_OIDC_CLIENT_SECRET:-}" ]; then
for _ in $(seq 60); do curl -s -o /dev/null http://127.0.0.1:8090/api/health && break; sleep 0.5; done
PB_APP_URL="${PB_APP_URL:-$(printf '%s' "$OIDC_REDIRECT_URL" | sed -E 's#^([a-z]+://[^/]+).*#\1#')/pb}"
if [ "$DEV_HOOKS" = "$GATE" ] && PB_APP_URL="$PB_APP_URL" bun /app/repo/deployment/cloud/pb-oidc.mjs; then
PB_PUBLIC=(--skip-auth-route='^/pb/api/(health|realtime|oauth2-redirect|batch)$'
--skip-auth-route='^/pb/api/files/'
--skip-auth-route='^/pb/api/collections/[^_/][^/]*/')
echo "[pb-dev] team API open at /pb/api/ (sign-in through PocketBase; dashboard stays gated)"
else
echo "[pb-dev] team sign-in NOT configured: /pb/ stays behind the site sign-in" >&2
fi
fi
VITE_HOST=127.0.0.1 VITE_PORT=5174 bun x vite --config "$CONFIG" &
oauth2-proxy \
--provider=oidc \
@ -128,6 +149,7 @@ oauth2-proxy \
--upstream=http://127.0.0.1:5175/admin/ \
--skip-auth-route='^/cdn/' \
--skip-auth-route='^/api-prod/api/' \
"${PB_PUBLIC[@]}" \
--http-address="0.0.0.0:$PORT" \
--reverse-proxy=true \
--cookie-secure=true \

View file

@ -0,0 +1,41 @@
// pb-oidc.mjs — make the team PocketBase (pb-dev) sign people in through the team's OIDC provider.
// Run by entry.sh at every start, against PocketBase on localhost, as the superuser (env, never printed).
// users: sign-in ONLY through OIDC (password sign-in off); the group check is the image's baked hook.
// The client secret comes from the environment; nothing here, or in PocketBase's data, is in git.
const env = process.env
const PB = env.PB_LOCAL_URL || 'http://127.0.0.1:8090'
const need = (k) => env[k] || (console.error(`[pb-oidc] ${k} is not set: team sign-in NOT configured`), process.exit(1))
const call = async (method, path, body, token) => {
const r = await fetch(PB + path, { method, headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: token } : {}) }, body: body && JSON.stringify(body) })
const j = await r.json().catch(() => ({}))
if (!r.ok) throw new Error(`${method} ${path}: ${r.status} ${j.message || ''}`)
return j
}
const issuer = need('OIDC_ISSUER').replace(/\/$/, '')
const disc = env.PB_OIDC_DISCOVERY_JSON ? JSON.parse(env.PB_OIDC_DISCOVERY_JSON)
: await (await fetch(issuer + '/.well-known/openid-configuration')).json()
const { token } = await call('POST', '/api/collections/_superusers/auth-with-password',
{ identity: need('PB_SUPERUSER_EMAIL'), password: need('PB_SUPERUSER_PASSWORD') })
await call('PATCH', '/api/collections/users', {
passwordAuth: { enabled: false, identityFields: ['email'] },
oauth2: {
enabled: true,
mappedFields: { id: '', name: 'name', username: '', avatarURL: '' },
providers: [{
name: 'oidc',
displayName: env.OIDC_DISPLAY_NAME || 'Team sign-in',
clientId: env.PB_OIDC_CLIENT_ID || 'dx-maps-pb-dev',
clientSecret: need('PB_OIDC_CLIENT_SECRET'),
authURL: disc.authorization_endpoint,
tokenURL: disc.token_endpoint,
userInfoURL: disc.userinfo_endpoint,
pkce: true,
extra: {},
}],
},
}, token)
if (env.PB_APP_URL) await call('PATCH', '/api/settings', { meta: { appURL: env.PB_APP_URL } }, token)
console.log(`[pb-oidc] users sign in through ${issuer} only (password sign-in off)`)

View file

@ -0,0 +1,52 @@
<!doctype html>
<!-- One-click check of the team PocketBase sign-in (/admin/pb-signin-check, behind the site sign-in).
The same flow as the PocketBase SDK's authWithOAuth2: subscribe to @oauth2 over /pb/api/realtime, open the
provider in a popup, exchange the code. The token is shown as a result only and never stored. -->
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Team PocketBase sign-in check</title>
<style>body{font:16px/1.5 system-ui,sans-serif;max-width:40rem;margin:3rem auto;padding:0 1rem}button{font:inherit;padding:.6rem 1.2rem;cursor:pointer}#out{margin-top:1.5rem;padding:1rem;border-radius:.5rem;background:#f3f3f3;white-space:pre-wrap}.ok{background:#e6f6ea!important}.no{background:#fdecec!important}</style>
<h1>Team PocketBase sign-in check</h1>
<p>Signs you in to the team PocketBase (<code>/pb</code>) through the team account, and shows who it thinks you are. Nothing is stored in this page.</p>
<button id="go">Sign in to the team PocketBase</button>
<div id="out">Not tried yet.</div>
<script type="module">
const PB = location.origin + '/pb'
const out = document.getElementById('out')
const show = (text, cls) => { out.textContent = text; out.className = cls || '' }
document.getElementById('go').onclick = async () => {
const popup = window.open('', 'pb-oauth2', 'width=520,height=720') // opened in the click, so it is not blocked
show('Connecting…')
try {
const methods = await (await fetch(PB + '/api/collections/users/auth-methods')).json()
const provider = (methods.oauth2?.providers || []).find((p) => p.name === 'oidc')
if (!provider) throw new Error('The team PocketBase has no team sign-in configured.')
const es = new EventSource(PB + '/api/realtime')
const clientId = await new Promise((ok, fail) => {
es.addEventListener('PB_CONNECT', (e) => ok(JSON.parse(e.data).clientId))
es.onerror = () => fail(new Error('Could not open the realtime connection.'))
})
const sub = await fetch(PB + '/api/realtime', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientId, subscriptions: ['@oauth2'] }) })
if (!sub.ok) throw new Error('Could not subscribe to the sign-in result (' + sub.status + ').')
const redirectURL = PB + '/api/oauth2-redirect'
const url = new URL(provider.authURL + encodeURIComponent(redirectURL))
url.searchParams.set('state', clientId)
show('Finish signing in in the popup…')
popup.location.href = url.toString()
const result = await new Promise((ok) => es.addEventListener('@oauth2', (e) => ok(JSON.parse(e.data))))
es.close()
try { popup.close() } catch {}
if (result.state !== clientId) throw new Error('The sign-in state did not match; try again.')
if (result.error || !result.code) throw new Error('The team account provider said: ' + (result.error || 'no code'))
const r = await fetch(PB + '/api/collections/users/auth-with-oauth2', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ provider: 'oidc', code: result.code, codeVerifier: provider.codeVerifier, redirectURL }) })
const j = await r.json()
if (!r.ok) return show('REFUSED by the team PocketBase (' + r.status + '): ' + (j.message || 'no message'), 'no')
const groups = j.meta?.rawUser?.groups
show('Signed in to the team PocketBase as ' + (j.record?.email || j.meta?.email || '(no email)') +
', groups: ' + (Array.isArray(groups) ? groups.join(', ') : '(none)') + (j.meta?.isNew ? '\n(first sign-in: your team user was created)' : ''), 'ok')
} catch (e) {
try { popup.close() } catch {}
show('Did not complete: ' + e.message, 'no')
}
}
</script>

View file

@ -0,0 +1,98 @@
/**
* _composed-tiers.mjs — the ONE place the composition tier is derived from `composes` edges.
*
* Shared on purpose. The generator WRITES this tier into the manifest and check-capability-derived
* CHECKS it, and for a while each held its own copy of the rule. A rule with three ref vocabularies
* and a self-exclusion will not stay identical in two files, and the drift has a specific shape: a
* gate that passes a manifest the generator would refuse to write. One implementation, two callers.
*
* What stays independent is the DATA, which is the half worth duplicating: the generator derives from
* the profiles it is about to emit, the gate rebuilds the same edges from the <profile>.meta.json files
* on disk and feeds them to this function against the PUBLISHED manifest. So a manifest that no longer
* matches its own sources still fails, while the rule itself cannot fork.
*
* Imports nothing — pure over the bundle rows, which is what makes it testable from either side.
*/
/**
* Derive the composition tier from the `composes` edges, and refuse to disagree with an author.
*
* ★ WHY DERIVE AT ALL (Driver, 2026-09-27). Tiers 3-5 were AUTHORED ONLY — discover.mjs infers just
* `single` and `parameterized`, so a composite with no meta.json shipped as capability 1. That is not
* hypothetical: research-dashboard did exactly that while nesting ten views, and the warning in
* detectProfileType exists because of it. A missing file is indistinguishable from a deliberate choice.
*
* THE RULE, measured against all 25 bundles before it was written: a profile that composes anything is
* cap-4 (nested-elements-mfe); if any of the things it composes is itself cap-4, it is cap-5
* (nested-mfe-spa). Keyed per PROFILE, and refs are accepted in BOTH published forms — 'bundle/profile'
* (doxa-maps-spa) and a bare 'bundle' (plugin-studio). Getting either of those wrong is not academic:
* keying on the bundle derived 11 false tiers, and resolving only the slashed form demoted plugin-studio
* from 5 to 4. With both handled: 10 composing profiles, 10 agree, 0 disagree.
*
* AN EXPLICIT type STAYS AUTHORITATIVE AND MUST AGREE. It is not overridden — it is CHECKED. A
* declaration that contradicts the structure is the interesting case: either the meta is stale or the
* composes list is, and both are worth a loud build failure rather than a silent pick between them.
*
* An UNRESOLVED ref is reported separately and never silently treated as "not cap-4", because a typo in
* composes and a genuinely non-composite child look identical from here.
*/
export function deriveComposedTiers(bundles) {
const TIER = { 'nested-mfe-spa': 5, 'nested-elements-mfe': 4, monolithic: 3, parameterized: 2, single: 1 }
const byKey = new Map(), byName = new Map(), byElement = new Map()
const reg = (m, k, bundle, type) => { if (!m.has(k)) m.set(k, []); m.get(k).push([bundle, type || null]) }
for (const b of bundles) {
for (const p of b.profiles || []) {
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
reg(byName, b.bundle, b.bundle, p.type)
reg(byName, p.profile, b.bundle, p.type)
if (p.element) reg(byElement, p.element, b.bundle, p.type)
}
for (const e of b.elements || []) reg(byElement, e, b.bundle, null)
}
// A name that covers SEVERAL profiles resolves to the HIGHEST tier among them, and both non-slashed
// vocabularies resolve the same way. They have to: a bare bundle name and that bundle's element tag
// both mean "this bundle", so taking the first profile for one and the highest for the other made
// the answer depend on discovery order. gospel-resources is the case that shows it — four `single`
// leaves and one cap-4 composite in one bundle, so "first" is a coin flip between 1 and 4, and
// losing the 4 silently demotes whoever composes it. Highest is also the truthful reading of a
// whole-bundle ref: nesting a bundle nests the most composed thing in it.
const best = (rows, selfBundle) => {
const others = rows.filter(([b, t]) => b !== selfBundle && t)
if (!others.length) return null
return others.sort((a, z) => (TIER[z[1]] || 0) - (TIER[a[1]] || 0))[0][1]
}
// ★ `composes` SPEAKS THREE VOCABULARIES, and only knowing two of them invents defects.
// Measured on the tree: 'bundle/profile' (doxa-maps-spa), a bare 'bundle' (plugin-studio's first four
// entries) and an ELEMENT TAG (its last three, plus big-picture and stack-demo). Resolving only the
// first two left FIVE refs "unresolved" and reported as possible typos — they were all element tags,
// written correctly by their authors. The data was right and the resolver was short.
//
// ★ AND A SELF-REFERENCE IS AN INTERNAL CHILD, NOT A NESTED PLUGIN. big-picture composes
// 'bp-research-header', which is its OWN element (src/components/BpResearchHeader.vue). Resolving that
// to the bundle registering it — itself, cap-4 — made big-picture look like it composes a cap-4 and
// promoted it to cap-5. Excluding self is what keeps "nests other plugins" from meaning "has parts".
const UNRESOLVED = Symbol('unresolved')
const resolve = (ref, selfBundle) => {
if (ref.includes('/')) {
if (!byKey.has(ref)) return UNRESOLVED
return ref.split('/')[0] === selfBundle ? null : byKey.get(ref)
}
if (byName.has(ref)) return best(byName.get(ref), selfBundle)
if (byElement.has(ref)) return best(byElement.get(ref), selfBundle)
return UNRESOLVED
}
const conflicts = [], unresolved = []
for (const b of bundles) for (const p of b.profiles || []) {
const own = p.composesOwn
if (!own || !own.length) continue
const kinds = own.map((ref) => {
const k = resolve(ref, b.bundle)
if (k === UNRESOLVED) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`)
return k
})
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
if (!p.type) { p.type = derived; continue }
if (p.type !== derived) conflicts.push(`${b.bundle}/${p.profile}: declared tier "${p.type}" disagrees with the "${derived}" its composes edges derive`)
}
return { conflicts, unresolved }
}

View file

@ -18,11 +18,28 @@
* DEV ONLY (`apply: 'serve'`). A production build never starts or bundles a backend.
*/
import { spawn } from 'node:child_process'
import { existsSync } from 'node:fs'
import { existsSync, mkdirSync, writeFileSync, rmSync, chmodSync, renameSync } from 'node:fs'
import { createHash } from 'node:crypto'
import { connect } from 'node:net'
import { inflateRawSync } from 'node:zlib'
import { resolve } from 'node:path'
// name → how to run it. `route` is proxied to `port` on 127.0.0.1.
export const DEV_BACKENDS = [
// PocketBase, the backend for plugins that need one: the SAME pinned version as the cloud container
// (deployment/cloud/Dockerfile), SHA-256 from the release's checksums.txt. Downloaded on the first
// `bun run dev` into backend/bin (gitignored); its data lives in .pb/dev (gitignored).
const PB_VERSION = '0.40.4'
const PB_SHA256 = {
linux_amd64: '9042ec818570e79c3628dadcd0a756c1496d9e1173918ec409d133c02f82e5fa',
linux_arm64: '86095bf8ed9345954f0d2bf0a5fb9b57584ae60b77ebf3b6cd23a8003a3fd418',
darwin_amd64: '052906521f09f6f23405cd804c930d2b7a1f8eee06d39b85723b5054b2acb4e4',
darwin_arm64: 'eeb619ea4f8a06421daedb946d133bed269fea334a760941d147f76befc25ebc',
}
// name → how to run it. `route` is proxied to `port` on 127.0.0.1, or to `remote` when that is set.
// `env` is vite's loadEnv (so .env.local counts), falling back to process.env.
export function devBackends(env = process.env) {
const pbPort = Number(env.DX_PB_PORT || 8090)
return [
{
name: 'rudder-engine',
bin: 'backend/bin/rudder-engine',
@ -33,13 +50,92 @@ export const DEV_BACKENDS = [
// This server is SUPPOSED to run the engine (a server deployment with the engine switched on): while it
// is down, the plugin says "not running yet" instead of "runs on your own computer".
expected: () => process.env.RUDDER_ENGINE === '1' || process.env.RUDDER_AUDIO === 'browser',
// RUDDER_ENGINE=0 (a server where Rudder is laptop-only, the Driver 2026-09-27): never start it, even if a
// binary built by an earlier engine-on deploy is still there — it would offer to record a server's mic.
disabled: () => process.env.RUDDER_ENGINE === '0',
},
]
{
// Hooks off (a hooks dir that never exists): only the migrations in git shape the schema, as in the cloud.
// DX_PB_URL points this laptop at a shared PocketBase instead (e.g. the cloud pb-dev); none starts here.
name: 'pocketbase',
bin: 'backend/bin/pocketbase',
args: ['serve', '--http', `127.0.0.1:${pbPort}`, '--dir', '.pb/dev', '--migrationsDir', 'backend/pocketbase/pb_migrations', '--hooksDir', '.pb/hooks-off'],
build: 'it downloads on the next `bun run dev` (or set DX_PB_URL)',
fetch: fetchPocketBase,
portEnv: 'DX_PB_PORT',
route: '/api/pb',
rewrite: (p) => p.replace(/^\/api\/pb/, '') || '/',
port: pbPort,
remote: env.DX_PB_URL || '',
offline: (res) => {
res.writeHead(503, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({ status: 503, message: 'PocketBase is not running on this computer (yet). See the dev server log.' }))
},
},
]
}
async function fetchPocketBase(root, logger) {
const plat = { 'linux-x64': 'linux_amd64', 'linux-arm64': 'linux_arm64', 'darwin-x64': 'darwin_amd64', 'darwin-arm64': 'darwin_arm64' }[`${process.platform}-${process.arch}`]
if (!plat) {
logger.warn(`[pocketbase] no pinned build for ${process.platform}-${process.arch}: put PocketBase ${PB_VERSION} at backend/bin/pocketbase, or set DX_PB_URL`)
return false
}
const name = `pocketbase_${PB_VERSION}_${plat}.zip`
const dir = resolve(root, 'backend/bin')
const part = resolve(dir, `.pocketbase.part`)
logger.info(`[pocketbase] downloading ${name} (first run only)`)
try {
mkdirSync(dir, { recursive: true })
const r = await fetch(`https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/${name}`)
if (!r.ok) throw new Error(`HTTP ${r.status}`)
const buf = Buffer.from(await r.arrayBuffer())
const sha = createHash('sha256').update(buf).digest('hex')
if (sha !== PB_SHA256[plat]) throw new Error(`checksum mismatch (${sha}): refusing to use it`)
writeFileSync(part, unzipOne(buf, 'pocketbase')) // not every laptop has `unzip`
chmodSync(part, 0o755)
renameSync(part, resolve(dir, 'pocketbase'))
return true
} catch (e) {
logger.warn(`[pocketbase] download failed (${e.message}); /api/pb answers 503 until the next \`bun run dev\``)
return false
} finally {
rmSync(part, { force: true })
}
}
// One file out of a (non-zip64) zip, via its central directory; the zip's SHA-256 was checked before this.
function unzipOne(buf, want) {
const end = buf.lastIndexOf(Buffer.from([0x50, 0x4b, 0x05, 0x06]))
if (end < 0) throw new Error('not a zip')
for (let i = 0, p = buf.readUInt32LE(end + 16); i < buf.readUInt16LE(end + 10); i++) {
const method = buf.readUInt16LE(p + 10), size = buf.readUInt32LE(p + 20)
const nameLen = buf.readUInt16LE(p + 28), local = buf.readUInt32LE(p + 42)
if (buf.toString('utf8', p + 46, p + 46 + nameLen) === want) {
const start = local + 30 + buf.readUInt16LE(local + 26) + buf.readUInt16LE(local + 28)
const data = buf.subarray(start, start + size)
if (method === 8) return inflateRawSync(data)
if (method === 0) return data
throw new Error(`unsupported zip method ${method}`)
}
p += 46 + nameLen + buf.readUInt16LE(p + 30) + buf.readUInt16LE(p + 32)
}
throw new Error(`${want} not in the zip`)
}
// Another `bun run dev` (another worktree) may already hold the port: say so once instead of crash-looping.
const portInUse = (port) => new Promise((ok) => {
const s = connect({ host: '127.0.0.1', port }, () => { s.destroy(); ok(true) })
s.on('error', () => ok(false))
})
// The proxy table for vite's `server.proxy`. SSE (`/events`) streams through unbuffered.
export function devBackendProxy() {
export function devBackendProxy(env = process.env) {
// ws: a backend may take a WebSocket (rudder's /stream carries the browser's microphone on a server deployment).
return Object.fromEntries(DEV_BACKENDS.map((b) => [b.route, { target: `http://127.0.0.1:${b.port}`, changeOrigin: false, ws: true }]))
return Object.fromEntries(devBackends(env).map((b) => [b.route, {
target: b.remote || `http://127.0.0.1:${b.port}`, changeOrigin: !!b.remote, ws: true,
...(b.rewrite ? { rewrite: b.rewrite } : {}),
}]))
}
const REG = (globalThis.__dxDevBackends ||= { procs: new Map(), exitHooked: false, stopping: false })
@ -52,7 +148,7 @@ function stopAll() {
function start(root, b, logger, restarts = 0) {
const tag = `[${b.name}]`
const child = spawn(resolve(root, b.bin), [], { cwd: root, env: { ...process.env, ...b.env }, stdio: ['ignore', 'pipe', 'pipe'] })
const child = spawn(resolve(root, b.bin), b.args || [], { cwd: root, env: { ...process.env, ...b.env }, stdio: ['ignore', 'pipe', 'pipe'] })
const entry = { child, restarts, logger }
REG.procs.set(b.name, entry)
const out = (d) => String(d).trim().split('\n').forEach((l) => l && entry.logger.info(`${tag} ${l}`))
@ -75,7 +171,8 @@ function start(root, b, logger, restarts = 0) {
logger.info(`${tag} started → ${b.route} on 127.0.0.1:${b.port}`)
}
export function backendDevPlugin(root) {
export function backendDevPlugin(root, env = process.env) {
const backends = devBackends(env)
return {
name: 'dx-backend-dev',
apply: 'serve',
@ -85,9 +182,10 @@ export function backendDevPlugin(root) {
// well-formed answers instead: /events streams ONE status event saying the engine is offline (the
// plugin renders its own "engine not running" state from it), anything else returns an empty JSON
// list. Registered here, so it runs before vite's proxy.
for (const b of DEV_BACKENDS) {
for (const b of backends) {
server.middlewares.use(b.route, (req, res, next) => {
if (isAlive(b.name)) return next()
if (b.remote || isAlive(b.name)) return next()
if (b.offline) return b.offline(res)
const status = { engine: 'offline', expected: !!(b.expected && b.expected()), error: 'The desktop engine is not running.' }
if ((req.url || '').startsWith('/events')) {
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' })
@ -111,17 +209,39 @@ export function backendDevPlugin(root) {
process.once('SIGINT', () => { stopAll(); process.exit(0) })
process.once('SIGTERM', () => { stopAll(); process.exit(0) })
}
for (const b of DEV_BACKENDS) {
for (const b of backends) {
if (b.remote) {
logger.info(`[${b.name}] not started here: ${b.route} → ${b.remote}`)
continue
}
if (isAlive(b.name)) {
REG.procs.get(b.name).logger = logger // log through the restarted server
logger.info(`[${b.name}] still running → ${b.route} (kept across the dev-server restart)`)
continue
}
if (b.disabled && b.disabled()) {
logger.info(`[backend] ${b.name} switched off here (${b.name === 'rudder-engine' ? 'RUDDER_ENGINE=0' : 'disabled'})`)
continue
}
const launch = async () => {
if (b.portEnv && await portInUse(b.port)) {
logger.warn(`[${b.name}] port ${b.port} is already in use (another \`bun run dev\`?): not started. Set ${b.portEnv} to use another port.`)
return
}
if (!REG.stopping && !isAlive(b.name)) start(root, b, logger)
}
if (!existsSync(resolve(root, b.bin))) {
if (b.fetch) {
REG.fetching ||= new Set()
if (REG.fetching.has(b.name)) continue // a vite restart mid-download: the first one finishes it
REG.fetching.add(b.name)
b.fetch(root, logger).then((ok) => { REG.fetching.delete(b.name); if (ok) launch() })
continue
}
logger.warn(`[backend] ${b.name} not built — its plugin will show "engine offline". Build: ${b.build}`)
continue
}
start(root, b, logger)
launch()
}
},
}

View file

@ -21,12 +21,15 @@
* - `composes` is PER-PROFILE at source and HOISTED TO THE BUNDLE in the manifest. Deriving from
* the bundle row applies a composite's edges to its plain sibling leaves: gospel-resources has one
* composite and four single leaves, and all four derived as cap-4. 11 false failures.
* - refs appear in TWO FORMS in the same field: 'bundle/profile' and a bare 'bundle'. Resolving
* only the first demoted plugin-studio from 5 to 4.
* - refs appear in THREE FORMS in the same field: 'bundle/profile', a bare 'bundle', and an ELEMENT
* TAG. Resolving only the first demoted plugin-studio from 5 to 4; not knowing the third left five
* refs "unresolved" and reported as possible typos when all five were correct.
* With both handled: 10 composing profiles, 10 agree, 0 disagree, on the tree as it stands.
*
* An UNRESOLVED ref is REPORTED, never counted as "not cap-4": a typo and a genuine non-composite
* child look identical from here, and quietly treating one as the other is how a tier silently drops.
* An UNRESOLVED ref now FAILS. It was only ever REPORTED because five were outstanding and they turned
* out to be correct data this gate could not read — failing then would have blamed five authors for a
* gap here. At zero, the reasoning inverts: a typo and a genuine non-composite child still look
* identical from here, so the one thing that must not happen is quietly reading one as the other.
*
* Headless, no browser. Exit 0 pass · 1 fail.
*/
@ -34,6 +37,7 @@ import { readFileSync, existsSync } from 'node:fs'
import { resolve, dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { TREE_NAME } from './_tree-name.mjs'
import { deriveComposedTiers } from './_composed-tiers.mjs'
const TAG = 'CAPABILITY-DERIVED'
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
@ -54,36 +58,31 @@ for (const b of bundles) for (const p of b.profiles || []) {
}
// ── 2. a declared tier must agree with the edges it declares ────────────────────────────────────
// Uses the SHARED resolver (internal/_composed-tiers.mjs) rather than a second copy. Two implementations of a rule this
// fiddly — three ref vocabularies and a self-exclusion — would drift, and the drift would show up as a
// gate that passes a manifest the generator would refuse to write. What stays independent is the DATA:
// the gate rebuilds composesOwn from the <profile>.meta.json files on disk and checks the PUBLISHED
// manifest against them, so a manifest that no longer matches its own sources still fails.
const readMeta = (bundle, profile) => {
const f = join(ROOT, 'plugin-designs', bundle, `${profile}.meta.json`)
try { return existsSync(f) ? JSON.parse(readFileSync(f, 'utf8')) : null } catch { return null }
}
const byKey = new Map(), byName = new Map()
for (const b of bundles) for (const p of b.profiles || []) {
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
if (!byName.has(b.bundle)) byName.set(b.bundle, p.type || null)
if (!byName.has(p.profile)) byName.set(p.profile, p.type || null)
}
const resolveRef = (ref) => (ref.includes('/') ? byKey.get(ref) : byName.get(ref))
const unresolved = []
let composing = 0
for (const b of bundles) for (const p of b.profiles || []) {
const meta = readMeta(b.bundle, p.profile)
const own = Array.isArray(meta?.composes) ? meta.composes.map(String).filter(Boolean) : []
if (!own.length) continue
composing++
const kinds = own.map((ref) => { const k = resolveRef(ref); if (k === undefined) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`); return k })
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
if (p.type !== derived) {
fails.push(`${b.bundle}/${p.profile}: declares "${p.type}" but its own composes edges derive "${derived}" — one of the two is stale.`)
}
}
const probe = bundles.map((b) => ({
...b,
profiles: (b.profiles || []).map((p) => {
const meta = readMeta(b.bundle, p.profile)
const own = Array.isArray(meta?.composes) ? meta.composes.map(String).filter(Boolean) : []
if (own.length) composing++
return { ...p, composesOwn: own.length ? own : null }
}),
}))
const { conflicts, unresolved } = deriveComposedTiers(probe)
for (const c of conflicts) fails.push(`${c} — the meta.json or the composes list is stale.`)
for (const u of unresolved) fails.push(`${u}: composes ref resolves to nothing. A ref may be "<bundle>/<profile>", a bare "<bundle>", or a registered element tag.`)
console.log(` · ${checked} profile(s) across ${bundles.length} bundle(s); ${composing} declare composes edges`)
if (unresolved.length) {
console.log(` · ${unresolved.length} composes ref(s) resolve to no known bundle/profile. Reported, NOT treated as "not a composite" — a typo and a plain child look the same from here:`)
for (const u of unresolved) console.log(` ${u}`)
}
if (fails.length) {
console.error(`\n${TAG}: FAIL`)
for (const f of fails) console.error(` ✗ ${f}`)

View file

@ -0,0 +1,32 @@
#!/usr/bin/env node
/**
* check-no-repo-pb-hooks.mjs — no PocketBase hooks (pb_hooks, *.pb.js) may live in the repo.
*
* WHY: the cloud container pulls this repo every few seconds. A PocketBase hook is server-side JS; one pushed
* by any plugin writer would run on the team backend within seconds, which is the rogue-writer hole the
* roundtable test closed. The container never points PocketBase at the repo (--hooksDir is outside the
* pulled tree; the one team sign-in hook is baked into the image and pinned, deployment/cloud/Dockerfile).
* This gate keeps anyone from adding a hooks folder that LOOKS like it would run, or that a later recipe
* change could start running.
*
* HOW: every tracked path; a self-test on every run (a poisoned list must fail), so the gate cannot go blind.
*/
import { execFileSync } from 'node:child_process'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const ROOT = process.env.DOXA_REPO || join(dirname(fileURLToPath(import.meta.url)), '..')
export const offending = (paths) => paths.filter((p) => /(^|\/)pb_hooks(\/|$)/.test(p) || /\.pb\.(js|ts)$/.test(p))
if (offending(['README.md', 'backend/pocketbase/pb_hooks/x.pb.js', 'a/b.pb.ts']).length !== 2) {
console.error('✗ check:no-repo-pb-hooks self-test failed: the matcher went blind'); process.exit(1)
}
const tracked = execFileSync('git', ['ls-files', '-z'], { cwd: ROOT }).toString().split('\0').filter(Boolean)
const bad = offending(tracked)
if (bad.length) {
console.error(`✗ PocketBase hooks in the repo (server-side JS must never ride the live pull):\n${bad.map((p) => ' ' + p).join('\n')}`)
console.error(' The team sign-in hook is baked into the image (deployment/cloud/Dockerfile); anything else needs a design review.')
process.exit(1)
}
console.log(`✓ no PocketBase hooks among ${tracked.length} tracked files`)

View file

@ -115,6 +115,18 @@ ok(/:only-child[^{]*\{[^}]*border-radius:\s*4px/.test(TOOLBAR), 'and a lone cont
ok(sqGap > -1 && sqGap < mq, 'CONTROL: the base square rule really does come BEFORE the media block, which is why the override is needed at all')
}
// ── 2c. NO CHILD BRINGS ITS OWN OUTLINE ──────────────────────────────────────────
// ShareButton is not a .mcb -- it wraps its button in .share-wrap with border-radius:50% and a
// conic-gradient ring on ::before -- so the button rules missed it and it kept a round rainbow halo
// inside the square panel. Found by rega at 390, not by me.
ok(/\.map-toolbar--square \.share-wrap \{[^}]*border-radius:\s*0/.test(TOOLBAR),
'the square panel flattens .share-wrap, which is a div and not a .mcb')
ok(/\.map-toolbar--square \.share-wrap::before \{[^}]*display:\s*none/.test(TOOLBAR),
"and suppresses its conic-gradient ring -- in this variant the PANEL owns the outline")
ok(/\.share-wrap\{[^}]*border-radius:50%/.test(readFileSync(join(REPO, 'library/components/map-controls/ShareButton.vue'), 'utf8').replace(/\s+/g, '')) ||
/border-radius:\s*50%/.test(readFileSync(join(REPO, 'library/components/map-controls/ShareButton.vue'), 'utf8')),
'CONTROL: ShareButton really does carry a 50% radius of its own, so the two rules above are not decorative')
// ── 3. forced colours, which the round buttons never had ────────────────────────────────────────
ok(/@media \(forced-colors: active\)/.test(TOOLBAR), 'the square variant ships a forced-colors block')
ok(/ButtonText/.test(TOOLBAR), 'using ButtonText, so the ring and dividers survive a replaced palette')

View file

@ -57,6 +57,16 @@ const BUNDLES = [
'upg-neighbor', 'wall-of-people-groups', 'key-cities', 'gospel-internet',
]
const ALLOW = {
'*:LOC-ENUS:library/utils/formatCount.js':
'HELD DECISION, and this file IS the decision: formatCount() is the one place the count locale is '
+ 'chosen, so COUNT_LOCALE = \'en-US\' is the policy written down rather than a bundle ignoring the '
+ 'reader. NUMERALS ARE HELD -- counts do not follow the locale -- and folding every dashboard onto '
+ 'this constant is what makes that auditable in one line instead of scattered across eight call '
+ 'sites. Bundle-wildcarded ON PURPOSE: the alternative is one entry per importer, so the LOCALE '
+ 'column warns every time a bundle adopts the shared helper -- punishing the fix and teaching '
+ 'people to stop reading the column. Restricted to library/ (see the lookup): no per-bundle source '
+ 'can be wildcarded, and a new toLocaleString(\'en-US\') inside research-dashboard or '
+ 'people-groups-grid still warns. Revisit only if the Driver unholds numerals.',
'prayer-walk-planner:ENG-PIN': 'keyless by design: always MapLibre, needs no token (index.js header)',
'regions-dashboard:LOC-ENUS:plugin-designs/regions-dashboard/src/RegionCountryMap.vue':
'HELD DECISION, not an oversight: the map popup formats population as fixed en-US on purpose. '
@ -175,6 +185,15 @@ if (locWrong.length) {
+ locWrong.map(([f, l]) => `${f ? 'missed' : 'false-flagged'}: ${l.slice(0, 56)}`).join(' | '))
process.exit(3)
}
// The bundle-wildcard is honoured ONLY under library/. Pinned because the failure is silent: widen it
// to any path and one entry could clear the column for a bundle's own source.
const wildcardKeys = Object.keys(ALLOW).filter((k) => k.startsWith('*:'))
const badWildcard = wildcardKeys.filter((k) => !k.split(':').slice(2).join(':').startsWith('library/'))
if (badWildcard.length) {
console.error('UNIVERSAL-PROPS: SELF-TEST FAILED — a `*:RULE:file` ALLOW entry outside library/ would '
+ 'never be honoured by the lookup, so it silently exempts nothing: ' + badWildcard.join(', '))
process.exit(3)
}
if (missed.length || falsePos.length) {
console.error(`UNIVERSAL-PROPS: SELF-TEST FAILED — ${missed.length ? 'rules blind to a planted bypass: ' + missed.join(', ') : ''}${falsePos.length ? ' false positives on clean code: ' + falsePos.join(', ') : ''}`)
process.exit(3)
@ -251,7 +270,16 @@ for (const b of BUNDLES.filter((x) => !ONLY || ONLY.includes(x))) {
// silenced any FUTURE operative en-US anywhere in that bundle -- clearing a column by going
// blind. A `bundle:RULE:file` key exempts the one file that earned it and leaves the rest of the
// bundle answerable.
const allowed = ALLOW[`${b}:${r.id}:${relative(ROOT, f)}`] || ALLOW[`${b}:${r.id}`]
// ★ AND A SHARED LIBRARY FILE CAN BE ALLOWED FOR EVERY BUNDLE THAT IMPORTS IT. A `*:RULE:file`
// key is honoured only for a path under library/, because that is the one case where the site is
// not the bundle's: library/utils/formatCount.js holds the HELD numerals decision for eight call
// sites, and it is attributed to every bundle that compiles it. Per-importer entries would mean
// the LOCALE column warns each time a bundle adopts the shared helper -- the column punishing the
// fold that made the policy auditable. The library/ restriction is the whole guard: a bundle's own
// source can never be wildcarded, so this cannot be used to clear a column broadly.
const rel = relative(ROOT, f).replace(/\\/g, '/')
const allowed = ALLOW[`${b}:${r.id}:${rel}`] || ALLOW[`${b}:${r.id}`]
|| (rel.startsWith('library/') ? ALLOW[`*:${r.id}:${rel}`] : undefined)
if (allowed) { if (matrix[b][r.prop] === 'ok') matrix[b][r.prop] = 'allowed'; continue }
findings.push({ b, rule: r.id, prop: r.prop, warn: !!r.warn, where: `${relative(ROOT, f)}:${lineOf(src, idx)}`, text: src.slice(idx, idx + 70).replace(/\s+/g, ' ').trim() })
matrix[b][r.prop] = r.warn ? (matrix[b][r.prop] === 'BYPASS' ? 'BYPASS' : 'warn') : 'BYPASS'

View file

@ -0,0 +1,89 @@
/**
* internal/dev-sync-plugin.mjs — `bun run dev` follows a shared branch, so a laptop sees teammates' landings.
*
* WHY: ten people each running `bun run dev` should see what the others landed on main without anyone
* typing `git pull`: the dev server fast-forwards and Vite hot-reloads the changed files. It is the local
* form of the cloud container's pull loop (deployment/cloud/entry.sh), MINUS the `reset --hard`: a laptop
* holds someone's unsaved work, so this NEVER merges over local edits, never stashes, never resets.
*
* OPT-IN, ONE switch in .env.local: DX_SYNC_REMOTE = a remote name (origin) OR a repo URL (https://…/x.git),
* e.g. to watch what cloud agents push. DX_SYNC_BRANCH defaults to main, DX_SYNC_INTERVAL to 5 seconds.
* Unset = off: plain hot reload of local edits, as always. Every interval it fetches <remote> <branch>
* (a URL needs no `git remote add`; private repos use your normal git credentials) and fast-forwards ONLY when
* this checkout is on that branch, no tracked file is modified, and `git merge --ff-only` agrees.
* Otherwise it logs once per new upstream commit ("main is N commits ahead, pull when ready") and reports
* the state at /api/dev-sync for a Studio badge.
*
* DEV ONLY (`apply: 'serve'`).
*/
import { execFile } from 'node:child_process'
const git = (root, args) => new Promise((ok) => execFile('git', args,
{ cwd: root, timeout: 60000, env: { ...process.env, GIT_TERMINAL_PROMPT: '0' } },
(e, out, err) => ok({ ok: !e, out: String(out || '').trim(), err: String(err || e?.message || '').trim().split('\n')[0] })))
// What the log and /api/dev-sync show: never the credentials of a https://user:token@host/… URL.
const shown = (remote) => remote.replace(/\/\/[^/@]*@/, '//')
const label = (remote, branch) => (remote.includes('/') ? `${branch} of ${shown(remote)}` : `${remote}/${branch}`)
// One timer per `bun run dev`, kept across Vite's own restarts (the config module is re-imported then).
const REG = (globalThis.__dxDevSync ||= { timer: null, running: false, status: { enabled: false } })
export async function syncOnce(root, remote, branch, log = { info() {}, warn() {} }) {
if (REG.running) return REG.status
REG.running = true
try {
const src = label(remote, branch)
const s = { enabled: true, remote: shown(remote), branch, checkedAt: new Date().toISOString() }
const f = await git(root, ['fetch', '-q', remote, branch])
if (!f.ok) return (REG.status = { ...s, state: 'fetch-failed', message: `could not fetch ${src}: ${shown(f.err)}` })
const up = (await git(root, ['rev-parse', 'FETCH_HEAD'])).out
const head = (await git(root, ['rev-parse', 'HEAD'])).out
const cur = (await git(root, ['symbolic-ref', '-q', '--short', 'HEAD'])).out
const behind = Number((await git(root, ['rev-list', '--count', `HEAD..${up}`])).out || 0)
const ahead = Number((await git(root, ['rev-list', '--count', `${up}..HEAD`])).out || 0)
const dirty = (await git(root, ['status', '--porcelain', '--untracked-files=no'])).out !== ''
Object.assign(s, { upstream: up, behind, ahead, dirty, currentBranch: cur || '(detached)' })
if (behind === 0) return (REG.status = { ...s, state: 'up-to-date', message: `up to date with ${src}` })
const why = cur !== branch ? `this checkout is on ${cur || 'a detached HEAD'}, not ${branch}`
: dirty ? 'you have local edits'
: ahead ? `you have ${ahead} local commit(s) that are not on ${src}` : ''
const m = why ? null : await git(root, ['merge', '--ff-only', '-q', up])
if (why || !m.ok) {
const message = `${branch} is ${behind} commit(s) ahead; ${why || `fast-forward refused (${m.err})`}, so nothing was merged. Pull when ready.`
if (REG.status.upstream !== up || REG.status.state !== 'behind') log.warn(`[dev-sync] ${message}`)
return (REG.status = { ...s, state: 'behind', message })
}
log.info(`[dev-sync] fast-forwarded ${head.slice(0, 8)} → ${up.slice(0, 8)} (${behind} commit(s) from ${src})`)
return (REG.status = { ...s, behind: 0, state: 'up-to-date', lastMerge: s.checkedAt, message: `fast-forwarded ${behind} commit(s) from ${src}` })
} finally {
REG.running = false
}
}
export function devSyncPlugin(root, env = process.env) {
const remote = env.DX_SYNC_REMOTE || ''
const branch = env.DX_SYNC_BRANCH || 'main'
const every = Math.max(2, Number(env.DX_SYNC_INTERVAL) || 5)
return {
name: 'dx-dev-sync',
apply: 'serve',
configureServer(server) {
server.middlewares.use('/api/dev-sync', (req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' })
res.end(JSON.stringify(REG.status))
})
clearInterval(REG.timer)
if (!remote) {
REG.status = { enabled: false, message: 'off: set DX_SYNC_REMOTE (a remote name like origin, or a repo URL) in .env.local to follow a shared branch' }
return
}
const log = server.config.logger
log.info(`[dev-sync] following ${label(remote, branch)} every ${every}s (fast-forward only, never over local edits)`)
const tick = () => syncOnce(root, remote, branch, log)
REG.timer = setInterval(tick, every * 1000)
REG.timer.unref?.()
tick()
},
}
}

View file

@ -46,6 +46,7 @@ import { createHash } from 'node:crypto'
import { detectProfileType } from './plugin-gallery/discover.mjs'
import { profileMetaFields, bundleStage } from './profile-meta.mjs'
import { TREE_NAME as CONFIGURED_TREE_NAME } from './_tree-name.mjs'
import { deriveComposedTiers } from './_composed-tiers.mjs'
import { syncAppShells } from './sync-app-shells.mjs'
const __dirname = dirname(fileURLToPath(import.meta.url))
@ -396,48 +397,6 @@ function composesAMapLeaf(dir, profileName, file) {
* composesAMapLeaf reads (see its point 1) but returns the author's data itself rather than
* a map-ness boolean derived from it — the manifest needs the edges, not just the verdict.
*/
/**
* Derive the composition tier from the `composes` edges, and refuse to disagree with an author.
*
* ★ WHY DERIVE AT ALL (Driver, 2026-09-27). Tiers 3-5 were AUTHORED ONLY — discover.mjs infers just
* `single` and `parameterized`, so a composite with no meta.json shipped as capability 1. That is not
* hypothetical: research-dashboard did exactly that while nesting ten views, and the warning in
* detectProfileType exists because of it. A missing file is indistinguishable from a deliberate choice.
*
* THE RULE, measured against all 25 bundles before it was written: a profile that composes anything is
* cap-4 (nested-elements-mfe); if any of the things it composes is itself cap-4, it is cap-5
* (nested-mfe-spa). Keyed per PROFILE, and refs are accepted in BOTH published forms — 'bundle/profile'
* (doxa-maps-spa) and a bare 'bundle' (plugin-studio). Getting either of those wrong is not academic:
* keying on the bundle derived 11 false tiers, and resolving only the slashed form demoted plugin-studio
* from 5 to 4. With both handled: 10 composing profiles, 10 agree, 0 disagree.
*
* AN EXPLICIT type STAYS AUTHORITATIVE AND MUST AGREE. It is not overridden — it is CHECKED. A
* declaration that contradicts the structure is the interesting case: either the meta is stale or the
* composes list is, and both are worth a loud build failure rather than a silent pick between them.
*
* An UNRESOLVED ref is reported separately and never silently treated as "not cap-4", because a typo in
* composes and a genuinely non-composite child look identical from here.
*/
export function deriveComposedTiers(bundles) {
const byKey = new Map(), byBundle = new Map()
for (const b of bundles) for (const p of b.profiles || []) {
byKey.set(`${b.bundle}/${p.profile}`, p.type || null)
if (!byBundle.has(b.bundle)) byBundle.set(b.bundle, p.type || null)
if (!byBundle.has(p.profile)) byBundle.set(p.profile, p.type || null)
}
const resolve = (ref) => (ref.includes('/') ? byKey.get(ref) : byBundle.get(ref))
const conflicts = [], unresolved = []
for (const b of bundles) for (const p of b.profiles || []) {
const own = p.composesOwn
if (!own || !own.length) continue
const kinds = own.map((ref) => { const k = resolve(ref); if (k === undefined) unresolved.push(`${b.bundle}/${p.profile} -> ${ref}`); return k })
const derived = kinds.some((k) => k === 'nested-elements-mfe') ? 'nested-mfe-spa' : 'nested-elements-mfe'
if (!p.type) { p.type = derived; continue }
if (p.type !== derived) conflicts.push(`${b.bundle}/${p.profile}: meta.json declares "${p.type}" but its composes edges derive "${derived}"`)
}
return { conflicts, unresolved }
}
function readComposes(dir, profileName) {
try {
const metaPath = join(dir, `${profileName}.meta.json`)
@ -1415,9 +1374,15 @@ function writeManifestAndHtml(root, bundles, tokenUrlExpr, bakedToken) {
// author forgot a meta.json, and a stale meta can no longer disagree with the structure in silence.
{
const { conflicts, unresolved } = deriveComposedTiers(bundles)
// FAILS rather than warns, now that the resolver understands all three vocabularies and the tree has
// ZERO unresolved refs. While five were outstanding a warning was right — they turned out to be
// correct data my resolver could not read, and failing would have blamed five authors for my gap.
// With the count at 0, a new unresolved ref is a genuinely broken edge and silently weakens a tier.
if (unresolved.length) {
console.warn(`[tree] ${unresolved.length} composes ref(s) resolve to no known bundle/profile — a typo here silently weakens a tier:`)
for (const u of unresolved) console.warn(` ${u}`)
console.error(`[tree] ${unresolved.length} composes ref(s) resolve to nothing — a broken edge silently weakens a tier:`)
for (const u of unresolved) console.error(` ${u}`)
console.error(' A ref may be "<bundle>/<profile>", a bare "<bundle>", or a registered element tag.')
process.exit(1)
}
if (conflicts.length) {
console.error('[tree] composition tier CONFLICT — a profile\'s meta.json disagrees with its own composes edges:')

View file

@ -98,6 +98,14 @@ useShadowStyles(`
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
/* .hbg-ctrl's 10px top margin would tear the panel apart; inside the group it has no business. */
.map-toolbar--square .hbg-ctrl { margin: 0; }
/* ★ ShareButton IS NOT A .mcb, so the rules above missed it. It wraps its button in a .share-wrap div
carrying border-radius:50% plus a conic-gradient ring on ::before at inset:-2px -- which inside the
panel reads as a circular rainbow halo poking out of one corner, breaking the single-card illusion
at exactly the place the eye lands. rega measured it at 390 and asked whether square should flatten
it; it should: in this variant the PANEL owns the outline, so a child may not bring its own.
The round default keeps its ring untouched. */
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
/* ★ OUTER CORNERS ONLY, AND NO overflow:hidden. Clipping would have been the quick way to round
the panel, but it also clips a focus ring on any inner button -- and the engine does not do it:
it rounds the first and last buttons instead (button:focus:first-child -> 4px 4px 0 0, :last-child

View file

@ -352,14 +352,14 @@ const VTL_SHADOW_CSS = `
.vtl-chev svg { width:15px; height:15px; }
.vtl-chev.open { transform:rotate(90deg); }
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
/* MATERIAL NAV-ROW METRICS (2026-09-21). Driver: "people are used to the YouTube layout, Google
layout is just way better. We do not need to create custom styles people are not used to."
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
Material/YouTube list layout rather than custom styling readers are not used to.
Measured before this change: 44px rows with an 8px radius.
min-height:48px the Material list-item height. min-height, not height, so a wrapping
label still grows instead of clipping.
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
The 999px stadium above was a real instruction ("imitate the YouTube
active row") and it shipped. The Driver then measured it against the
active row") and it shipped. It was then measured against the
rest of the product and reversed it: "the roundedness of the tabs is a
little bit too round because there is nowhere else in the app that has
that same roundedness. Even the collapse button is not that round...
@ -841,14 +841,14 @@ export default defineComponent({
.vtl-chev svg { width:15px; height:15px; }
.vtl-chev.open { transform:rotate(90deg); }
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
/* MATERIAL NAV-ROW METRICS (2026-09-21). Driver: "people are used to the YouTube layout, Google
layout is just way better. We do not need to create custom styles people are not used to."
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
Material/YouTube list layout rather than custom styling readers are not used to.
Measured before this change: 44px rows with an 8px radius.
min-height:48px the Material list-item height. min-height, not height, so a wrapping
label still grows instead of clipping.
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
The 999px stadium above was a real instruction ("imitate the YouTube
active row") and it shipped. The Driver then measured it against the
active row") and it shipped. It was then measured against the
rest of the product and reversed it: "the roundedness of the tabs is a
little bit too round because there is nowhere else in the app that has
that same roundedness. Even the collapse button is not that round...

View file

@ -137,7 +137,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null })
.pg-h1{margin:2px 0 0;font:700 40px Georgia,serif;color:#1b1a17}
.pg-lede{margin:0 0 22px;max-width:1180px;font:400 19px/1.5 Georgia,serif;color:#413d35}
/* ⚠ THE CELLS ARE RECTANGLES, NOT SQUARES, and that is forced by the sheet rather than chosen.
52 columns is fixed by the data (weeks in a year) and 100 rows by the Driver's "100 year life",
52 columns is fixed by the data (weeks in a year) and 100 rows by the product's "100 year life" framing,
so both dimensions are given and only the SHAPE is free. Squares would need
(1380/52)=26.5px per side x 100 rows = 2,654px of grid in 1,521px of printable height — it
overflows the page by 1.7x. Caught by computing the height before rendering rather than by
@ -169,7 +169,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null })
justify-content:center;font:italic 13px Georgia,serif;color:#a89f8c;text-align:center;padding:6px}
.nm{font:700 25px Georgia,serif;color:#1b1a17;line-height:1.1}
.mt{font:400 17px Georgia,serif;color:#6d766e}
/* FINE PRINT — Driver: "attribution minimal, fine print small". */
/* FINE PRINT — product decision: attribution minimal, fine print small. */
.fine{position:absolute;left:0;right:0;bottom:22px;text-align:center;
font:400 13px Georgia,serif;color:#a89f8c}
/* PRINT. The sheet is authored at ${W}px wide while @page is physical, so without

View file

@ -2,7 +2,7 @@
"_meta": {
"purpose": "EVERY human-readable string in the UPG-100 prayer packet, in one file, so a new language is a new block here and NOT a code change. packet.mjs reads LANG (default 'en') and falls back to 'en' key-by-key, so a partial translation renders the translated keys and leaves the rest in English rather than blanking.",
"how_to_translate": "Copy the \"en\" block, change the key to the ISO code, translate the values. Keep {placeholders} exactly as they are — they are substituted at render time. Do not translate scripture REFERENCES (book names are resolved by the reader's own Bible); DO translate the prayer text.",
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:1-20, printed in full at the Driver's instruction). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
"note_on_scripture": "point4_passage is the ONLY full scripture text in the packet (Mark 5:1-20, printed in full by product decision). A translation MUST supply its own rendering in a public-domain or properly-licensed version FOR THAT LANGUAGE. ⚠ Do NOT translate it yourself and do NOT leave a machine rendering in place: this is printed scripture in a prayer packet. A language block that omits point4_passage falls back to the English WEB text per-key, which is honest — an untrusted translation of Mark 5 is not.",
"note_on_references": "Scripture REFERENCES (Matthew 27:27, Mark 5:1-20) are deliberately left in English in every language block, so a reader can look them up in their own Bible regardless of the packet's language. ⚠ MEASURED TRADEOFF, not an oversight: on a rendered French page the English book names are visibly foreign next to fully-translated prayer text. If a language wants localised book names, add a `books` map to that block and teach the renderer to use it — do NOT translate the refs inline, because the same strings identify the passage for any future lookup.",
"note_on_scripts": "ALL 11 app locales now ship. Script coverage MEASURED by rendering at 48px and READING THE PIXELS: Latin, Cyrillic (ru), Arabic (ar) and CJK (zh) shape correctly with the system Georgia/Palatino/serif stack. DEVANAGARI (hi) does NOT — it renders as tofu boxes — so Noto Serif Devanagari is vendored (OFL) and base64-INLINED into hi packets by the renderer's SCRIPT_FONT map. Inlined, not linked, because a packet is a standalone file that must print offline; ~165KB on a 3.5MB packet, and only for that language. mr and ne map to the same face.\n⚠ TWO MEASUREMENTS LIED ABOUT THIS, so do not automate it cheaply: (1) comparing shaped width against a missing font reported ar and zh BROKEN and hi FINE — exactly backwards, because Devanagari tofu boxes match real glyph advance; (2) an ink-column-profile heuristic scored CORRECTLY-RENDERED Devanagari the same as tofu (3 vs 2 distinct heights), because its baseline bar gives a uniform profile. check:packet-render therefore asserts only that a DECLARED @font-face LOADED — the mechanical half — and leaves glyph correctness to a human reading a screenshot. A detector that blocks working packets is worse than none.",
"note_on_rtl": "ar is right-to-left. The renderer emits dir on <html> from an RTL set (packet-render.js), and scripture REFERENCES are wrapped in dir=ltr + unicode-bidi:isolate. Without that isolation the bidi algorithm reorders a reference that STARTS WITH A DIGIT: '1 Peter 5:6-11' rendered as 'Peter 5:6-11 1'. Note the reference LIST then reads right-to-left on an RTL page (first item rightmost) — that is correct for an RTL reader, not a defect."

View file

@ -168,6 +168,7 @@
"check:one-palette:self-test": "node internal/check-one-palette.mjs --self-test",
"check:optional-t-equivalence": "node internal/check-optional-t-equivalence.mjs",
"check:package-json-unique-keys": "node internal/check-package-json-unique-keys.mjs",
"check:no-repo-pb-hooks": "node internal/check-no-repo-pb-hooks.mjs",
"check:packet-browser": "node internal/check-packet-browser.mjs",
"check:packet-fixture": "node internal/generate-packet-fixture.mjs --check",
"check:packet-render": "node internal/check-packet-render.mjs",
@ -247,7 +248,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:done-evidence check:script-flags check:backlog-status 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:backlog-refs 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: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:regions-uses-library check:shadow-css-parses check:square-map-controls",
"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-credentials-omit check:no-credentials-omit:self-test check:shadow-reduced-motion",
"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",
"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",
@ -395,6 +396,7 @@
"check:no-silent-engine": "A profile must NEVER fall back to a different map engine than its provider asked for. `engineGlobal(provider) || window.mapboxgl` looks defensive and is not: engineGlobal already returns the right global for the requested provider (useMapInstance.js:115 falls back to mapbox's NAME only for an UNKNOWN provider, never a missing engine), so the || fires in exactly one case — the page asked for maplibre and maplibre failed to load — and hands back the TOKEN-GATED engine to a page that asked for the KEYLESS one. Worse, accessToken is gated on !isMaplibre, so the substitute arrives WITHOUT a token: 401s on every tile instead of a legible failure. Found by regions' C3 read 2026-09-26; 2 offenders remained (cities-internet, gospel-resources) after my-upg-100-list was fixed. NOT a duplicate of check:leaf-engine-per-provider / check:provider-switch / check:auto-engine — all three assert the HAPPY path (what loads) and this bug only appears when something does NOT load, so all three were green while it existed. A SOURCE check on purpose: reproducing it live means serving a leaf with MapLibre deliberately blocked, spending a browser slot on what a grep decides. Exits 75 when no file calls engineGlobal — 'found nothing' is not 'found nothing wrong'. Run :self-test to prove the pattern still matches.",
"check:optional-t-equivalence": "C4's shared guarded translator (library/composables/useOptionalT.js) must behave like the twenty hand-written try{useI18n()}catch blocks it replaces: all three host states, and the per-site register asserts each migrated file still passes ITS OWN fallback rather than inheriting the catalogue, because routing them through tStatic would change what seven bare-host bundles render. EVERY LATER C4 WAVE APPENDS A ROW. Extract-and-executes the module source, since useOptionalT imports vue-i18n and an i18n index that calls import.meta.glob.",
"check:package-json-unique-keys": "no object in package.json may carry the same key twice: JSON.parse keeps the last silently, so a duplicate kills the first entry while every gate that reads the PARSED object passes (a //scripts note sat twice after a merge). A small scanner tracks keys per object; its self-test runs every time.",
"check:no-repo-pb-hooks": "no PocketBase hooks (pb_hooks/, *.pb.js) in the repo: the cloud container pulls it live, so a pushed hook would be server-side JS from any writer; the one team sign-in hook is baked into the image",
"check:packet-browser": "the packet the READER gets — the legend's Export > Prayer packet path, proving the shared renderer runs in a BROWSER. Asserts the same 12 points / 12 wheel labels / page-1 geography / print layer as check:packet-render, which it did not until 2026-09-24. CONDITIONAL: SKIPs without a server over the repo root (python3 -m http.server 4898) and a reachable records API.",
"check:packet-fixture": "the committed fixture must still match clusters.json and must never carry image_url (CI would fetch 43 photos from someone else's CDN).",
"check:packet-render:expect-funnel": "check:packet-render with the page-2 FUNNEL declared REQUIRED. Exists because of a real near-miss: a merge resolved with `git checkout --ours` deleted the printPacket call site that supplies the funnel data (60 lines) and EVERY GATE STAYED GREEN — it had to, because the funnel page is OPTIONAL by design (buildPacket omits it when the arg is null), so a packet without page 2 is not malformed, just smaller. Always requiring it would be the wrong fix: the 11 pre-funnel laos packets and any host with no funnel data would go red, and a false red costs as much as a false green. So the CALLER, which knows whether this packet was built with funnel data, declares it — an absence is then either declared (no flag) or a failure (flag passed, page missing), never a silent nothing. Pass it for any packet from a profile that wires packetFunnel(). Browser gate.",

View file

@ -472,7 +472,7 @@ useShadowStyles(
'.gm-adm1{margin-top:8px;padding-top:7px;border-top:1px solid rgba(0,0,0,.12)}' +
'.gm-adm1-h{font-weight:600;font-size:12px;margin-bottom:5px}' +
'.gm-seg{display:inline-flex;border:1px solid rgba(0,0,0,.2);border-radius:6px;overflow:hidden;margin-bottom:6px}' +
'.gm-seg button{font:inherit;font-size:11px;padding:3px 10px;border:0;background:transparent;color:inherit;cursor:pointer}' +
'.gm-seg button{font:inherit;font-size:11px;padding:3px 10px;min-height:24px;border:0;background:transparent;color:inherit;cursor:pointer}' + // 24px: the AA touch-target minimum, at every width
'.gm-seg button.on{background:#08519c;color:#fff}' +
'.gm-adm1-t{width:100%;border-collapse:collapse;font-size:12px;margin:4px 0 6px}' +
'.gm-adm1-t th,.gm-adm1-t td{padding:3px 4px;text-align:end}' +

View file

@ -1,6 +1,7 @@
<script setup>
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
import { usePplrT } from '../composables/usePplrT.js'
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the Driver
import { tStatic } from '@map/i18n/index.js'
/**
* pplr-coverage.vue — Country choropleth: avg # of locales filled per PG in that country.
@ -126,7 +127,7 @@ onMounted(async () => {
new (glFor(map.value)).Popup({ maxWidth: '320px' })
.setLngLat(f.geometry.coordinates).setHTML(popupForPG(f.properties)).addTo(map.value)
})
status.value = t('pplr.status.readyCoverage', { countries: countryStats.size, rows: [...countryStats.values()].reduce((n, c) => n + c.pgCount, 0).toLocaleString('en-US') })
status.value = t('pplr.status.readyCoverage', { countries: countryStats.size, rows: formatCount([...countryStats.values()].reduce((n, c) => n + c.pgCount, 0)) })
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
await whenGeojsonDrawn(map.value)
dataReady.value = true

View file

@ -7,6 +7,7 @@
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
import { usePplrT } from '../composables/usePplrT.js'
import { formatCount } from '@map/utils/formatCount.js' // counts stay fixed en-US: numerals are held for the Driver
import { tStatic } from '@map/i18n/index.js'
import { useMapInstance } from '@map/composables/useMapInstance.js'
import { addCountryPolygons, addPGPoints, popupForPG, POPUP_CSS } from '../utils/pplrMap.js'
@ -58,7 +59,7 @@ onMounted(async () => {
.setHTML(popupForPG(f.properties))
.addTo(map.value)
})
status.value = t('pplr.status.readyPins', { pins: fc.features.length.toLocaleString('en-US') })
status.value = t('pplr.status.readyPins', { pins: formatCount(fc.features.length) })
// keep the LoadingGlobe up until the pins are actually drawn, not merely added
await whenGeojsonDrawn(map.value)
dataReady.value = true

View file

@ -382,6 +382,9 @@ const audioMode = ref('local')
// The server is set up to run the engine (it reports expected=true while the engine is down): an absent
// engine there means "starting or failed to set up", not "this only runs on your computer".
const engineExpected = ref(false)
// An engine that records ITS OWN machine's microphone, reached from another machine: it would record the
// server, not this reader, so the page treats it as laptop-only.
const remoteLocalMic = computed(() => audioMode.value === 'local' && !onOwnComputer.value && engine.value === 'ready')
let sock = null, media = null, actx = null
async function startBrowser() {
@ -586,7 +589,7 @@ watch([draft, recording], queueActivity)
const statusText = computed(() => ({
connecting: 'Connecting…',
starting: 'Loading speech model… (about 20 s the first time)',
ready: recording.value ? 'Listening' : 'Ready',
ready: remoteLocalMic.value ? 'Runs on your computer' : recording.value ? 'Listening' : 'Ready',
error: 'Engine error',
offline: onOwnComputer.value ? 'Engine offline' : engineExpected.value ? 'Not running yet' : 'Runs on your computer',
}[engine.value] || engine.value))
@ -647,7 +650,7 @@ const statusText = computed(() => ({
<button
class="mic"
:class="{ on: recording }"
:disabled="busy || engine !== 'ready'"
:disabled="busy || engine !== 'ready' || remoteLocalMic"
:aria-pressed="recording"
:aria-label="recording ? 'Stop recording' : 'Start recording'"
@click="toggle"
@ -689,7 +692,7 @@ const statusText = computed(() => ({
<p v-else-if="engine === 'offline' && !onOwnComputer && engineExpected" class="notice" data-kind="warn">
The voice engine on this server isn't running yet (it is starting, or it failed to set up). Try again in a minute.
</p>
<p v-else-if="engine === 'offline' && !onOwnComputer" class="notice" data-kind="warn">
<p v-else-if="(engine === 'offline' || remoteLocalMic) && !onOwnComputer" class="notice" data-kind="warn">
Voice to text runs on your own computer, not on this server: it listens to the microphone of the machine
the engine runs on. Open the Plugin Studio on your computer (<code>bun run dev</code>) or use the Rudder desktop app.
</p>
@ -719,7 +722,7 @@ const statusText = computed(() => ({
v-if="compact"
class="mic sm"
:class="{ on: recording }"
:disabled="busy || engine !== 'ready'"
:disabled="busy || engine !== 'ready' || remoteLocalMic"
:aria-pressed="recording"
:aria-label="recording ? 'Stop recording' : 'Start recording'"
@click="toggle"

View file

@ -84,9 +84,13 @@ const SRC_R = 'cp-r', SRC_U = 'cp-u'
const fc = (features) => ({ type: 'FeatureCollection', features })
const pt = (g) => ({ type: 'Feature', geometry: { type: 'Point', coordinates: [g.lng, g.lat] }, properties: { id: g.pgid, pop: g.pop, b: g.believers } })
function setSrc(m, id, d) { const s = m.getSource(id); if (s) s.setData(d); else m.addSource(id, { type: 'geojson', data: d }) }
let repaintPending = false
function repaint() {
const m = map.value
if (!m || !m.isStyleLoaded?.()) return
if (!m) return
// isStyleLoaded() is also false while TILES load (MapLibre), so a data load that lands then used to
// be dropped for good: the start view showed no dots at all (rega, upgn6). Try again once idle.
if (!m.isStyleLoaded?.()) { if (!repaintPending) { repaintPending = true; m.once('idle', () => { repaintPending = false; repaint() }) } return }
const b = active.value
setSrc(m, SRC_U, fc(b ? b.unreached.map(pt) : []))
setSrc(m, SRC_R, fc(b ? b.reached.map(pt) : []))

View file

@ -54,6 +54,9 @@ function select(g) { if (g && !g.reached) { nbState.pgid = g.pgid; query.value =
// The neighbor in focus: a dot click picks its card, a card click flies to its dot. Both ways, so the
// map and the brief never disagree about which neighbor you are looking at.
const activeId = ref(null)
// Hover label: 7,000 red dots are anonymous until clicked, so name the one under the pointer.
const hover = ref(null) // { x, y, text }
function hoverAt(ev, text) { hover.value = text ? { x: ev.point.x, y: ev.point.y, text } : null }
watch(() => nbState.pgid, () => { activeId.value = null })
function focusNeighbor(n, fly = true) {
activeId.value = n.g.pgid
@ -143,9 +146,13 @@ function ensureLayers(m) {
function applyDim(m) {
if (m.getLayer('nb-u')) m.setPaintProperty('nb-u', 'circle-opacity', selected.value ? 0.18 : 0.55)
}
let repaintPending = false
function repaint() {
const m = map.value
if (!m || !m.isStyleLoaded?.()) return
if (!m) return
// isStyleLoaded() is also false while TILES load (MapLibre), so a data load that lands then used to
// be dropped for good: the start view showed no dots at all (rega, upgn6). Try again once idle.
if (!m.isStyleLoaded?.()) { if (!repaintPending) { repaintPending = true; m.once('idle', () => { repaintPending = false; repaint() }) } return }
ensureLayers(m)
}
function frame() {
@ -189,9 +196,12 @@ onMounted(async () => {
const n = neighbors.value.find((x) => x.g.pgid === id)
if (n) focusNeighbor(n, false)
})
const byId = (id) => data.value?.groups.find((g) => g.pgid === id)
const label = (g) => g && `${g.name} · ${g.country} · ${g.langName}`
for (const id of ['nb-u', 'nb-n']) {
m.on('mouseenter', id, () => { m.getCanvas().style.cursor = 'pointer' })
m.on('mouseleave', id, () => { m.getCanvas().style.cursor = '' })
m.on('mousemove', id, (ev) => hoverAt(ev, label(byId(ev.features?.[0]?.properties?.id))))
m.on('mouseleave', id, () => { m.getCanvas().style.cursor = ''; hover.value = null })
}
})
// A later style reload (a theme switch) drops our layers; put them back.
@ -242,6 +252,7 @@ useShadowStyles(`
.mb-same { font:700 10px/1 inherit; color:#7a3e00; background:#fdeedd; border-radius:999px; padding:3px 6px; margin-left:4px; }
.mb-note { padding:14px; color:#6b7280; font-size:13px; line-height:1.45; }
.mb-maperr { position:absolute; right:12px; top:12px; z-index:15; background:#fff; border:1px solid #d9dee6; border-radius:8px; padding:8px 12px; font-size:13px; color:#6b7280; }
.mb-hover { position:absolute; z-index:25; pointer-events:none; background:rgba(0,27,68,.92); color:#fff; font-size:12px; line-height:1.3; padding:5px 8px; border-radius:6px; max-width:260px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mb-legend { position:absolute; right:12px; bottom:28px; z-index:15; background:rgba(255,255,255,.95); border:1px solid #d9dee6; border-radius:10px; padding:8px 10px; font-size:12px; }
.mb-legend div { display:flex; align-items:center; gap:7px; padding:2px 0; }
@media (max-width:760px) {
@ -255,6 +266,7 @@ useShadowStyles(`
<div class="mb-root">
<div ref="mapContainer" class="mb-map"></div>
<div v-if="mapError" class="mb-maperr" role="status">{{ mapError }}</div>
<div v-if="hover" class="mb-hover" :style="{ left: hover.x + 12 + 'px', top: hover.y + 12 + 'px' }">{{ hover.text }}</div>
<div class="mb-legend" :aria-label="$t('neighbor.mob.legend')">
<div><span class="mb-dot" :style="{ background: UNREACHED }"></span>{{ $t('neighbor.mob.legendUnreached') }}</div>

View file

@ -107,6 +107,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <all-people-groups> custom element. -->
<script src="../all-people-groups.js" integrity="sha384-cJcadyELOZmDNp2L6R0Er4BZzjgkvLOVC7ojcDewUqDhO7sT0of0bhz12cFDdgsE" crossorigin="anonymous"></script>
<script src="../all-people-groups.js" integrity="sha384-Tc/Jinjihx10hSKgNMFL/QRW/1aVqB+6Fp4wxiAi4ACneQYIS3iRMM8lvkL9Mx2s" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <cities-internet-map> custom element. -->
<script src="../cities-internet.js" integrity="sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR" crossorigin="anonymous"></script>
<script src="../cities-internet.js" integrity="sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
<script src="../country-posters.js" integrity="sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx" crossorigin="anonymous"></script>
<script src="../country-posters.js" integrity="sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
<script src="../country-posters.js" integrity="sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx" crossorigin="anonymous"></script>
<script src="../country-posters.js" integrity="sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <country-posters-map> custom element. -->
<script src="../country-posters.js" integrity="sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx" crossorigin="anonymous"></script>
<script src="../country-posters.js" integrity="sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -674,6 +674,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
<script src="../../dashboard-plus-grid.js" integrity="sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC" crossorigin="anonymous"></script>
<script src="../../dashboard-plus-grid.js" integrity="sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <dashboard-plus-grid> custom element. -->
<script src="../dashboard-plus-grid.js" integrity="sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC" crossorigin="anonymous"></script>
<script src="../dashboard-plus-grid.js" integrity="sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -212,6 +212,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <demo-map> custom element. -->
<script src="../demo-map.js" integrity="sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI" crossorigin="anonymous"></script>
<script src="../demo-map.js" integrity="sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -33,7 +33,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <demo-map> custom element. -->
<script src="../../demo-map.js" integrity="sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI" crossorigin="anonymous"></script>
<script src="../../demo-map.js" integrity="sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -98,14 +98,14 @@
.vtl-chev svg { width:15px; height:15px; }
.vtl-chev.open { transform:rotate(90deg); }
.vtl-rows { display:flex; flex-direction:column; gap:1px; }
/* MATERIAL NAV-ROW METRICS (2026-09-21). Driver: "people are used to the YouTube layout, Google
layout is just way better. We do not need to create custom styles people are not used to."
/* MATERIAL NAV-ROW METRICS (2026-09-21). Product decision: follow the familiar
Material/YouTube list layout rather than custom styling readers are not used to.
Measured before this change: 44px rows with an 8px radius.
min-height:48px the Material list-item height. min-height, not height, so a wrapping
label still grows instead of clipping.
border-radius var(--vtl-radius,8px) — SUPERSEDED THE FULL PILL (2026-09-23).
The 999px stadium above was a real instruction ("imitate the YouTube
active row") and it shipped. The Driver then measured it against the
active row") and it shipped. It was then measured against the
rest of the product and reversed it: "the roundedness of the tabs is a
little bit too round because there is nowhere else in the app that has
that same roundedness. Even the collapse button is not that round...

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
<script src="../../doxa-maps-spa.js" integrity="sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8" crossorigin="anonymous"></script>
<script src="../../doxa-maps-spa.js" integrity="sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-maps-spa> custom element. -->
<script src="../doxa-maps-spa.js" integrity="sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8" crossorigin="anonymous"></script>
<script src="../doxa-maps-spa.js" integrity="sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -12,7 +12,7 @@
"bundle": "all-people-groups",
"scriptUrl": "./all-people-groups/all-people-groups.js",
"output": "dx-maps/all-people-groups/all-people-groups.js",
"integrity": "sha384-cJcadyELOZmDNp2L6R0Er4BZzjgkvLOVC7ojcDewUqDhO7sT0of0bhz12cFDdgsE",
"integrity": "sha384-Tc/Jinjihx10hSKgNMFL/QRW/1aVqB+6Fp4wxiAi4ACneQYIS3iRMM8lvkL9Mx2s",
"elements": [
"all-people-groups"
],
@ -30,7 +30,7 @@
"scriptUrl": "./all-people-groups/all-people-groups.js",
"embed": {
"iframe": "<iframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-cJcadyELOZmDNp2L6R0Er4BZzjgkvLOVC7ojcDewUqDhO7sT0of0bhz12cFDdgsE\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></all-people-groups>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-Tc/Jinjihx10hSKgNMFL/QRW/1aVqB+6Fp4wxiAi4ACneQYIS3iRMM8lvkL9Mx2s\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></all-people-groups>"
},
"bundle": "all-people-groups"
}
@ -108,7 +108,7 @@
"bundle": "cities-internet",
"scriptUrl": "./cities-internet/cities-internet.js",
"output": "dx-maps/cities-internet/cities-internet.js",
"integrity": "sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR",
"integrity": "sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg",
"elements": [
"cities-internet-map"
],
@ -126,7 +126,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-list/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=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -141,7 +141,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -156,7 +156,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/data-tables/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=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
}
]
@ -165,7 +165,7 @@
"bundle": "country-posters",
"scriptUrl": "./country-posters/country-posters.js",
"output": "dx-maps/country-posters/country-posters.js",
"integrity": "sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx",
"integrity": "sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA",
"elements": [
"country-posters-map"
],
@ -187,7 +187,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
},
{
@ -202,7 +202,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/country-poster-wall/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=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
},
{
@ -217,7 +217,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
}
]
@ -226,7 +226,7 @@
"bundle": "dashboard-plus-grid",
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
"output": "dx-maps/dashboard-plus-grid/dashboard-plus-grid.js",
"integrity": "sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC",
"integrity": "sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr",
"elements": [
"dashboard-plus-grid"
],
@ -248,7 +248,7 @@
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
"embed": {
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
},
"instances": [
{
@ -272,7 +272,7 @@
"bundle": "demo-map",
"scriptUrl": "./demo-map/demo-map.js",
"output": "dx-maps/demo-map/demo-map.js",
"integrity": "sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI",
"integrity": "sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t",
"elements": [
"demo-map"
],
@ -290,7 +290,7 @@
"scriptUrl": "./demo-map/demo-map.js",
"embed": {
"iframe": "<iframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></demo-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></demo-map>"
},
"instances": [
{
@ -317,7 +317,7 @@
"bundle": "doxa-maps-spa",
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
"integrity": "sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8",
"integrity": "sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw",
"elements": [
"doxa-maps-spa"
],
@ -344,7 +344,7 @@
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
"embed": {
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/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=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
},
"instances": [
{
@ -371,7 +371,7 @@
"bundle": "doxa-research-map",
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
"integrity": "sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW",
"integrity": "sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk",
"elements": [
"doxa-research-map"
],
@ -389,7 +389,7 @@
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
},
"instances": [
{
@ -415,7 +415,7 @@
"bundle": "doxa-simple-map",
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"output": "dx-maps/doxa-simple-map/doxa-simple-map.js",
"integrity": "sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq",
"integrity": "sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h",
"elements": [
"doxa-map",
"doxa-simple-map"
@ -434,7 +434,7 @@
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-map>"
},
"instances": [
{
@ -604,7 +604,7 @@
"bundle": "gospel-internet",
"scriptUrl": "./gospel-internet/gospel-internet.js",
"output": "dx-maps/gospel-internet/gospel-internet.js",
"integrity": "sha384-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e",
"integrity": "sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y",
"elements": [
"gospel-internet-board"
],
@ -623,7 +623,7 @@
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
},
"instances": [
{
@ -723,7 +723,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk",
"integrity": "sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok",
"elements": [
"gospel-resources-map"
],
@ -745,7 +745,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -760,7 +760,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -775,7 +775,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -790,7 +790,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -805,7 +805,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]
@ -814,7 +814,7 @@
"bundle": "my-upg-100-list",
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
"integrity": "sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn",
"integrity": "sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF",
"elements": [
"my-upg-100-list-map"
],
@ -836,7 +836,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/poster-wall/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=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
},
{
@ -851,7 +851,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
},
{
@ -866,7 +866,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
}
]
@ -938,7 +938,7 @@
"bundle": "plugin-studio",
"scriptUrl": "./plugin-studio/plugin-studio.js",
"output": "dx-maps/plugin-studio/plugin-studio.js",
"integrity": "sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z",
"integrity": "sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu",
"elements": [
"plugin-studio"
],
@ -968,7 +968,7 @@
"scriptUrl": "./plugin-studio/plugin-studio.js",
"embed": {
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/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=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
},
"instances": [
{
@ -995,7 +995,7 @@
"bundle": "pplr-data-maps",
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
"integrity": "sha384-1N834moirmq1zevhRzlQm1tsVOwx2hFpLDc4YdpHeW6/hoiXtLqgQ1zTrwXPfkh8",
"integrity": "sha384-PrNoOug2lEoTkFJmTpjOY1uweCo/CV5JEiVs6qbHKQeUzv40KJ9m5zx2FB+z1di0",
"elements": [
"pplr-data-maps"
],
@ -1013,7 +1013,7 @@
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
"embed": {
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-1N834moirmq1zevhRzlQm1tsVOwx2hFpLDc4YdpHeW6/hoiXtLqgQ1zTrwXPfkh8\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-PrNoOug2lEoTkFJmTpjOY1uweCo/CV5JEiVs6qbHKQeUzv40KJ9m5zx2FB+z1di0\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
},
"bundle": "pplr-data-maps"
}
@ -1050,7 +1050,7 @@
"bundle": "regions-dashboard",
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
"integrity": "sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm",
"integrity": "sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn",
"elements": [
"regions-dashboard"
],
@ -1072,7 +1072,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
},
{
@ -1087,7 +1087,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/regions-list/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
},
{
@ -1102,7 +1102,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
}
]
@ -1111,7 +1111,7 @@
"bundle": "research-dashboard",
"scriptUrl": "./research-dashboard/research-dashboard.js",
"output": "dx-maps/research-dashboard/research-dashboard.js",
"integrity": "sha384-UE1W1z0oqOp9TmPxZ2U76eYXeYkPV5sXKczPbPW8D7LBEZ0U3u4GKBZUzVSlGfRo",
"integrity": "sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1",
"elements": [
"research-dashboard-map"
],
@ -1129,7 +1129,7 @@
"scriptUrl": "./research-dashboard/research-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-UE1W1z0oqOp9TmPxZ2U76eYXeYkPV5sXKczPbPW8D7LBEZ0U3u4GKBZUzVSlGfRo\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
},
"bundle": "research-dashboard"
}
@ -1185,7 +1185,7 @@
"bundle": "rudder-voice",
"scriptUrl": "./rudder-voice/rudder-voice.js",
"output": "dx-maps/rudder-voice/rudder-voice.js",
"integrity": "sha384-lHpK3+oBzByGH1hRsz64N7FbKCLl5q6HsVdpSZuv4MHC3PYjYbw0CxF12gnycL/5",
"integrity": "sha384-mPb2Q/qsmkqwX6e5QOD95dq551HeIfvvDHm43RjEyWx4IBphNGJov8Er5cQCf/Ey",
"elements": [
"rudder-voice"
],
@ -1206,7 +1206,7 @@
"scriptUrl": "./rudder-voice/rudder-voice.js",
"embed": {
"iframe": "<iframe src=\"./rudder-voice/rudder-voice/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=\"./rudder-voice/rudder-voice.js\" integrity=\"sha384-lHpK3+oBzByGH1hRsz64N7FbKCLl5q6HsVdpSZuv4MHC3PYjYbw0CxF12gnycL/5\" crossorigin=\"anonymous\"></script>\n<rudder-voice profile-config='{\"profile\":\"rudder-voice\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></rudder-voice>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./rudder-voice/rudder-voice.js\" integrity=\"sha384-mPb2Q/qsmkqwX6e5QOD95dq551HeIfvvDHm43RjEyWx4IBphNGJov8Er5cQCf/Ey\" crossorigin=\"anonymous\"></script>\n<rudder-voice profile-config='{\"profile\":\"rudder-voice\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></rudder-voice>"
}
}
]
@ -1261,7 +1261,7 @@
"bundle": "upg-neighbor",
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
"output": "dx-maps/upg-neighbor/upg-neighbor.js",
"integrity": "sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz",
"integrity": "sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3",
"elements": [
"upg-neighbor"
],
@ -1279,7 +1279,7 @@
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
"embed": {
"iframe": "<iframe src=\"./upg-neighbor/upg-neighbor/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz\" crossorigin=\"anonymous\"></script>\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3\" crossorigin=\"anonymous\"></script>\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
},
"instances": [
{

File diff suppressed because one or more lines are too long

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
<script src="../doxa-research-map.js" integrity="sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW" crossorigin="anonymous"></script>
<script src="../doxa-research-map.js" integrity="sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -33,7 +33,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
<script src="../../doxa-research-map.js" integrity="sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW" crossorigin="anonymous"></script>
<script src="../../doxa-research-map.js" integrity="sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../doxa-simple-map.js" integrity="sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq" crossorigin="anonymous"></script>
<script src="../doxa-simple-map.js" integrity="sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <doxa-map> custom element. -->
<script src="../../doxa-simple-map.js" integrity="sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq" crossorigin="anonymous"></script>
<script src="../../doxa-simple-map.js" integrity="sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,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-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -107,6 +107,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -133,6 +133,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -19,6 +19,6 @@
</head>
<body>
<plugin-studio tree-base="."></plugin-studio>
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z" crossorigin="anonymous"></script>
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu" crossorigin="anonymous"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -12,7 +12,7 @@
"bundle": "all-people-groups",
"scriptUrl": "./all-people-groups/all-people-groups.js",
"output": "dx-maps/all-people-groups/all-people-groups.js",
"integrity": "sha384-cJcadyELOZmDNp2L6R0Er4BZzjgkvLOVC7ojcDewUqDhO7sT0of0bhz12cFDdgsE",
"integrity": "sha384-Tc/Jinjihx10hSKgNMFL/QRW/1aVqB+6Fp4wxiAi4ACneQYIS3iRMM8lvkL9Mx2s",
"elements": [
"all-people-groups"
],
@ -30,7 +30,7 @@
"scriptUrl": "./all-people-groups/all-people-groups.js",
"embed": {
"iframe": "<iframe src=\"./all-people-groups/all-people-groups/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-cJcadyELOZmDNp2L6R0Er4BZzjgkvLOVC7ojcDewUqDhO7sT0of0bhz12cFDdgsE\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></all-people-groups>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./all-people-groups/all-people-groups.js\" integrity=\"sha384-Tc/Jinjihx10hSKgNMFL/QRW/1aVqB+6Fp4wxiAi4ACneQYIS3iRMM8lvkL9Mx2s\" crossorigin=\"anonymous\"></script>\n<all-people-groups profile-config='{\"profile\":\"all-people-groups\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></all-people-groups>"
},
"bundle": "all-people-groups"
}
@ -108,7 +108,7 @@
"bundle": "cities-internet",
"scriptUrl": "./cities-internet/cities-internet.js",
"output": "dx-maps/cities-internet/cities-internet.js",
"integrity": "sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR",
"integrity": "sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg",
"elements": [
"cities-internet-map"
],
@ -126,7 +126,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-list/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=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -141,7 +141,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/connectivity-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"connectivity-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
},
{
@ -156,7 +156,7 @@
"scriptUrl": "./cities-internet/cities-internet.js",
"embed": {
"iframe": "<iframe src=\"./cities-internet/data-tables/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=\"./cities-internet/cities-internet.js\" integrity=\"sha384-ULlB/DCzAyaHfrfBV9071oUglClX87X6op2tSg2vSvQMt8gKr52LhOFALEF89zBR\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./cities-internet/cities-internet.js\" integrity=\"sha384-S4DQQmFE0K4BdigO8mueo8Xz7q42arGcfiFP4hiSsT58FTVE4KxwidiM8pQvd3Wg\" crossorigin=\"anonymous\"></script>\n<cities-internet-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></cities-internet-map>"
}
}
]
@ -165,7 +165,7 @@
"bundle": "country-posters",
"scriptUrl": "./country-posters/country-posters.js",
"output": "dx-maps/country-posters/country-posters.js",
"integrity": "sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx",
"integrity": "sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA",
"elements": [
"country-posters-map"
],
@ -187,7 +187,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/countries-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"countries-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
},
{
@ -202,7 +202,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/country-poster-wall/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=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
},
{
@ -217,7 +217,7 @@
"scriptUrl": "./country-posters/country-posters.js",
"embed": {
"iframe": "<iframe src=\"./country-posters/country-posters-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-CqHCKNyX+hIRryJl2+dUn5DkS3x9QHpa+5ZHSl5ejGW8jKL1gk/QNUgBV8oayQkx\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./country-posters/country-posters.js\" integrity=\"sha384-TGcGt/DMzMTUXCS01z2XJg/kDnpHTQXavyILjh/8PKU7rxGW+PBALzFWZGKmRJKA\" crossorigin=\"anonymous\"></script>\n<country-posters-map profile-config='{\"profile\":\"country-posters-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></country-posters-map>"
}
}
]
@ -226,7 +226,7 @@
"bundle": "dashboard-plus-grid",
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
"output": "dx-maps/dashboard-plus-grid/dashboard-plus-grid.js",
"integrity": "sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC",
"integrity": "sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr",
"elements": [
"dashboard-plus-grid"
],
@ -248,7 +248,7 @@
"scriptUrl": "./dashboard-plus-grid/dashboard-plus-grid.js",
"embed": {
"iframe": "<iframe src=\"./dashboard-plus-grid/dashboard-plus-grid/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-ZZ1Wj19lI8oxxNWcjAbswTiGdjEqmyCDS9t8DrIrVxxi9snTDz0384Htexgt89vC\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./dashboard-plus-grid/dashboard-plus-grid.js\" integrity=\"sha384-nr6tMv3MzTLdSlvOzIeG2D/HWyjrT2O2VWT9GqYcFt5Hifgo1IT+y8hPAdhncmEr\" crossorigin=\"anonymous\"></script>\n<dashboard-plus-grid profile-config='{\"profile\":\"dashboard-plus-grid\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></dashboard-plus-grid>"
},
"instances": [
{
@ -272,7 +272,7 @@
"bundle": "demo-map",
"scriptUrl": "./demo-map/demo-map.js",
"output": "dx-maps/demo-map/demo-map.js",
"integrity": "sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI",
"integrity": "sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t",
"elements": [
"demo-map"
],
@ -290,7 +290,7 @@
"scriptUrl": "./demo-map/demo-map.js",
"embed": {
"iframe": "<iframe src=\"./demo-map/demo-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-x1UQlXQ2iVJNVLgwKJpZBzW4cL70qaew/WCF3swhmauP96El87iogu4YY1zLAOtI\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></demo-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./demo-map/demo-map.js\" integrity=\"sha384-AzsSNpv90I/Ev5e1kYJeFV5h1ETxw9kE092t7jV3nfUVLOpIIccfSooACb4bd86t\" crossorigin=\"anonymous\"></script>\n<demo-map profile-config='{\"profile\":\"demo-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></demo-map>"
},
"instances": [
{
@ -317,7 +317,7 @@
"bundle": "doxa-maps-spa",
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
"output": "dx-maps/doxa-maps-spa/doxa-maps-spa.js",
"integrity": "sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8",
"integrity": "sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw",
"elements": [
"doxa-maps-spa"
],
@ -344,7 +344,7 @@
"scriptUrl": "./doxa-maps-spa/doxa-maps-spa.js",
"embed": {
"iframe": "<iframe src=\"./doxa-maps-spa/doxa-maps-spa/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=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-VIqwutIFWsxqEd/+MbGvhkTl8HFNyFaVODUb4e77KV6aVUTqpkjgT5SULi0srZo8\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-maps-spa/doxa-maps-spa.js\" integrity=\"sha384-rLTDkqumxtv1rDoCpF7Gubflil8YbosAnEN741ue/oml2btEkGBJrHoLcERx3Iiw\" crossorigin=\"anonymous\"></script>\n<doxa-maps-spa profile-config='{\"profile\":\"doxa-maps-spa\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-maps-spa>"
},
"instances": [
{
@ -371,7 +371,7 @@
"bundle": "doxa-research-map",
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
"integrity": "sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW",
"integrity": "sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk",
"elements": [
"doxa-research-map"
],
@ -389,7 +389,7 @@
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-research-map/research-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-Gfi3otYfltimAH5aa3tlX3B1VtWt0G/USTvHSNVeoGN7mkUZMbTyuBoc8/dH5UzW\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-zU1NN/Z+gtNTLnjiCWaRd+Vxh7IjVZvgcnEm8ApmXPxQP4TazThQt0LjgF95vJzk\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
},
"instances": [
{
@ -415,7 +415,7 @@
"bundle": "doxa-simple-map",
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"output": "dx-maps/doxa-simple-map/doxa-simple-map.js",
"integrity": "sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq",
"integrity": "sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h",
"elements": [
"doxa-map",
"doxa-simple-map"
@ -434,7 +434,7 @@
"scriptUrl": "./doxa-simple-map/doxa-simple-map.js",
"embed": {
"iframe": "<iframe src=\"./doxa-simple-map/doxa-simple-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-sixS8+nfwi9jIcTBQuACJnSKoVaPqTDalZn4P6a+sxSkolG5LzudDdL7OTbBVUAq\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./doxa-simple-map/doxa-simple-map.js\" integrity=\"sha384-2DrYMVbr/zV3EvnpYFJeVAmhPis6p0+LCio1EcMssuDMdMRpQDrkIR+2zPnAKA3h\" crossorigin=\"anonymous\"></script>\n<doxa-map profile-config='{\"profile\":\"doxa-simple-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-map>"
},
"instances": [
{
@ -604,7 +604,7 @@
"bundle": "gospel-internet",
"scriptUrl": "./gospel-internet/gospel-internet.js",
"output": "dx-maps/gospel-internet/gospel-internet.js",
"integrity": "sha384-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e",
"integrity": "sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y",
"elements": [
"gospel-internet-board"
],
@ -623,7 +623,7 @@
"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": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-UzIUa443rr6cg9ziwap8CAePtEHFukZtErU3v1owVKjseb5WNyq8oDDH6b1lXa5e\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-1QKATO2zc5eFQVqHLIMkyHx2RcXSpvb2U/+1i2wyQFAy9WQPCR449qwFFu1+8S/Y\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
},
"instances": [
{
@ -723,7 +723,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "dx-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk",
"integrity": "sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok",
"elements": [
"gospel-resources-map"
],
@ -745,7 +745,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -760,7 +760,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -775,7 +775,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -790,7 +790,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/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=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -805,7 +805,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-XnjYCEDu/kYAvyuLGieORzo93RcsCZBL8aifSkvVHhC8pOjIUJ48ztu6Yli5uLMk\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-t+MOIkvkxYTWLjg7aebAFVPOd1Qpc1967r8HF2e++DoQuCihsVboYWJ5nTxTs1Ok\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]
@ -814,7 +814,7 @@
"bundle": "my-upg-100-list",
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"output": "dx-maps/my-upg-100-list/my-upg-100-list.js",
"integrity": "sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn",
"integrity": "sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF",
"elements": [
"my-upg-100-list-map"
],
@ -836,7 +836,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/poster-wall/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=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"poster-wall\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
},
{
@ -851,7 +851,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
},
{
@ -866,7 +866,7 @@
"scriptUrl": "./my-upg-100-list/my-upg-100-list.js",
"embed": {
"iframe": "<iframe src=\"./my-upg-100-list/upg-100-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./my-upg-100-list/my-upg-100-list.js\" integrity=\"sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF\" crossorigin=\"anonymous\"></script>\n<my-upg-100-list-map profile-config='{\"profile\":\"upg-100-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></my-upg-100-list-map>"
}
}
]
@ -938,7 +938,7 @@
"bundle": "plugin-studio",
"scriptUrl": "./plugin-studio/plugin-studio.js",
"output": "dx-maps/plugin-studio/plugin-studio.js",
"integrity": "sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z",
"integrity": "sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu",
"elements": [
"plugin-studio"
],
@ -968,7 +968,7 @@
"scriptUrl": "./plugin-studio/plugin-studio.js",
"embed": {
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/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=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
},
"instances": [
{
@ -995,7 +995,7 @@
"bundle": "pplr-data-maps",
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
"output": "dx-maps/pplr-data-maps/pplr-data-maps.js",
"integrity": "sha384-1N834moirmq1zevhRzlQm1tsVOwx2hFpLDc4YdpHeW6/hoiXtLqgQ1zTrwXPfkh8",
"integrity": "sha384-PrNoOug2lEoTkFJmTpjOY1uweCo/CV5JEiVs6qbHKQeUzv40KJ9m5zx2FB+z1di0",
"elements": [
"pplr-data-maps"
],
@ -1013,7 +1013,7 @@
"scriptUrl": "./pplr-data-maps/pplr-data-maps.js",
"embed": {
"iframe": "<iframe src=\"./pplr-data-maps/pplr-data-maps/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-1N834moirmq1zevhRzlQm1tsVOwx2hFpLDc4YdpHeW6/hoiXtLqgQ1zTrwXPfkh8\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./pplr-data-maps/pplr-data-maps.js\" integrity=\"sha384-PrNoOug2lEoTkFJmTpjOY1uweCo/CV5JEiVs6qbHKQeUzv40KJ9m5zx2FB+z1di0\" crossorigin=\"anonymous\"></script>\n<pplr-data-maps profile-config='{\"profile\":\"pplr-data-maps\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></pplr-data-maps>"
},
"bundle": "pplr-data-maps"
}
@ -1050,7 +1050,7 @@
"bundle": "regions-dashboard",
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"output": "dx-maps/regions-dashboard/regions-dashboard.js",
"integrity": "sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm",
"integrity": "sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn",
"elements": [
"regions-dashboard"
],
@ -1072,7 +1072,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/region-dashboards/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"region-dashboards\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
},
{
@ -1087,7 +1087,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/regions-list/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=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
},
{
@ -1102,7 +1102,7 @@
"scriptUrl": "./regions-dashboard/regions-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./regions-dashboard/regions-mfe/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./regions-dashboard/regions-dashboard.js\" integrity=\"sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn\" crossorigin=\"anonymous\"></script>\n<regions-dashboard profile-config='{\"profile\":\"regions-mfe\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></regions-dashboard>"
}
}
]
@ -1111,7 +1111,7 @@
"bundle": "research-dashboard",
"scriptUrl": "./research-dashboard/research-dashboard.js",
"output": "dx-maps/research-dashboard/research-dashboard.js",
"integrity": "sha384-UE1W1z0oqOp9TmPxZ2U76eYXeYkPV5sXKczPbPW8D7LBEZ0U3u4GKBZUzVSlGfRo",
"integrity": "sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1",
"elements": [
"research-dashboard-map"
],
@ -1129,7 +1129,7 @@
"scriptUrl": "./research-dashboard/research-dashboard.js",
"embed": {
"iframe": "<iframe src=\"./research-dashboard/research-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-UE1W1z0oqOp9TmPxZ2U76eYXeYkPV5sXKczPbPW8D7LBEZ0U3u4GKBZUzVSlGfRo\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./research-dashboard/research-dashboard.js\" integrity=\"sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1\" crossorigin=\"anonymous\"></script>\n<research-dashboard-map profile-config='{\"profile\":\"research-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></research-dashboard-map>"
},
"bundle": "research-dashboard"
}
@ -1185,7 +1185,7 @@
"bundle": "rudder-voice",
"scriptUrl": "./rudder-voice/rudder-voice.js",
"output": "dx-maps/rudder-voice/rudder-voice.js",
"integrity": "sha384-lHpK3+oBzByGH1hRsz64N7FbKCLl5q6HsVdpSZuv4MHC3PYjYbw0CxF12gnycL/5",
"integrity": "sha384-mPb2Q/qsmkqwX6e5QOD95dq551HeIfvvDHm43RjEyWx4IBphNGJov8Er5cQCf/Ey",
"elements": [
"rudder-voice"
],
@ -1206,7 +1206,7 @@
"scriptUrl": "./rudder-voice/rudder-voice.js",
"embed": {
"iframe": "<iframe src=\"./rudder-voice/rudder-voice/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=\"./rudder-voice/rudder-voice.js\" integrity=\"sha384-lHpK3+oBzByGH1hRsz64N7FbKCLl5q6HsVdpSZuv4MHC3PYjYbw0CxF12gnycL/5\" crossorigin=\"anonymous\"></script>\n<rudder-voice profile-config='{\"profile\":\"rudder-voice\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></rudder-voice>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./rudder-voice/rudder-voice.js\" integrity=\"sha384-mPb2Q/qsmkqwX6e5QOD95dq551HeIfvvDHm43RjEyWx4IBphNGJov8Er5cQCf/Ey\" crossorigin=\"anonymous\"></script>\n<rudder-voice profile-config='{\"profile\":\"rudder-voice\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></rudder-voice>"
}
}
]
@ -1261,7 +1261,7 @@
"bundle": "upg-neighbor",
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
"output": "dx-maps/upg-neighbor/upg-neighbor.js",
"integrity": "sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz",
"integrity": "sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3",
"elements": [
"upg-neighbor"
],
@ -1279,7 +1279,7 @@
"scriptUrl": "./upg-neighbor/upg-neighbor.js",
"embed": {
"iframe": "<iframe src=\"./upg-neighbor/upg-neighbor/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz\" crossorigin=\"anonymous\"></script>\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\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<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./upg-neighbor/upg-neighbor.js\" integrity=\"sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3\" crossorigin=\"anonymous\"></script>\n<upg-neighbor profile-config='{\"profile\":\"upg-neighbor\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></upg-neighbor>"
},
"instances": [
{

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <my-upg-100-list-map> custom element. -->
<script src="../my-upg-100-list.js" integrity="sha384-UtxhD3pdx8VlN8X+0eXrn/H9NMCdZ/CnetUSFSn+87dXJ5BujOv+zHhqTFo66fUn" crossorigin="anonymous"></script>
<script src="../my-upg-100-list.js" integrity="sha384-zRCUCInrjAg7FkO00XfsZOvzTzhYtbQRaSJZ35iU3moarmFRrf11f/DgtIMKk+mF" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
<script src="../plugin-studio.js" integrity="sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z" crossorigin="anonymous"></script>
<script src="../plugin-studio.js" integrity="sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
<script src="../../plugin-studio.js" integrity="sha384-I0ivoKwdWtB52mGsH9mxdIpcmw5wSt/iJE6G7yWMCJSkvGTFSZ8kmmdGU1RY8T/z" crossorigin="anonymous"></script>
<script src="../../plugin-studio.js" integrity="sha384-Awv4926G0miJpm4VD0vO4rC4SeeUIRQ4ASqg0kFuJt01iSVScplcaa9UkxE0a7nu" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <pplr-data-maps> custom element. -->
<script src="../pplr-data-maps.js" integrity="sha384-1N834moirmq1zevhRzlQm1tsVOwx2hFpLDc4YdpHeW6/hoiXtLqgQ1zTrwXPfkh8" crossorigin="anonymous"></script>
<script src="../pplr-data-maps.js" integrity="sha384-PrNoOug2lEoTkFJmTpjOY1uweCo/CV5JEiVs6qbHKQeUzv40KJ9m5zx2FB+z1di0" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
<script src="../regions-dashboard.js" integrity="sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm" crossorigin="anonymous"></script>
<script src="../regions-dashboard.js" integrity="sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
<script src="../regions-dashboard.js" integrity="sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm" crossorigin="anonymous"></script>
<script src="../regions-dashboard.js" integrity="sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -47,7 +47,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <regions-dashboard> custom element. -->
<script src="../regions-dashboard.js" integrity="sha384-jLyENsNqMoNv1HxETVpHL+aZ1mlnd8S9ZDQ9rgkffR2Bp8Ohvlg0U2UBPXir+Tsm" crossorigin="anonymous"></script>
<script src="../regions-dashboard.js" integrity="sha384-w6zwFLjOJosuTvBOW+4dL/wHKVKroj0nhIcmm1KjhVUMOhr6Mz1XVR/nonKyCSvn" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -679,6 +679,8 @@
}
.map-toolbar--square > * + * { border-top: 1px solid #ddd; }
.map-toolbar--square .hbg-ctrl { margin: 0; }
.map-toolbar--square .share-wrap { border-radius: 0; }
.map-toolbar--square .share-wrap::before { display: none; }
.map-toolbar--square > :first-child,
.map-toolbar--square > :first-child .mcb,
.map-toolbar--square > :first-child .hbg-btn { border-radius: 4px 4px 0 0; }

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <research-dashboard-map> custom element. -->
<script src="../research-dashboard.js" integrity="sha384-UE1W1z0oqOp9TmPxZ2U76eYXeYkPV5sXKczPbPW8D7LBEZ0U3u4GKBZUzVSlGfRo" crossorigin="anonymous"></script>
<script src="../research-dashboard.js" integrity="sha384-VjTrJSY6kovHUE0P6oWg1Px4MiJPId7KsKQZWT3EskLPhoRejSQS+6/TtJfMWBc1" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <rudder-voice> custom element. -->
<script src="../rudder-voice.js" integrity="sha384-lHpK3+oBzByGH1hRsz64N7FbKCLl5q6HsVdpSZuv4MHC3PYjYbw0CxF12gnycL/5" crossorigin="anonymous"></script>
<script src="../rudder-voice.js" integrity="sha384-mPb2Q/qsmkqwX6e5QOD95dq551HeIfvvDHm43RjEyWx4IBphNGJov8Er5cQCf/Ey" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <upg-neighbor> custom element. -->
<script src="../../upg-neighbor.js" integrity="sha384-/X5wsZAqk9m0eHK5OgfsWJxcFqTlCvBTHC6kZCPEpa0bdDUj65EYJFR2HUgnOCkz" crossorigin="anonymous"></script>
<script src="../../upg-neighbor.js" integrity="sha384-XkOdij2EnfJejAik4PUbvAKwA9iFb1mDVtmm23TEV5A7xX+i3efsd6yNzOSuXhn3" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -25,6 +25,7 @@ import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
import { autoSpaDevPlugin } from './internal/plugin-gallery/dev-plugin.mjs'
import { stripShadowCssCommentsPlugin } from './internal/vite-plugin-strip-shadow-css-comments.mjs'
import { backendDevPlugin, devBackendProxy } from './internal/backend-dev-plugin.mjs'
import { devSyncPlugin } from './internal/dev-sync-plugin.mjs'
import { fileURLToPath } from 'node:url'
import { resolve, dirname } from 'node:path'
import { readdirSync, statSync, existsSync } from 'node:fs'
@ -121,7 +122,7 @@ export default defineConfig(({ command, mode }) => {
// port. `--host` on the command line still overrides this for a deliberate LAN session.
// Local plugin backends (backend/, e.g. rudder-engine) are started by backendDevPlugin and reached
// through these same-origin routes, so a plugin calls /api/<name>/… in dev exactly as on desktop.
server: { host: '127.0.0.1', proxy: devBackendProxy() },
server: { host: '127.0.0.1', proxy: devBackendProxy(env) },
define: {
// ★ NO 'unsafe-eval' (CRITIC-4, 2026-09-26). vue-i18n's default message compiler builds each message
// with `new Function`, so a partner with a strict Content-Security-Policy saw every translated string
@ -162,7 +163,8 @@ export default defineConfig(({ command, mode }) => {
vue({ customElement: true }),
cssInjectedByJsPlugin(),
autoSpaDevPlugin(env.VITE_MAPBOX_TOKEN || process.env.VITE_MAPBOX_TOKEN || ''),
backendDevPlugin(__dirname),
backendDevPlugin(__dirname, env),
devSyncPlugin(__dirname, env),
],
resolve: {
alias: { '@map': resolve(__dirname, 'library') },