Merge remote-tracking branch 'origin/development' into bundler-2/bp-grid-locale
|
|
@ -279,13 +279,17 @@ function syncAttribClearance(root) {
|
|||
if (!el || !root?.querySelector) return
|
||||
let h = 0
|
||||
try {
|
||||
// TWO attribution flavours ship in this repo and the pill must clear EITHER:
|
||||
// .mapboxgl-ctrl-attrib — Mapbox's own control (useMapInstance, attributionControl:true)
|
||||
// .doxa-attribution — our own credit line (useMapAttribution.js) on the profiles
|
||||
// that construct with attributionControl:false
|
||||
// Both are licence-required credit, so both are obstacles, never things to cover.
|
||||
// THREE attribution flavours ship in this repo and the pill must clear ANY of them:
|
||||
// .mapboxgl-ctrl-attrib — Mapbox's own control (useMapInstance, attributionControl:true)
|
||||
// .maplibregl-ctrl-attrib — MapLibre's, the DEFAULT engine. Missing from this list, the pill
|
||||
// kept the 20px fallback and, on a 390px phone where the credit wraps
|
||||
// to two lines (37px), covered it by 35px on every map. Mapbox measured 0.
|
||||
// .doxa-attribution — our own credit line (useMapAttribution.js) on the profiles
|
||||
// that construct with attributionControl:false
|
||||
// All are licence-required credit, so all are obstacles, never things to cover.
|
||||
const a = root.querySelector(
|
||||
'.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib, .mapboxgl-ctrl-bottom-right .doxa-attribution, .doxa-attribution')
|
||||
'.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib, .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib, '
|
||||
+ '.mapboxgl-ctrl-bottom-right .doxa-attribution, .maplibregl-ctrl-bottom-right .doxa-attribution, .doxa-attribution')
|
||||
if (a) {
|
||||
// Measure the strip the control OCCUPIES from the bottom of the box we are anchored
|
||||
// in, not the control's own height: Mapbox adds a margin inside
|
||||
|
|
|
|||
|
|
@ -252,6 +252,41 @@ useShadowStyles(`
|
|||
.mi-foot input{ width:20px; height:20px; }
|
||||
|
||||
/* A phone gets the whole screen: a floating card with margins leaves too little room for a page. */
|
||||
/* ★ THE ONE-TIME NUDGE IS DESKTOP-ONLY, AND THE THRESHOLD IS MEASURED, NOT CHOSEN. The pointer
|
||||
is anchored beside the button and extends ~213px INWARD, straight across whatever the tab puts
|
||||
in its top strip. Measured on Deep Research, on the shared browser, worst overlap per width:
|
||||
390 Regions "Region Dashboards" 1416px^2 UPG-100 1428px^2
|
||||
768 Cities legend 6560 Gospel legend 6560 + input 6240 Regions selector 4200
|
||||
900 Cities legend 2432 Gospel legend 2496 + input 2176 Regions selector 3696
|
||||
1024 Cities CLEAN Gospel CLEAN Regions selector 2100
|
||||
1200 CLEAN CLEAN CLEAN
|
||||
1280 CLEAN CLEAN CLEAN
|
||||
UPG-100 measures the same shape independently: 768 over "Prayer Resources" AND "Map", 1024 over
|
||||
"Map", clear at 1200/1280/1440 -- in en AND ar.
|
||||
So it is not a phone problem, which is how it was first reported and first fixed: it persists
|
||||
to 1024 and only clears near 1200. A max-width:600px rule would have left 768, 900 and 1024
|
||||
broken on four tabs -- found because gospel counted PANELS (.gm-legend/.gm-sheet) as well as
|
||||
controls, which a control-only probe misses entirely.
|
||||
ARABIC IS MEASURED, not argued: via DX Life's /ar/ route (dir=rtl confirmed), the pointer is
|
||||
hidden and clean at 390, 768 and 1024, and at 1440 it mirrors to the start side (x=104) and is
|
||||
clean there too.
|
||||
THE RULE IS ITS OWN BLOCK, deliberately: the 600px block below also full-screens the dialog,
|
||||
and this has nothing to do with the phone sheet. The .98 covers fractional viewport widths
|
||||
under browser zoom.
|
||||
Hiding it below the measured clear width is the only rule that holds everywhere: the button it
|
||||
points at is untouched, so nothing becomes unreachable, and a hint that covers a map's own
|
||||
legend, search box or view switcher is worse than no hint.
|
||||
Two other shapes were measured and both were worse: stacking it below the button traded one
|
||||
collision for five (Gospel's "Resources found" 2010px^2, plus the zoom +/- of three tabs), and
|
||||
hiding only its text still left 675px^2 on "Region Dashboards" and 900px^2 on Gospel's input.
|
||||
⚠ NOT A PLACEMENT CHANGE. The per-tab pos.narrow values in the shell's tabInfo are measured per
|
||||
tab (the buttons sit at x=8, 12, 294 and 346 across the seven tabs at 390); an inset-inline-*
|
||||
pinned here would win by specificity and silently flatten all of them. The button is
|
||||
placement's business; this rule is only about the hint. */
|
||||
@media (max-width:1199.98px){
|
||||
.mi-pointer{ display:none; }
|
||||
}
|
||||
|
||||
@media (max-width:600px){
|
||||
.mi-scrim{ padding:0; align-items:stretch; }
|
||||
.mi-dialog{ width:100%; max-height:none; height:100%; border-radius:0; }
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
<div class="dms-slot" :ref="el => setSlot(i, el)"></div>
|
||||
<!-- The tab's "what can this do for you?" button (library MapInfo), from src/tabInfo.js. It sits
|
||||
over the pane, top-right; profile-config info:false removes it. -->
|
||||
<MapInfo v-if="infoFor(t)" :key="'info-' + t.id" v-bind="infoProps(t)" :style="infoStyle(t)" :placement="infoPos(t).placement || 'top-right'"
|
||||
<MapInfo v-if="infoFor(t)" :key="'info-' + t.id" v-bind="infoProps(t)" :style="infoStyle(t)" :placement="infoPos(t).placement || 'top-right'" :class="{ 'dms-info-raise': infoPos(t).raise }"
|
||||
:assets-base="assetsBase" :locale="effectiveLocale" />
|
||||
<div v-if="t.state === 'loading'" class="dms-hint">{{ tr('loading', { label: tabLabel(t) }) }}</div>
|
||||
<div v-else-if="t.state === 'error'" class="dms-hint err">
|
||||
|
|
@ -1659,6 +1659,11 @@ export default defineComponent({
|
|||
documents this opt-out for exactly this case, and .vtl-host and plugin-studio's .ps-pane both set
|
||||
it. This pane was ported from .vtl-host and took two of its three lines. */
|
||||
.dms-pane { position: absolute; inset: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; --profile-min-h: 0; }
|
||||
/* A tab whose free corner lies over a positioned bar of the map's own (Big Picture's filter bar, z-index 55)
|
||||
raises the info BUTTON above that bar (src/tabInfo.js pos.raise). Only the button: the one-time pointer
|
||||
stays under the bar, so it covers no filter even visually. Measured: nothing interactive under the button,
|
||||
the button topmost at its centre, and a click opens the popup, at 1440, 1024 and 800, en and ar. */
|
||||
.mi.dms-info-raise .mi-btn { z-index: 60; }
|
||||
.dms-slot { position: relative; min-height: 100%; }
|
||||
.dms-hint {
|
||||
position: absolute; inset: 0; display: grid; place-items: center; text-align: center;
|
||||
|
|
|
|||
|
|
@ -22,23 +22,32 @@
|
|||
* pos.narrow overrides on a phone (the shell's `narrow`, max-width:760px), where the chrome differs:
|
||||
* Regions' and UPG-100's strip is full at its END (selector + Share) and empty at its START, so the
|
||||
* button goes to the start (placement 'top-left', which MapInfo resolves to the logical start, so
|
||||
* Arabic mirrors); Gospel's panel spans to 345px of 390, so its button takes the corner above the
|
||||
* zoom column. Measured with the same probe at 390 in en and ar.
|
||||
* ★ ADD AN EXAMPLE ONLY WHEN ITS FILE IS IN THE TREE. A missing file renders the popup's "not
|
||||
* available" box in front of the audience; an example that is not there yet is simply left out.
|
||||
* Arabic mirrors); Gospel's and Cities' legend panels span to 344px of 390, so their button takes the corner
|
||||
* above the zoom column. Measured with the same probe at 390 in en and ar.
|
||||
* ★ AN EXAMPLE'S FILES SHIP WITH IT. MapInfo drops an example whose lead image fails to load (quietly,
|
||||
* title and all), so a link can land before its files; but a popup is only worth opening once they are
|
||||
* in the tree, so land the two together.
|
||||
* ★ KEYS MUST NOT CONTAIN A DOT beyond the area separator: the gallery has no vue-i18n, so MapInfo
|
||||
* resolves through tStatic, which splits the path on "." and would never find a sentence-shaped key.
|
||||
*/
|
||||
// The UPG-100 zone's pre-generated packet ('full' variant) and card deck, shot once and shared: Simple
|
||||
// Research's packet is the same renderer, method and variant (usePosterPrints.printPacket, 'full'), so it
|
||||
// shows these pages too, CAPTIONED as an example zone, because their data is a UPG-100 zone and not a
|
||||
// Simple Research selection.
|
||||
const MEC = 'previews/examples/middle-east-core'
|
||||
const MEC_PAGES = Array.from({ length: 12 }, (_, i) => `${MEC}/packet-p${String(i + 1).padStart(2, '0')}.webp`)
|
||||
const MEC_CARDS = Array.from({ length: 70 }, (_, i) => `${MEC}/card-${String(i + 1).padStart(2, '0')}.webp`)
|
||||
|
||||
export const TAB_INFO = {
|
||||
'upg-100': {
|
||||
storageKey: 'upg-100',
|
||||
pos: { side: '56px', narrow: { placement: 'top-left', side: '12px' } },
|
||||
leadKey: 'mapInfo.tab.upg-100.lead',
|
||||
takeawayKey: 'mapInfo.tab.upg-100.takeaway',
|
||||
// The packet pages (12) and the card deck (70) join this list when their pre-generated shots land
|
||||
// in assets/previews/examples/middle-east-core/.
|
||||
examples: [
|
||||
{ kind: 'image', src: 'previews/middle-east-core.webp', full: 'posters/middle-east-core.html' },
|
||||
{ kind: 'pages', pages: MEC_PAGES },
|
||||
{ kind: 'deck', cards: MEC_CARDS },
|
||||
],
|
||||
},
|
||||
'regions-dashboard': {
|
||||
|
|
@ -58,7 +67,10 @@ export const TAB_INFO = {
|
|||
},
|
||||
'dashboard-plus-grid': {
|
||||
storageKey: 'dashboard-plus-grid',
|
||||
pos: { top: '46px' },
|
||||
// top 46px is the empty END of Big Picture's filter area at every width (1 row at 1440, 2 at 1024,
|
||||
// 3 at 800), but that bar is a positioned layer (z-index 55) painted above the button, which left it
|
||||
// unclickable (rega, 1440). raise lifts the BUTTON over the bar; the pointer stays under it.
|
||||
pos: { top: '46px', raise: true },
|
||||
leadKey: 'mapInfo.tab.dashboard-plus-grid.lead',
|
||||
takeawayKey: 'mapInfo.tab.dashboard-plus-grid.takeaway',
|
||||
// Big Picture's export is a spreadsheet, so its example is a real excerpt of one (sr): the six
|
||||
|
|
@ -87,7 +99,10 @@ export const TAB_INFO = {
|
|||
pos: { top: '56px', side: '56px' },
|
||||
leadKey: 'mapInfo.tab.research-map-plus-grid.lead',
|
||||
takeawayKey: 'mapInfo.tab.research-map-plus-grid.takeaway',
|
||||
examples: [],
|
||||
// Its own poster joins when rega's shot is in the tree.
|
||||
examples: [
|
||||
{ kind: 'pages', pages: MEC_PAGES, titleKey: 'mapInfo.tab.research-map-plus-grid.examplePacket' },
|
||||
],
|
||||
},
|
||||
'prayer-map': {
|
||||
storageKey: 'prayer-map',
|
||||
|
|
@ -98,7 +113,7 @@ export const TAB_INFO = {
|
|||
},
|
||||
'cities-internet': {
|
||||
storageKey: 'cities-internet',
|
||||
pos: { side: '56px' },
|
||||
pos: { side: '56px', narrow: { side: '4px' } },
|
||||
leadKey: 'mapInfo.tab.cities-internet.lead',
|
||||
takeawayKey: 'mapInfo.tab.cities-internet.takeaway',
|
||||
examples: [],
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 171 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
|
@ -46,7 +46,7 @@
|
|||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}`;function Lm(e){let t=0;for(let o=0;o<e.length;o++)t=(t<<5)-t+e.charCodeAt(o),t|=0;return"s"+Math.abs(t).toString(36)}const Cm={class:"pin-hint-pill"},Mm=["aria-label"],Em={__name:"PinHint",setup(e){const t=(H,j)=>qt(H)||j,o={"messages.pinHint.tapDot":"Tap a dot to see who still needs prayer"},{t:n,te:a}=iu("",{fallback:H=>o[H]}),s=De("uiStore",null),i=De("profileConfig",null),r=ce(()=>(s==null?void 0:s.theme)==="dark"),l=ce(()=>{var Q;const H=(Q=i==null?void 0:i.value)==null?void 0:Q.pinHintLabel;if(H)return H;const j="Tap a coloured dot — someone still needs prayer";try{return a("messages.pinHint.tapDot")?n("messages.pinHint.tapDot"):j}catch{return j}}),c=oe(!1),u=oe(!0);let f=null;const b=oe(!0);let v=[];const k=["inert","hidden","aria-hidden"];function A(H){const j=[];let Q=H;for(;Q;)Q.nodeType===1&&j.push(Q),Q=Q.parentNode||Q.host||null;return j}function N(H){return A(H).some(j=>j.hasAttribute("inert")||j.hasAttribute("hidden")||j.getAttribute("aria-hidden")==="true")}function x(H){const j=()=>{const Q=!N(H);Q!==b.value&&(b.value=Q,Q&&mo(z))};if(j(),!(typeof MutationObserver>"u"))for(const Q of A(H))try{const re=new MutationObserver(j);re.observe(Q,{attributes:!0,attributeFilter:k}),v.push(re)}catch{}}const w=oe(null);let $=null,_=null,S=null,M=null,T=null,P=null,y=[],K=null,q=null;function B(){c.value=!1}function R(H,j){var re;let Q=H==null?void 0:H.parentElement;for(let de=0;Q&&de<12;de++,Q=Q.parentElement){if(Q===j||(re=Q.classList)!=null&&re.contains("profile-loader"))return null;let me="";try{me=getComputedStyle(Q).position}catch{}if(me&&me!=="static"){const Ne=Q.getBoundingClientRect();if(Ne.height>=120&&Ne.width>=160)return Q}}return null}function J(H){var Q;const j=(Q=M==null?void 0:M.querySelector)==null?void 0:Q.call(M,".legend-mobile-sheet");if(!j)return 1/0;if(T&&P!==j){try{T.disconnect()}catch{}T=null}if(!T&&typeof ResizeObserver<"u")try{T=new ResizeObserver(()=>z()),T.observe(j),P=j}catch{T=null}try{const re=j.getBoundingClientRect();return!(re.height>16)||!(re.width>16)||H.right<=re.left||re.right<=H.left?1/0:re.top}catch{return 1/0}}function z(){const H=w.value;if(!(!H||!u.value||!b.value))try{H.style.removeProperty("--pin-hint-lift");const j=H.getBoundingClientRect();if(!j.height)return;const Q=Math.min(window.innerHeight,J(j)),re=Math.round(j.bottom-Q);re>0&&H.style.setProperty("--pin-hint-lift",re+8+"px")}catch{}}function X(H){const j=w.value;if(!j||!(H!=null&&H.querySelector))return;let Q=0;try{const de=H.querySelector(".mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib, .mapboxgl-ctrl-bottom-right .doxa-attribution, .doxa-attribution");if(de){const me=de.getBoundingClientRect(),Ne=j.parentElement,ke=Ne?Ne.getBoundingClientRect():null;if(Q=ke?Math.max(me.height||0,ke.bottom-me.top):me.height||0,q!==de&&typeof ResizeObserver<"u"){if(S)try{S.disconnect()}catch{}q=de,S=new ResizeObserver(()=>X(H)),S.observe(de)}}}catch{}const re=Math.min(Math.max(Math.ceil(Q)||20,20),72);j.style.setProperty("--pin-hint-attrib-clear",re+"px"),z()}return $o(()=>{var re,de,me;const H=ft(),j=(me=(de=(re=H==null?void 0:H.proxy)==null?void 0:re.$el)==null?void 0:de.getRootNode)==null?void 0:me.call(de);if(!j||typeof j.querySelector!="function")return;M=j;let Q=0;$=setInterval(()=>{Q++;const Ne=j.querySelector("canvas.maplibregl-canvas, canvas.mapboxgl-canvas");Ne?(clearInterval($),$=null,c.value=!0,mo(()=>{const ke=R(Ne,j),Ve=w.value;if(ke&&Ve&&Ve.parentElement!==ke)try{ke.appendChild(Ve),_=ke}catch{}if(ke&&x(ke),ke&&typeof IntersectionObserver<"u")try{f=new IntersectionObserver(xe=>{const $e=xe[xe.length-1],Ue=!!$e&&$e.isIntersecting&&$e.intersectionRatio>=.2;Ue!==u.value&&(u.value=Ue,Ue&&mo(z))},{threshold:[0,.2,.5]}),f.observe(ke)}catch{}X(j),z(),y.push(setTimeout(z,1200),setTimeout(z,3e3),setTimeout(z,6e3));try{const xe=w.value&&w.value.offsetParent||null;if(xe&&typeof ResizeObserver<"u"){if(K)try{K.disconnect()}catch{}K=new ResizeObserver(()=>z()),K.observe(xe)}}catch{}})):Q>40&&(clearInterval($),$=null)},300)}),Fo(()=>{var H;if($&&clearInterval($),f){try{f.disconnect()}catch{}f=null}for(const j of v)try{j.disconnect()}catch{}if(v=[],S){try{S.disconnect()}catch{}S=null}if(q=null,K){try{K.disconnect()}catch{}K=null}if(T){try{T.disconnect()}catch{}T=null}P=null;for(const j of y)clearTimeout(j);if(y=[],M=null,_&&((H=w.value)==null?void 0:H.parentElement)===_)try{_.removeChild(w.value)}catch{}_=null}),Uo(`
|
||||
}`;function Lm(e){let t=0;for(let o=0;o<e.length;o++)t=(t<<5)-t+e.charCodeAt(o),t|=0;return"s"+Math.abs(t).toString(36)}const Cm={class:"pin-hint-pill"},Mm=["aria-label"],Em={__name:"PinHint",setup(e){const t=(H,j)=>qt(H)||j,o={"messages.pinHint.tapDot":"Tap a dot to see who still needs prayer"},{t:n,te:a}=iu("",{fallback:H=>o[H]}),s=De("uiStore",null),i=De("profileConfig",null),r=ce(()=>(s==null?void 0:s.theme)==="dark"),l=ce(()=>{var Q;const H=(Q=i==null?void 0:i.value)==null?void 0:Q.pinHintLabel;if(H)return H;const j="Tap a coloured dot — someone still needs prayer";try{return a("messages.pinHint.tapDot")?n("messages.pinHint.tapDot"):j}catch{return j}}),c=oe(!1),u=oe(!0);let f=null;const b=oe(!0);let v=[];const k=["inert","hidden","aria-hidden"];function A(H){const j=[];let Q=H;for(;Q;)Q.nodeType===1&&j.push(Q),Q=Q.parentNode||Q.host||null;return j}function N(H){return A(H).some(j=>j.hasAttribute("inert")||j.hasAttribute("hidden")||j.getAttribute("aria-hidden")==="true")}function x(H){const j=()=>{const Q=!N(H);Q!==b.value&&(b.value=Q,Q&&mo(z))};if(j(),!(typeof MutationObserver>"u"))for(const Q of A(H))try{const re=new MutationObserver(j);re.observe(Q,{attributes:!0,attributeFilter:k}),v.push(re)}catch{}}const w=oe(null);let $=null,_=null,S=null,M=null,T=null,P=null,y=[],K=null,q=null;function B(){c.value=!1}function R(H,j){var re;let Q=H==null?void 0:H.parentElement;for(let de=0;Q&&de<12;de++,Q=Q.parentElement){if(Q===j||(re=Q.classList)!=null&&re.contains("profile-loader"))return null;let me="";try{me=getComputedStyle(Q).position}catch{}if(me&&me!=="static"){const Ne=Q.getBoundingClientRect();if(Ne.height>=120&&Ne.width>=160)return Q}}return null}function J(H){var Q;const j=(Q=M==null?void 0:M.querySelector)==null?void 0:Q.call(M,".legend-mobile-sheet");if(!j)return 1/0;if(T&&P!==j){try{T.disconnect()}catch{}T=null}if(!T&&typeof ResizeObserver<"u")try{T=new ResizeObserver(()=>z()),T.observe(j),P=j}catch{T=null}try{const re=j.getBoundingClientRect();return!(re.height>16)||!(re.width>16)||H.right<=re.left||re.right<=H.left?1/0:re.top}catch{return 1/0}}function z(){const H=w.value;if(!(!H||!u.value||!b.value))try{H.style.removeProperty("--pin-hint-lift");const j=H.getBoundingClientRect();if(!j.height)return;const Q=Math.min(window.innerHeight,J(j)),re=Math.round(j.bottom-Q);re>0&&H.style.setProperty("--pin-hint-lift",re+8+"px")}catch{}}function X(H){const j=w.value;if(!j||!(H!=null&&H.querySelector))return;let Q=0;try{const de=H.querySelector(".mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-attrib, .maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib, .mapboxgl-ctrl-bottom-right .doxa-attribution, .maplibregl-ctrl-bottom-right .doxa-attribution, .doxa-attribution");if(de){const me=de.getBoundingClientRect(),Ne=j.parentElement,ke=Ne?Ne.getBoundingClientRect():null;if(Q=ke?Math.max(me.height||0,ke.bottom-me.top):me.height||0,q!==de&&typeof ResizeObserver<"u"){if(S)try{S.disconnect()}catch{}q=de,S=new ResizeObserver(()=>X(H)),S.observe(de)}}}catch{}const re=Math.min(Math.max(Math.ceil(Q)||20,20),72);j.style.setProperty("--pin-hint-attrib-clear",re+"px"),z()}return $o(()=>{var re,de,me;const H=ft(),j=(me=(de=(re=H==null?void 0:H.proxy)==null?void 0:re.$el)==null?void 0:de.getRootNode)==null?void 0:me.call(de);if(!j||typeof j.querySelector!="function")return;M=j;let Q=0;$=setInterval(()=>{Q++;const Ne=j.querySelector("canvas.maplibregl-canvas, canvas.mapboxgl-canvas");Ne?(clearInterval($),$=null,c.value=!0,mo(()=>{const ke=R(Ne,j),Ve=w.value;if(ke&&Ve&&Ve.parentElement!==ke)try{ke.appendChild(Ve),_=ke}catch{}if(ke&&x(ke),ke&&typeof IntersectionObserver<"u")try{f=new IntersectionObserver(xe=>{const $e=xe[xe.length-1],Ue=!!$e&&$e.isIntersecting&&$e.intersectionRatio>=.2;Ue!==u.value&&(u.value=Ue,Ue&&mo(z))},{threshold:[0,.2,.5]}),f.observe(ke)}catch{}X(j),z(),y.push(setTimeout(z,1200),setTimeout(z,3e3),setTimeout(z,6e3));try{const xe=w.value&&w.value.offsetParent||null;if(xe&&typeof ResizeObserver<"u"){if(K)try{K.disconnect()}catch{}K=new ResizeObserver(()=>z()),K.observe(xe)}}catch{}})):Q>40&&(clearInterval($),$=null)},300)}),Fo(()=>{var H;if($&&clearInterval($),f){try{f.disconnect()}catch{}f=null}for(const j of v)try{j.disconnect()}catch{}if(v=[],S){try{S.disconnect()}catch{}S=null}if(q=null,K){try{K.disconnect()}catch{}K=null}if(T){try{T.disconnect()}catch{}T=null}P=null;for(const j of y)clearTimeout(j);if(y=[],M=null,_&&((H=w.value)==null?void 0:H.parentElement)===_)try{_.removeChild(w.value)}catch{}_=null}),Uo(`
|
||||
@media print { .pin-hint { display: none !important; } }
|
||||
.pin-hint { position: absolute; left: 50%;
|
||||
bottom: calc(var(--pin-hint-attrib-clear, 20px) + 12px + var(--pin-hint-lift, 0px)); transform: translateX(-50%);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,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-iuTg/9NOhnbwRr9AmR7DEZXqNBIfrw8AHrgHD6U+ZcJGDHXFH5uSQTDzbfIAPA9e" crossorigin="anonymous"></script>
|
||||
<script src="../all-people-groups.js" integrity="sha384-1tlJDUPXPgioha7BM6CPslfjD+zvorBn1KsXs2G3qBhe28oxuckN/0pAG6hfo3sz" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |