{"id":15995,"date":"2026-10-30T14:30:59","date_gmt":"2026-10-30T21:30:59","guid":{"rendered":"https:\/\/garymcavoy.com\/karte-der-vatikanstadt\/"},"modified":"2026-10-30T17:00:16","modified_gmt":"2026-10-31T00:00:16","slug":"karte-der-vatikanstadt","status":"publish","type":"page","link":"https:\/\/garymcavoy.com\/de\/karte-der-vatikanstadt\/","title":{"rendered":"Karte der Vatikanstadt"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"15995\" class=\"elementor elementor-15995 elementor-15962\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ab3f9e e-con e-atomic-element e-flexbox-base e-default-div e-10ece7a \" data-id=\"6ab3f9e\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"6ab3f9e\" data-e-type=\"e-flexbox\" data-id=\"6ab3f9e\">\n    \t\t<div class=\"elementor-element elementor-element-3b7811a elementor-widget elementor-widget-html\" data-id=\"3b7811a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- ============================================================\n     VATICAN CITY \u2014 INTERACTIVE PAINTED MAP\n     Paste this entire file into one Elementor \"HTML\" widget.\n     Before pasting, put the web address of your painting in\n     BASE_IMAGE (in SETTINGS, near the top of the script below).\n     Everything is scoped under #vmap-root, so it won\u2019t clash\n     with your theme.\n     ============================================================ -->\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin=\"\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:ital,wght@0,500;0,600;0,700;1,500;1,600&family=Inter:wght@400;500;600&family=Bitter:ital,wght@0,400;0,500;0,600;1,400;1,500&display=swap\" rel=\"stylesheet\">\n\n<div id=\"vmap-root\" class=\"is-dark\">\n  <div class=\"vm-stage\" tabindex=\"0\" aria-label=\"Interactive painted map of Vatican City. Drag to pan, scroll to zoom, Shift-drag to rotate and tilt.\">\n    <div class=\"vm-desk\"><\/div>\n    <div class=\"vm-plane\">\n      <img class=\"vm-img\" alt=\"Gemalte Vogelperspektive auf die Vatikanstadt\" draggable=\"false\">\n      <div class=\"vm-clouds\"><i><\/i><i><\/i><i><\/i><\/div>\n      <div class=\"vm-halo\"><span><\/span><span><\/span><\/div>\n    <\/div>\n    <canvas class=\"vm-life\" aria-hidden=\"true\"><\/canvas>\n    <div class=\"vm-occ\" aria-hidden=\"true\"><\/div>\n    <div class=\"vm-spot\"><\/div>\n    <div class=\"vm-pins\"><\/div>\n\n    <header class=\"vm-title vm-ui\">\n      <div class=\"vm-kicker\">Stato della Citt\u00e0 del Vaticano<\/div>\n      <h2>Innerhalb der Mauern<\/h2>\n      <p>Vierundzwanzig Orte in und um die p\u00e4pstliche Stadt, von den Archivgew\u00f6lben bis zur Kaserne der Schweizergarde.<\/p>\n    <\/header>\n\n    <aside class=\"vm-legend vm-ui is-closed\">\n      <button type=\"button\" class=\"vm-legend-head\" aria-expanded=\"false\"><span>Sehensw\u00fcrdigkeiten<\/span><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 12 12\" width=\"12\" height=\"12\"><path d=\"M2 4l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><\/svg><\/button>\n      <div class=\"vm-legend-body\"><\/div>\n    <\/aside>\n\n    <button type=\"button\" class=\"vm-tourbtn vm-ui\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M4 2.5v11l9-5.5z\" fill=\"currentColor\"><\/path><\/svg><span>Zur Tour<\/span><\/button>\n\n    <div class=\"vm-controls vm-ui\" role=\"toolbar\" aria-label=\"Map controls\">\n      <button type=\"button\" data-c=\"compass\" class=\"vm-compass\" title=\"Ansicht zur\u00fccksetzen (0)\" aria-label=\"Reset view\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 40 40\"><circle cx=\"20\" cy=\"20\" r=\"17\" fill=\"none\" stroke=\"currentColor\" stroke-opacity=\".35\"><\/circle><g class=\"vm-needle\"><path d=\"M20 5l4.5 15h-9z\" fill=\"#c0392b\"\/><path d=\"M20 35l-4.5-15h9z\" fill=\"currentColor\"\/><\/g><text x=\"20\" y=\"4.2\" text-anchor=\"middle\" font-size=\"5.5\" font-weight=\"700\" fill=\"currentColor\">N<\/text><\/svg><\/button>\n      <span class=\"vm-sep\"><\/span>\n      <button type=\"button\" data-c=\"in\" title=\"Vergr\u00f6\u00dfern (+)\" aria-label=\"Zoom in\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 20 20\"><path d=\"M10 4v12M4 10h12\" stroke=\"currentColor\" stroke-width=\"1.8\"><\/path><\/svg><\/button>\n      <button type=\"button\" data-c=\"out\" title=\"Verkleinern (\u2212)\" aria-label=\"Zoom out\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 20 20\"><path d=\"M4 10h12\" stroke=\"currentColor\" stroke-width=\"1.8\"><\/path><\/svg><\/button>\n      <span class=\"vm-sep\"><\/span>\n      <button type=\"button\" data-c=\"ccw\" title=\"Nach links drehen (Q)\" aria-label=\"Rotate left\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 20 20\"><path d=\"M5 8a6 6 0 1 1 0 4.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><path d=\"M3 4v4.5h4.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><\/svg><\/button>\n      <button type=\"button\" data-c=\"cw\" title=\"Nach rechts drehen (E)\" aria-label=\"Rotate right\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 20 20\"><path d=\"M15 8a6 6 0 1 0 0 4.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><path d=\"M17 4v4.5h-4.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><\/svg><\/button>\n      <button type=\"button\" data-c=\"tilt\" class=\"vm-tilt\" title=\"In 3D kippen (T)\" aria-label=\"Tilt in 3D\" aria-pressed=\"false\"><span>3D<\/span><\/button>\n      <span class=\"vm-sep\"><\/span>\n      <button type=\"button\" data-c=\"full\" title=\"Vollbild (F)\" aria-label=\"Full screen\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 20 20\"><path d=\"M3 7V3h4M13 3h4v4M17 13v4h-4M7 17H3v-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"><\/path><\/svg><\/button>\n    <\/div>\n\n    <div class=\"vm-hint vm-ui\"><\/div>\n\n    <div class=\"vm-tourbar vm-ui\" hidden=\"\">\n      <button type=\"button\" data-t=\"prev\" aria-label=\"Previous stop\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M10.5 3L5.5 8l5 5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><\/path><\/svg><\/button>\n      <button type=\"button\" data-t=\"pause\" aria-label=\"Pause tour\" class=\"vm-tb-play\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M5 3h2v10H5zM9 3h2v10H9z\" fill=\"currentColor\"><\/path><\/svg><\/button>\n      <button type=\"button\" data-t=\"next\" aria-label=\"Next stop\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M5.5 3l5 5-5 5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"><\/path><\/svg><\/button>\n      <div class=\"vm-tb-info\"><span class=\"vm-tb-count\"><\/span><span class=\"vm-tb-name\"><\/span><i class=\"vm-tb-prog\"><b><\/b><\/i><\/div>\n      <button type=\"button\" data-t=\"end\" class=\"vm-tb-end\">Tour beenden<\/button>\n    <\/div>\n\n    <div class=\"vm-card vm-ui\" hidden=\"\">\n      <button type=\"button\" class=\"vm-card-close\" aria-label=\"Close\">\u00d7<\/button>\n      <div class=\"vm-card-inner\"><\/div>\n    <\/div>\n\n     <div class=\"vm-fd vm-ui\" hidden=\"\" role=\"dialog\" aria-label=\"Ask Father Dominic\">\n      <button type=\"button\" class=\"vm-fd-close\" aria-label=\"Close Father Dominic and reset the map\" title=\"Karte schlie\u00dfen und zur\u00fccksetzen\">\u00d7<\/button>\n      <div class=\"vm-fd-slot\"><\/div>\n    <\/div>\n\n    <div class=\"vm-bless vm-ui\" hidden=\"\"><i><\/i><span><\/span><\/div>\n\n    <div class=\"vm-copy\">Kartendesign Copyright \u00a9 <span class=\"vm-copy-yr\">2026<\/span> Gary McAvoy. Alle Rechte vorbehalten.<\/div>\n    <div class=\"vm-msg\" hidden=\"\"><\/div>\n  <\/div>\n  <div class=\"vm-below\"><\/div>\n<\/div>\n\n<style>\n#vmap-root{\n  --ink:#2a2116; --ink-soft:#6b5a40; --paper:#f7f0df; --paper-2:#efe4cb; --gold:#b08d3c; --red:#8c1d18; --line:rgba(42,33,22,.22);\n  --desk-1:#3b2d1e; --desk-2:#120d08; --ui:#f7f0df; --ui-ink:#2a2116;\n  position:relative; box-sizing:border-box; width:100%; margin:0; padding:0; color:var(--ink);\n  font-family:\"Inter\",system-ui,-apple-system,\"Segoe UI\",sans-serif; line-height:1.5; -webkit-font-smoothing:antialiased;\n}\n#vmap-root.is-light{ --desk-1:#efe4cb; --desk-2:#d9c8a4; }\n#vmap-root *,#vmap-root *::before,#vmap-root *::after{box-sizing:border-box}\n#vmap-root button{font-family:inherit}\n\n\/* Stage & plane *\/\n#vmap-root .vm-stage{position:relative;width:100%;height:min(calc(100vh - 0px),max(560px,58vw));min-height:460px;overflow:hidden;outline:none;\n  cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;background:var(--desk-2)}\n#vmap-root .vm-stage.is-grabbing{cursor:grabbing}\n#vmap-root .vm-stage.is-orbit{cursor:ew-resize}\n#vmap-root .vm-desk{position:absolute;inset:0;background:radial-gradient(ellipse at 50% 45%,var(--desk-1) 0%,var(--desk-2) 78%)}\n#vmap-root .vm-desk::after{content:\"\";position:absolute;inset:0;opacity:.35;background-image:repeating-linear-gradient(92deg,rgba(255,255,255,.025) 0 2px,rgba(0,0,0,.03) 2px 5px)}\n#vmap-root .vm-plane{position:absolute;left:50%;top:50%;transform-origin:50% 50%;will-change:transform;\n  box-shadow:0 40px 90px -20px rgba(0,0,0,.75),0 10px 24px -8px rgba(0,0,0,.5);border-radius:2px;opacity:0;transition:opacity .9s ease}\n#vmap-root .vm-plane.is-ready{opacity:1}\n#vmap-root{--vm-tone:sepia(.22) saturate(.88) contrast(1.16) brightness(.9)}\n#vmap-root .vm-img{display:block;width:100%;height:100%;pointer-events:none;border-radius:2px;filter:var(--vm-tone)}\n#vmap-root .vm-occ canvas{filter:var(--vm-tone)}\n#vmap-root .vm-plane::after{content:\"\";position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 40px rgba(90,60,20,.35);border-radius:2px}\n\n\/* Drifting cloud shadows *\/\n#vmap-root .vm-clouds{position:absolute;inset:0;overflow:hidden;pointer-events:none;mix-blend-mode:multiply;\n  -webkit-mask-image:radial-gradient(ellipse 48% 46% at 55% 42%,#000 55%,transparent 100%);mask-image:radial-gradient(ellipse 48% 46% at 55% 42%,#000 55%,transparent 100%)}\n#vmap-root .vm-clouds i{position:absolute;width:38%;height:30%;border-radius:50%;background:radial-gradient(closest-side,rgba(40,30,60,.22),rgba(40,30,60,0));filter:blur(8px);animation:vm-drift 70s linear infinite}\n#vmap-root .vm-clouds i:nth-child(1){top:8%;left:-40%}\n#vmap-root .vm-clouds i:nth-child(2){top:46%;left:-40%;width:30%;height:24%;animation-duration:95s;animation-delay:-40s}\n#vmap-root .vm-clouds i:nth-child(3){top:24%;left:-40%;width:46%;height:34%;animation-duration:120s;animation-delay:-85s;opacity:.7}\n@keyframes vm-drift{from{transform:translateX(0)}to{transform:translateX(380%)}}\n\n\/* Halo on the active place (lies on the map and rotates with it) *\/\n#vmap-root .vm-halo{position:absolute;width:7%;aspect-ratio:1;transform:translate(-50%,-50%) scaleY(.62);pointer-events:none;opacity:0;transition:opacity .4s ease}\n#vmap-root .vm-halo.is-on{opacity:1}\n#vmap-root .vm-halo span{position:absolute;inset:0;border-radius:50%;border:2px solid rgba(255,214,120,.95);box-shadow:0 0 18px rgba(255,200,90,.7);animation:vm-ring 2.4s ease-out infinite}\n#vmap-root .vm-halo span:nth-child(2){animation-delay:1.2s}\n@keyframes vm-ring{0%{transform:scale(.35);opacity:1}100%{transform:scale(1.25);opacity:0}}\n\n\/* Living map layer: people, boats, traffic, birds *\/\n#vmap-root .vm-life{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}\n\/* the painting\u2019s own statues and buildings, redrawn above the traffic so it passes behind them *\/\n#vmap-root .vm-occ{position:absolute;left:50%;top:50%;transform-origin:50% 50%;pointer-events:none;will-change:transform;opacity:0;transition:opacity .9s ease}\n#vmap-root .vm-occ.is-ready{opacity:1}\n#vmap-root .vm-occ canvas{position:absolute;display:block}\n\n\/* Spotlight *\/\n#vmap-root .vm-spot{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .6s ease}\n#vmap-root .vm-spot.is-on{opacity:1}\n\n\/* Markers *\/\n#vmap-root .vm-pins{position:absolute;inset:0;pointer-events:none;z-index:3}\n#vmap-root .vm-pin{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none}\n#vmap-root .vm-pin.is-off{visibility:hidden}\n#vmap-root .vm-pin-in{position:absolute;left:0;top:0;transform:translate(-50%,-100%);display:flex;flex-direction:column;align-items:center;pointer-events:auto;cursor:pointer;\n  background:none;border:0;padding:0;margin:0;animation:vm-drop .7s cubic-bezier(.2,1.4,.4,1) backwards}\n#vmap-root .vm-pin-disc{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;background:var(--ink);color:#f7f0df;font:700 12.5px\/1 \"Inter\",sans-serif;\n  border:2px solid #f7f0df;box-shadow:0 4px 10px rgba(0,0,0,.45);transition:transform .2s ease,background .2s ease}\n#vmap-root .vm-pin.is-featured .vm-pin-disc{background:var(--red)}\n#vmap-root .vm-pin-stem{width:2px;height:12px;background:#f7f0df;box-shadow:0 0 0 1px rgba(42,33,22,.6)}\n#vmap-root .vm-pin-foot{width:8px;height:4px;border-radius:50%;background:rgba(0,0,0,.55);margin-top:-1px}\n#vmap-root .vm-pin-tag{position:absolute;bottom:52px;left:50%;transform:translate(-50%,4px);white-space:nowrap;background:rgba(247,240,223,.96);color:var(--ink);\n  font:600 12px\/1 \"Inter\",sans-serif;padding:7px 9px;border-radius:3px;box-shadow:0 6px 14px rgba(0,0,0,.35);opacity:0;transition:opacity .15s ease,transform .15s ease;pointer-events:none}\n#vmap-root .vm-pin-in:hover .vm-pin-disc,#vmap-root .vm-pin-in:focus-visible .vm-pin-disc,#vmap-root .vm-pin.is-active .vm-pin-disc{transform:translateY(-3px) scale(1.15)}\n#vmap-root .vm-pin-in:focus-visible{outline:none}\n#vmap-root .vm-pin-in:focus-visible .vm-pin-disc{box-shadow:0 0 0 3px #ffd678,0 4px 10px rgba(0,0,0,.45)}\n#vmap-root.is-touch .vm-pin-tag{display:none}\n#vmap-root .vm-pin.is-peek .vm-pin-tag{opacity:1;transform:translate(-50%,0)}\n@keyframes vm-drop{0%{opacity:0;transform:translate(-50%,-170%)}100%{opacity:1;transform:translate(-50%,-100%)}}\n\n\/* Shared parchment UI *\/\n#vmap-root .vm-ui{position:absolute;z-index:4}\n#vmap-root .vm-title,#vmap-root .vm-legend,#vmap-root .vm-controls,#vmap-root .vm-card,#vmap-root .vm-tourbar,#vmap-root .vm-tourbtn,#vmap-root .vm-hint{\n  background:rgba(247,240,223,.94);color:var(--ink);border:1px solid rgba(176,141,60,.55);box-shadow:0 0 0 3px rgba(247,240,223,.25),0 18px 40px -16px rgba(0,0,0,.6);\n  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}\n#vmap-root .vm-title{left:22px;top:22px;width:300px;padding:16px 20px 14px;border-radius:3px;cursor:default}\n#vmap-root .vm-kicker{font:600 10.5px\/1.2 \"Inter\",sans-serif;letter-spacing:.22em;text-transform:uppercase;color:var(--red)}\n#vmap-root .vm-title h2{font:600 34px\/1.02 \"Cormorant Garamond\",Georgia,serif;margin:6px 0 6px;color:var(--ink);letter-spacing:.01em}\n#vmap-root .vm-title p{margin:0;font:italic 500 15px\/1.35 \"Cormorant Garamond\",Georgia,serif;color:var(--ink-soft)}\n\n#vmap-root .vm-legend{left:22px;top:178px;width:300px;border-radius:3px;max-height:calc(100% - 200px);display:flex;flex-direction:column;overflow:hidden}\n#vmap-root .vm-legend-head{display:flex;align-items:center;justify-content:space-between;width:100%;background:none;border:0;padding:12px 18px;cursor:pointer;\n  font:700 12px\/1 \"Inter\",sans-serif;letter-spacing:.18em;text-transform:uppercase;color:var(--ink)}\n#vmap-root .vm-legend-head svg{transition:transform .25s ease}\n#vmap-root .vm-legend.is-closed .vm-legend-head svg{transform:rotate(-90deg)}\n#vmap-root .vm-legend-body{overflow:auto;padding:0 10px 10px;border-top:1px solid var(--line)}\n#vmap-root .vm-legend.is-closed .vm-legend-body{display:none}\n#vmap-root .vm-lg-group{font:600 10px\/1 \"Inter\",sans-serif;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);padding:12px 8px 6px}\n#vmap-root .vm-lg{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;border:0;border-radius:3px;padding:6px 8px;cursor:pointer;\n  font:600 16px\/1.2 \"Cormorant Garamond\",Georgia,serif;color:var(--ink);transition:background .15s ease}\n#vmap-root .vm-lg b{flex:none;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--ink);color:#f7f0df;font:700 10px\/1 \"Inter\",sans-serif}\n#vmap-root .vm-lg.is-featured b{background:var(--red)}\n#vmap-root .vm-lg:hover,#vmap-root .vm-lg.is-active{background:rgba(176,141,60,.18)}\n\n#vmap-root .vm-tourbtn{right:22px;top:22px;height:44px;box-sizing:border-box;display:flex;align-items:center;gap:9px;padding:11px 16px;border-radius:999px;cursor:pointer;\n  font:600 13px\/1 \"Inter\",sans-serif;letter-spacing:.02em;background:var(--red);color:#fff;border-color:rgba(255,255,255,.25)}\n#vmap-root .vm-tourbtn:hover{background:#a3241d}\n#vmap-root .vm-tourbtn[hidden]{display:none}\n\n#vmap-root .vm-controls{right:22px;top:84px;display:flex;flex-direction:column;align-items:center;padding:6px;border-radius:999px;gap:2px}\n#vmap-root .vm-controls button{width:38px;height:38px;border-radius:50%;border:0;background:transparent;color:var(--ink);cursor:pointer;display:grid;place-items:center;padding:0;transition:background .15s}\n#vmap-root .vm-controls button:hover{background:rgba(176,141,60,.22)}\n#vmap-root .vm-controls button svg{width:20px;height:20px}\n#vmap-root .vm-controls .vm-compass{width:44px;height:44px}\n#vmap-root .vm-controls .vm-compass svg{width:38px;height:38px}\n#vmap-root .vm-needle{transform-origin:20px 20px}\n#vmap-root .vm-tilt span{font:700 11.5px\/1 \"Inter\",sans-serif;letter-spacing:.04em}\n#vmap-root .vm-tilt[aria-pressed=\"true\"]{background:var(--ink)!important;color:#f7f0df!important}\n#vmap-root .vm-sep{width:20px;height:1px;background:var(--line);margin:3px 0}\n\n#vmap-root .vm-hint{left:50%;bottom:22px;transform:translateX(-50%);padding:9px 16px;border-radius:999px;font:500 12.5px\/1 \"Inter\",sans-serif;white-space:nowrap;\n  pointer-events:none;transition:opacity .6s ease}\n#vmap-root .vm-hint.is-gone{opacity:0}\n\n#vmap-root .vm-tourbar{left:22px;bottom:62px;display:flex;align-items:center;gap:4px;padding:6px 8px;border-radius:999px;min-width:440px}\n#vmap-root .vm-tourbar[hidden]{display:none}\n#vmap-root .vm-tourbar button{border:0;background:transparent;color:var(--ink);cursor:pointer;width:34px;height:34px;border-radius:50%;display:grid;place-items:center}\n#vmap-root .vm-tourbar button:hover{background:rgba(176,141,60,.22)}\n#vmap-root .vm-tourbar .vm-tb-end{width:auto;padding:0 14px;border-radius:999px;font:600 12px\/1 \"Inter\",sans-serif;border:1px solid var(--line)}\n#vmap-root .vm-tb-info{flex:1;display:flex;flex-direction:column;gap:3px;padding:0 10px;min-width:0}\n#vmap-root .vm-tb-count{font:600 10px\/1 \"Inter\",sans-serif;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft)}\n#vmap-root .vm-tb-name{font:600 16px\/1.1 \"Cormorant Garamond\",serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n#vmap-root .vm-tb-prog{display:block;height:2px;background:var(--line);border-radius:2px;overflow:hidden}\n#vmap-root .vm-tb-prog b{display:block;height:100%;width:0;background:var(--red)}\n\n\/* Card *\/\n#vmap-root .vm-card{left:auto;right:98px;top:84px;width:330px;max-height:calc(100% - 106px);overflow:auto;border-radius:3px;opacity:0;transform:translateX(18px);\n  transition:opacity .25s ease,transform .25s ease;z-index:6}\n#vmap-root .vm-card.is-on{opacity:1;transform:none}\n#vmap-root .vm-card,#vmap-root .vm-legend-body{touch-action:pan-y}\n#vmap-root.is-touring .vm-card{max-height:calc(100% - 106px)}\n#vmap-root .vm-card[hidden]{display:none}\n#vmap-root .vm-card-close{position:absolute;right:10px;top:10px;z-index:3;width:30px;height:30px;border-radius:50%;border:0;background:rgba(42,33,22,.82);color:#f7f0df;\n  font:400 20px\/30px \"Inter\",sans-serif;cursor:pointer;padding:0;text-align:center}\n#vmap-root .vm-card-close:hover{background:var(--red)}\n#vmap-root .vm-media{position:relative;aspect-ratio:2\/1;overflow:hidden;background:#d8c7a2;border-bottom:1px solid var(--line)}\n#vmap-root .vm-layer{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .35s ease}\n#vmap-root .vm-layer.is-hidden{opacity:0;pointer-events:none}\n#vmap-root .vm-aerial{background-image:var(--vm-img);background-repeat:no-repeat;filter:var(--vm-tone);animation:vm-kb 11s ease-in-out infinite alternate}\n@keyframes vm-kb{from{transform:scale(1)}to{transform:scale(1.16)}}\n#vmap-root .vm-plan svg{display:block;width:100%;height:100%}\n#vmap-root .vm-tabs{position:absolute;left:10px;bottom:10px;display:flex;background:rgba(42,33,22,.78);border-radius:999px;padding:3px;z-index:2}\n#vmap-root .vm-tabs button{border:0;background:transparent;color:#f7f0df;font:600 11px\/1 \"Inter\",sans-serif;letter-spacing:.06em;padding:7px 11px;border-radius:999px;cursor:pointer}\n#vmap-root .vm-tabs button.is-on{background:#f7f0df;color:var(--ink)}\n#vmap-root .vm-credit{position:absolute;right:8px;bottom:6px;font-size:10px;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.7);z-index:2}\n#vmap-root .vm-body{padding:13px 17px 15px}\n#vmap-root .vm-it{font:italic 500 15px\/1.3 \"Cormorant Garamond\",serif;color:var(--ink-soft);margin:0}\n#vmap-root .vm-name{font:600 25px\/1.06 \"Cormorant Garamond\",serif;margin:3px 0 9px;color:var(--ink)}\n#vmap-root .vm-date{display:inline-block;font:600 10.5px\/1 \"Inter\",sans-serif;letter-spacing:.12em;text-transform:uppercase;color:var(--red);\n  border:1px solid rgba(140,29,24,.45);padding:5px 7px;border-radius:2px;margin-bottom:10px}\n#vmap-root .vm-blurb{margin:0 0 9px;font-size:13.5px;line-height:1.52;color:var(--ink)}\n#vmap-root .vm-facts{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}\n#vmap-root .vm-facts li{position:relative;padding:6px 0 6px 16px;border-bottom:1px solid var(--line);font-size:12.5px;line-height:1.45;color:#3d3424}\n#vmap-root .vm-facts li::before{content:\"\";position:absolute;left:1px;top:13px;width:6px;height:6px;background:var(--gold);transform:rotate(45deg)}\n#vmap-root .vm-ask,#vmap-root .vm-ask *{white-space:normal !important;text-transform:none}\n#vmap-root .vm-ask{display:flex;align-items:flex-start;gap:11px;width:100%;margin-top:12px;padding:11px 13px;text-align:left;cursor:pointer;\n  background:linear-gradient(180deg,#9a2620,#7f1a15);color:#fbf3e2;border:1px solid rgba(255,230,180,.35);border-radius:4px;\n  box-shadow:0 6px 14px -8px rgba(80,10,5,.7);transition:transform .15s ease,box-shadow .15s ease,filter .15s ease}\n#vmap-root .vm-ask:hover{transform:translateY(-1px);filter:brightness(1.07);box-shadow:0 10px 18px -8px rgba(80,10,5,.75)}\n#vmap-root .vm-ask:active{transform:none}\n#vmap-root .vm-ask-ic{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:rgba(255,240,210,.16);color:#f3d58b;margin-top:1px}\n#vmap-root .vm-ask-tx{display:flex;flex-direction:column;gap:3px;min-width:0}\n#vmap-root .vm-ask-tx b{font:600 10.5px\/1.1 \"Inter\",sans-serif;letter-spacing:.14em;text-transform:uppercase !important;color:#f3d58b}\n#vmap-root .vm-ask-tx i{font:italic 400 14.5px\/1.42 \"Bitter\",Georgia,serif;color:#fbf3e2}\n#vmap-root .vm-ask.is-busy{opacity:.75;pointer-events:none}\n#vmap-root .vm-ask-more{display:flex;align-items:center;justify-content:space-between;width:100%;margin-top:6px;padding:9px 12px;cursor:pointer;\n  background:rgba(140,29,24,.06);color:#7f1a15;border:1px solid rgba(140,29,24,.32);border-radius:4px;font:600 10.5px\/1 \"Inter\",sans-serif;letter-spacing:.14em;text-transform:uppercase;transition:background .15s ease}\n#vmap-root .vm-ask-more:hover{background:rgba(140,29,24,.12)}\n#vmap-root .vm-ask-more svg{transition:transform .2s ease}\n#vmap-root .vm-ask-more[aria-expanded=\"true\"]{border-radius:4px 4px 0 0}\n#vmap-root .vm-ask-more[aria-expanded=\"true\"] svg{transform:rotate(180deg)}\n#vmap-root .vm-ask-list{list-style:none;margin:0;padding:0;background:#fffaf0;border:1px solid rgba(140,29,24,.25);border-top:0;border-radius:0 0 4px 4px}\n#vmap-root .vm-ask-list[hidden]{display:none}\n#vmap-root .vm-ask-list button{position:relative;display:block;width:100%;text-align:left;background:none;border:0;border-bottom:1px solid var(--line);padding:9px 12px 9px 27px;cursor:pointer;\n  font:italic 400 14px\/1.42 \"Bitter\",Georgia,serif;color:var(--ink);white-space:normal;text-transform:none;transition:background .15s ease}\n#vmap-root .vm-ask-list li:last-child button{border-bottom:0}\n#vmap-root .vm-ask-list button::before{content:\"\";position:absolute;left:11px;top:16px;width:6px;height:6px;background:var(--gold);transform:rotate(45deg)}\n#vmap-root .vm-ask-list button:hover{background:rgba(176,141,60,.16)}\n#vmap-root .vm-ask-list .vm-ask-own{font:600 12.5px\/1.4 \"Inter\",sans-serif;color:#7f1a15}\n#vmap-root .vm-ask-list .vm-ask-own::before{background:var(--red)}\n#vmap-root .vm-toast{position:absolute;left:50%;top:22px;transform:translate(-50%,-8px);z-index:9;max-width:min(460px,calc(100% - 40px));padding:11px 16px;border-radius:4px;\n  background:rgba(247,240,223,.97);color:#2a2116;border:1px solid rgba(176,141,60,.6);box-shadow:0 14px 30px -12px rgba(0,0,0,.6);font:500 13px\/1.45 \"Inter\",sans-serif;\n  opacity:0;transition:opacity .25s ease,transform .25s ease;pointer-events:none}\n#vmap-root .vm-toast.is-on{opacity:1;transform:translate(-50%,0);pointer-events:auto}\n#vmap-root .vm-toast a{color:#8c1d18;font-weight:600}\n#vmap-root .vm-card-nav{display:flex;justify-content:space-between;gap:8px;margin-top:12px}\n#vmap-root .vm-card-nav button{flex:1;border:1px solid var(--line);background:transparent;border-radius:3px;padding:8px;font:600 12px\/1 \"Inter\",sans-serif;color:var(--ink);cursor:pointer}\n#vmap-root .vm-card-nav button:hover{background:rgba(176,141,60,.18)}\n\n#vmap-root .vm-msg{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:7;max-width:440px;padding:22px 26px;background:var(--paper);border:1px solid var(--gold);border-radius:3px;font-size:14px;text-align:center}\n#vmap-root .vm-msg[hidden]{display:none}\n#vmap-root .vm-msg code{background:var(--paper-2);padding:1px 5px;border-radius:2px}\n\n\/* Father Dominic panel, inside the map *\/\n#vmap-root .vm-fd{left:22px;top:22px;bottom:22px;width:min(420px,calc(100% - 44px));z-index:8;display:flex;flex-direction:column;\n  cursor:auto;touch-action:auto;user-select:text;-webkit-user-select:text;opacity:0;transform:translateX(-14px);transition:opacity .25s ease,transform .25s ease}\n#vmap-root .vm-fd.is-on{opacity:1;transform:none}\n#vmap-root .vm-fd[hidden]{display:none}\n#vmap-root .vm-fd-slot{flex:1;min-height:0;display:flex;flex-direction:column}\n#vmap-root .vm-fd-close{position:absolute;right:10px;top:9px;z-index:5;width:30px;height:30px;border-radius:50%;border:1px solid rgba(243,213,139,.6);background:rgba(0,0,0,.2);\n  color:#fbf3e2;font:400 20px\/28px \"Inter\",sans-serif;cursor:pointer;padding:0;text-align:center;transition:background .15s ease,color .15s ease}\n#vmap-root .vm-fd-close:hover,#vmap-root .vm-fd-close:focus-visible{background:#fbf3e2;color:#7f1a15;outline:none}\n#vmap-root .vm-fd .mwai-chatbot-container{flex:1;min-height:0;display:flex;flex-direction:column}\n#vmap-root .vm-fd-slot .mwai-chat:not(.mwai-window){flex:1;min-height:0;display:flex !important;flex-direction:column;width:100% !important;max-width:none !important;margin:0 !important;padding:0 !important;--mwai-width:100%}\n#vmap-root .vm-fd .mwai-chat .mwai-window-box{flex:1;min-height:0;height:auto !important;max-height:none !important;display:flex !important;flex-direction:column;width:100% !important;margin:0 !important}\n#vmap-root .vm-fd .mwai-chat .mwai-body{flex:1;min-height:0;display:flex !important;flex-direction:column;height:auto !important;max-height:none !important}\n#vmap-root .vm-fd .mwai-chat .mwai-body::before{padding-right:54px}\n#vmap-root .vm-fd .mwai-chat .mwai-conversation{flex:1 1 auto;min-height:0;max-height:none !important;overflow-y:auto !important;overscroll-behavior:contain}\n#vmap-root .vm-fd .mwai-chat .mwai-input{flex:none}\n#vmap-root.is-compact .vm-fd{left:8px;right:56px;width:auto;top:auto;bottom:8px;height:min(82%,560px);transform:translateY(14px)}\n#vmap-root.is-compact .vm-fd.is-on{transform:none}\n#vmap-root.is-compact.is-fd .vm-card,#vmap-root.is-compact.is-fd .vm-legend{display:none}\n\/* the chatbot\u2019s own block below the map stays hidden; it opens inside the map *\/\nbody:has(#vmap-root) .elementor-widget-shortcode:has(.mwai-chatbot-container){display:none !important}\n\n\/* the blessing from the Angelus window *\/\n#vmap-root .vm-bless{left:0;top:0;z-index:5;max-width:280px;padding:9px 13px 10px;border-radius:4px;background:rgba(247,240,223,.96);color:var(--ink);border:1px solid rgba(176,141,60,.6);\n  box-shadow:0 12px 26px -12px rgba(0,0,0,.6);pointer-events:none;opacity:0;transition:opacity .35s ease;transform:translate(-50%,-100%)}\n#vmap-root .vm-bless.is-on{opacity:1}\n#vmap-root .vm-bless[hidden]{display:none}\n#vmap-root .vm-bless i{display:block;font:italic 500 16px\/1.3 \"Bitter\",Georgia,serif;color:#6f1612}\n#vmap-root .vm-bless span{display:block;margin-top:3px;font:500 11.5px\/1.3 \"Inter\",sans-serif;color:var(--ink-soft)}\n#vmap-root .vm-bless::after{content:\"\";position:absolute;left:50%;bottom:-7px;width:12px;height:12px;background:rgba(247,240,223,.96);border-right:1px solid rgba(176,141,60,.6);border-bottom:1px solid rgba(176,141,60,.6);transform:translateX(-50%) rotate(45deg)}\n#vmap-root.is-compact .vm-bless{max-width:220px}\n#vmap-root.is-compact .vm-bless i{font-size:14px}\n\n\/* Compact: narrow screens and narrow columns *\/\n#vmap-root.is-compact .vm-stage{min-height:400px}\n#vmap-root.is-compact .vm-title{display:none}\n#vmap-root.is-compact .vm-title h2{font-size:24px;margin:3px 0 0}\n#vmap-root.is-compact .vm-title p{display:none}\n#vmap-root.is-compact .vm-legend{left:12px;top:auto;bottom:46px;width:calc(100% - 90px);max-height:55%}\n#vmap-root.is-compact .vm-tourbtn{right:12px;top:12px;padding:10px 13px;height:40px}\n#vmap-root.is-compact .vm-copy{left:12px;bottom:12px;max-width:calc(100% - 24px);font-size:11.5px;letter-spacing:0;padding:5px 10px;line-height:1.2;border-radius:12px}\n#vmap-root.is-compact .vm-legend{bottom:50px}\n#vmap-root.is-compact .vm-controls{right:12px;top:62px;padding:4px}\n#vmap-root.is-compact .vm-sep{margin:1px 0}\n#vmap-root.is-compact .vm-controls button{width:32px;height:32px}\n#vmap-root.is-compact .vm-controls .vm-compass{width:36px;height:36px}\n#vmap-root.is-compact .vm-controls .vm-compass svg{width:30px;height:30px}\n#vmap-root.is-compact .vm-hint{display:none}\n#vmap-root.is-compact .vm-pin-disc{width:25px;height:25px;font-size:11px}\n#vmap-root.is-compact .vm-pin-stem{height:8px}\n#vmap-root.is-compact .vm-tourbar{min-width:0;width:calc(100% - 24px);left:12px;top:12px;bottom:auto}\n#vmap-root.is-compact.is-touring .vm-title{display:none}\n#vmap-root.is-compact .vm-tourbar .vm-tb-end{display:none}\n#vmap-root.is-compact .vm-card{left:0;right:0;top:auto;bottom:0;width:auto;max-height:58%;border-radius:14px 14px 0 0;border-bottom:0;opacity:1;transform:translateY(105%);transition:transform .32s cubic-bezier(.2,.8,.2,1);overscroll-behavior:contain;z-index:7}\n#vmap-root.is-compact .vm-card.is-on{transform:none}\n#vmap-root .vm-controls{transition:opacity .25s ease}\n#vmap-root.is-compact.is-sheet .vm-legend{opacity:0;pointer-events:none}\n#vmap-root.is-compact .vm-controls{z-index:8}\n#vmap-root.is-compact .vm-card{right:56px;border-right:1px solid rgba(176,141,60,.55);border-radius:14px 14px 0 0}\n#vmap-root.is-compact .vm-media{aspect-ratio:5\/2}\n#vmap-root.is-compact .vm-name{font-size:23px}\n#vmap-root.is-compact .vm-card-close{top:8px;right:8px}\n#vmap-root.is-compact .vm-below{background:var(--paper)}\n#vmap-root:fullscreen{background:var(--desk-2)}\n#vmap-root:fullscreen .vm-stage{height:100vh}\n\n\/* Plan drawings in cards *\/\n#vmap-root .v-ink{fill:none;stroke:#2e2416;stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}\n#vmap-root .v-soft{fill:none;stroke:rgba(46,36,22,.35);stroke-width:1}\n#vmap-root .v-fill{fill:url(#vgStone);stroke:#2e2416;stroke-width:1.3;stroke-linejoin:round}\n#vmap-root .v-gold{fill:url(#vgGold);stroke:#2e2416;stroke-width:1.1}\n#vmap-root .v-goldline{fill:none;stroke:#d9a93c;stroke-width:3}\n#vmap-root .v-red{fill:#8c1d18}\n#vmap-root .v-redline{fill:none;stroke:#8c1d18;stroke-width:1.6;stroke-dasharray:4 3}\n#vmap-root .v-green{fill:#7a8a4e;stroke:#4f5d34;stroke-width:.8}\n#vmap-root .v-txt{font:600 8.5px \"Inter\",sans-serif;fill:#5c4c34;letter-spacing:.08em;text-transform:uppercase}\n#vmap-root .v-dark{fill:#3a2e1e}\n\n\/* Placement tool *\/\n#vmap-root .vm-cal{position:absolute;left:22px;bottom:22px;z-index:8;width:330px;background:#f7f0df;border:1px solid #2a2116;padding:12px 14px;border-radius:3px;font-size:12.5px}\n#vmap-root .vm-cal p{margin:4px 0 8px;line-height:1.4}\n#vmap-root .vm-cal select,#vmap-root .vm-cal textarea{width:100%;font:12px ui-monospace,Menlo,monospace;margin:4px 0;padding:5px;border:1px solid rgba(42,33,22,.4);background:#fff}\n#vmap-root .vm-cal div{display:flex;gap:6px}\n#vmap-root .vm-cal button{flex:1;font:600 12px \"Inter\",sans-serif;padding:6px;border:1px solid #2a2116;background:#efe4cb;cursor:pointer;border-radius:2px}\n\n\/* Copyright notice *\/\n#vmap-root .vm-copy{position:absolute;left:22px;bottom:20px;z-index:4;pointer-events:none;user-select:none;\n  font:italic 600 15px\/1 \"Cormorant Garamond\",Georgia,serif;letter-spacing:.03em;color:#f3e7cb;\n  background:rgba(22,15,8,.62);border:1px solid rgba(176,141,60,.5);padding:6px 13px 7px;border-radius:999px;\n  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);text-shadow:0 1px 2px rgba(0,0,0,.5)}\n\n\/* =========================================================\n   Father Dominic chat window, styled to match the map.\n   Applies only on pages that contain this map.\n   ========================================================= *\/\nbody:has(#vmap-root) .mwai-chat{\n  --mwai-fontFamily:\"Bitter\",Georgia,serif;\n  --mwai-backgroundPrimaryColor:#f7f0df; --mwai-backgroundSecondaryColor:#efe4cb; --mwai-surfaceColor:#fffaf0;\n  --mwai-backgroundHeaderColor:#7f1a15; --mwai-headerColor:#fbf3e2; --mwai-fontColor:#2a2116;\n  --mwai-accentColor:#8c1d18; --mwai-backgroundUserColor:#8c1d18; --mwai-backgroundAiColor:#fffaf0;\n  --mwai-conversationsBackgroundColor:#f7f0df; --mwai-conversationsTextColor:#2a2116;\n  --mwai-borderColor:rgba(176,141,60,.55); --mwai-lineColor:rgba(176,141,60,.35); --mwai-linkColor:#8c1d18;\n  --mwai-iconTextColor:#2a2116; --mwai-iconTextBackgroundColor:#f7f0df; --mwai-bubbleColor:#8c1d18;\n  --mwai-borderRadius:14px; --mwai-fontSize:15px; --mwai-lineHeight:1.5; --mwai-width:400px;\n  color:#2a2116;\n}\n\/* window shell *\/\nbody:has(#vmap-root) .mwai-chat .mwai-window-box{\n  background:linear-gradient(180deg,#faf4e6,#f1e6cc) !important; border:1px solid rgba(176,141,60,.7) !important; border-radius:14px !important; overflow:hidden !important;\n  box-shadow:0 0 0 4px rgba(247,240,223,.35),0 30px 70px -20px rgba(20,10,0,.75),0 10px 24px -10px rgba(20,10,0,.5) !important; filter:none !important;\n}\nbody:has(#vmap-root) .mwai-chat:not(.mwai-window){ --mwai-width:100%; width:100% !important; max-width:860px !important; margin:24px auto !important; }\nbody:has(#vmap-root) .mwai-chat:not(.mwai-window) .mwai-window-box{ width:100% !important; margin:0 !important; }\nbody:has(#vmap-root) .mwai-chat.mwai-window .mwai-window-box{ width:min(400px,calc(100vw - 32px)) !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-body{ background:transparent !important; }\n\/* title strip (shown above the conversation in every mode) *\/\nbody:has(#vmap-root) .mwai-chat .mwai-body::before{\n  content:\"Ask Father Dominic\"; display:block; flex:none; padding:13px 18px 12px;\n  background:linear-gradient(180deg,#9a2620,#6f1612); color:#fbf3e2; border-bottom:2px solid #c9a35a;\n  font:600 18px\/1.2 \"Bitter\",Georgia,serif; letter-spacing:.01em;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-header{ background:linear-gradient(180deg,#9a2620,#6f1612) !important; color:#fbf3e2 !important; border-bottom:2px solid #c9a35a !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-header *{ color:#fbf3e2 !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-header svg{ stroke:#f3d58b !important; }\n\/* conversation *\/\nbody:has(#vmap-root) .mwai-chat .mwai-conversation{\n  background:radial-gradient(ellipse at 50% 0%,rgba(255,255,255,.55),rgba(255,255,255,0) 70%) !important;\n  padding:16px 16px 6px !important; scrollbar-color:rgba(176,141,60,.6) transparent;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-conversation::-webkit-scrollbar-thumb{ background:rgba(176,141,60,.55) !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply{ margin-bottom:14px !important; padding:0 !important; background:transparent !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply .mwai-name .mwai-avatar img{ border-radius:50% !important; border:1.5px solid #c9a35a !important; box-shadow:0 2px 6px rgba(60,30,5,.3) !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text{\n  display:block !important; background:#fffaf0 !important; color:#2a2116 !important; border:1px solid rgba(176,141,60,.45) !important;\n  border-radius:4px 14px 14px 14px !important; padding:12px 15px !important; box-shadow:0 4px 12px -8px rgba(60,40,10,.45) !important;\n  font-family:\"Bitter\",Georgia,serif !important; font-size:17px !important; line-height:1.6 !important; font-weight:400 !important;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text *{ color:#2a2116 !important; font-family:\"Bitter\",Georgia,serif !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text strong,\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text b{ color:#6f1612 !important; font-weight:700 !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text a{ color:#8c1d18 !important; text-decoration:underline !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-user .mwai-text{\n  background:linear-gradient(180deg,#9a2620,#7f1a15) !important; color:#fbf3e2 !important; border-radius:14px 4px 14px 14px !important;\n  padding:10px 15px !important; font-family:\"Bitter\",Georgia,serif !important; font-size:15.5px !important; line-height:1.5 !important; box-shadow:0 6px 14px -8px rgba(80,10,5,.6) !important;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-reply.mwai-user .mwai-text *{ color:#fbf3e2 !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-reply-actions svg{ color:#8a7a5c !important; fill:currentColor; }\n\/* input *\/\nbody:has(#vmap-root) .mwai-chat .mwai-input{\n  background:#fffdf7 !important; border:1px solid rgba(176,141,60,.65) !important; border-radius:999px !important;\n  margin:10px 14px 14px !important; box-shadow:inset 0 1px 2px rgba(60,40,10,.08),0 4px 12px -8px rgba(60,40,10,.4) !important;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-input:focus-within{ border-color:#b08d3c !important; box-shadow:0 0 0 3px rgba(201,163,90,.3) !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-input textarea{ background:transparent !important; color:#2a2116 !important; font-family:\"Bitter\",Georgia,serif !important; font-size:16px !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-input textarea::placeholder{ color:#9a8a6c !important; font-style:italic; }\nbody:has(#vmap-root) .mwai-chat .mwai-input button.mwai-input-submit{\n  background:linear-gradient(180deg,#9a2620,#7f1a15) !important; color:#f3d58b !important; border:0 !important; border-radius:50% !important; opacity:1 !important;\n}\nbody:has(#vmap-root) .mwai-chat .mwai-input button.mwai-input-submit svg,\nbody:has(#vmap-root) .mwai-chat .mwai-input button.mwai-input-submit svg *{ color:#f3d58b !important; stroke:#f3d58b !important; }\nbody:has(#vmap-root) .mwai-chat .mwai-footer,\nbody:has(#vmap-root) .mwai-chat .mwai-compliance{ background:transparent !important; color:#8a7a5c !important; font:italic 400 12.5px \"Bitter\",Georgia,serif !important; border:0 !important; }\n\/* launcher bubble *\/\nbody:has(#vmap-root) .mwai-chat .mwai-trigger .mwai-icon-container .mwai-icon{ border-radius:50% !important; border:2px solid #c9a35a !important; box-shadow:0 10px 24px -8px rgba(60,10,5,.7) !important; }\n\/* phones: inset from the edges instead of edge to edge *\/\n@media (max-width:600px){\n  body:has(#vmap-root) .mwai-chat.mwai-window.mwai-open .mwai-window-box{ position:fixed !important; left:10px !important; right:10px !important; bottom:10px !important; top:auto !important; width:auto !important; max-height:80vh !important; height:auto !important; }\n  body:has(#vmap-root) .mwai-chat:not(.mwai-window){ margin:12px auto !important; padding:0 8px; }\n  body:has(#vmap-root) .mwai-chat .mwai-reply.mwai-ai .mwai-text{ font-size:16.5px !important; }\n}\n\/* Keep the top of the map clear of the site\u2019s fixed menu bar.\n   --vm-cover is how much of the map the menu is hiding, set by the script. *\/\n#vmap-root .vm-title{top:calc(22px + var(--vm-cover,0px))}\n#vmap-root .vm-legend{top:calc(178px + var(--vm-cover,0px));max-height:calc(100% - 240px - var(--vm-cover,0px))}\n#vmap-root .vm-tourbtn{top:calc(22px + var(--vm-cover,0px))}\n#vmap-root .vm-controls{top:calc(84px + var(--vm-cover,0px))}\n#vmap-root .vm-card{top:calc(84px + var(--vm-cover,0px));max-height:calc(100% - 106px - var(--vm-cover,0px))}\n#vmap-root .vm-fd{top:calc(22px + var(--vm-cover,0px))}\n#vmap-root .vm-toast{top:calc(22px + var(--vm-cover,0px))}\n\/* Phones: tour and controls share one row at the top, cards and Father Dominic use the full width *\/\n#vmap-root.is-compact .vm-legend{top:auto;width:calc(100% - 24px)}\n#vmap-root.is-compact .vm-tourbtn{left:12px;right:auto;top:calc(12px + var(--vm-cover,0px));height:40px;padding:0 15px;gap:7px}\n#vmap-root.is-compact .vm-tourbtn span{font-size:0}\n#vmap-root.is-compact .vm-tourbtn span::after{content:\"Tour\";font-size:13px}\n#vmap-root.is-compact .vm-controls{flex-direction:row;right:12px;top:calc(12px + var(--vm-cover,0px));height:40px;padding:2px 5px;gap:0}\n#vmap-root.is-compact .vm-controls [data-c=\"ccw\"],#vmap-root.is-compact .vm-controls [data-c=\"cw\"]{display:none}\n#vmap-root.is-compact .vm-sep{width:1px;height:18px;margin:0 3px}\n#vmap-root.is-compact .vm-controls button{width:34px;height:34px}\n#vmap-root.is-compact .vm-controls .vm-compass{width:36px;height:36px}\n#vmap-root.is-compact .vm-controls .vm-compass svg{width:30px;height:30px}\n#vmap-root.is-compact .vm-tourbar{top:calc(60px + var(--vm-cover,0px))}\n#vmap-root.is-compact .vm-card{top:auto;right:0;border-right:0;max-height:min(60%,calc(100% - 64px - var(--vm-cover,0px)))}\n#vmap-root.is-compact .vm-fd{left:8px;right:8px;width:auto;top:calc(60px + var(--vm-cover,0px));bottom:8px;height:auto}\n#vmap-root.is-compact .vm-toast{top:calc(60px + var(--vm-cover,0px))}\n@media (prefers-reduced-motion:reduce){ #vmap-root *{animation:none!important;transition:none!important} }\n<\/style>\n\n<script>\n(function(){\n  var root = document.getElementById('vmap-root');\n  if (!root || root.dataset.ready) return;\n  root.dataset.ready = '1';\n\n  \/* =================================================================\n     SETTINGS\n     BASE_IMAGE:   web address of the painting (Media Library File URL).\n     BACKDROP:     'dark' (lamp-lit desk) or 'light' (parchment).\n     WHEEL_ZOOM:   true lets the mouse wheel zoom the map.\n     TOUR_SECONDS: how long the tour lingers at each stop.\n     CALIBRATE:    true turns on the marker-placement tool (or add\n                   ?vmap-calibrate=1 to the page address).\n     POSITIONS:    where each marker sits on the painting, as\n                   [percent across, percent down].\n     ================================================================= *\/\n  var CONFIG = {\n    BASE_IMAGE: 'https:\/\/garymcavoy.com\/wp-content\/uploads\/2026\/10\/exec-93d82395-dc4e-4b7f-9d1f-d191b2dc28d8.png',\n    BACKDROP: 'dark',\n    WHEEL_ZOOM: true,\n    TOUR_SECONDS: 10,\n    \/* LIFE: true brings the painting to life with pilgrims, Swiss Guards,\n       boats, traffic, and birds, plus the occasional helicopter landing and\n       white smoke. Set to false for a still painting. To preview the rare\n       moments quickly, add ?vmap-life=preview to the page address. *\/\n    LIFE: true,\n    \/* Ask Father Dominic: the map opens your AI Engine chatbot on this page\n       and asks it the question shown on each card.\n       FD_BOT_ID: the chatbot\u2019s ID from AI Engine (leave '' to use the first\n                  chatbot found on the page).\n       FD_PAGE:   your Ask Father Dominic page, used only if the chatbot\n                  isn\u2019t on the map page. *\/\n    FD_BOT_ID: '',\n    FD_PAGE: 'https:\/\/garymcavoy.com\/ask-father-dominic\/',\n    CALIBRATE: false,\n    POSITIONS: {\n      archive:[39.8, 31],\n      bunker:[44, 16],\n      tower:[39.8, 25.5],\n      library:[43.5, 24.5],\n      sistine:[38.5, 42],\n      raphael:[42.5, 40.5],\n      palace:[45.5, 41],\n      basilica:[37.5, 50],\n      scavi:[33.2, 50.5],\n      square:[52, 53],\n      museums:[44, 9],\n      gardens:[19, 38],\n      governorate:[27.5, 50.5],\n      santamarta:[35, 64.5],\n      passetto:[64, 35.6],\n      colonnade:[54.6, 59.7],\n      castel:[88, 33],\n      apartments:[47, 41.4],\n      barracks:[50.8, 29.5],\n      armory:[49.8, 27.3],\n      santanna:[52.5, 31],\n      canteen:[49.8, 19.5],\n      heliport:[6, 53],\n      grotto:[16.9, 46.9],\n      walls:[14, 62]\n    }\n  };\n\n  \/* =================================================================\n     LOCATIONS \u2014 names, dates, descriptions, and facts.\n     image: optional photo URL for the close-up; credit: photo credit.\n     ================================================================= *\/\n  var PLACES = [\n    { id:'archive', featured:true, x:646, y:224, z:26, v:'archive', image:'', credit:'',\n      name:'Vatican Apostolic Archive', it:'Archivum Apostolicum Vaticanum \u00b7 formerly the Secret Archives', date:'Founded 1612',\n      blurb:'Paul V separated the papal archive from the Library in 1612, and for nearly three centuries it remained closed to outsiders. Its old name never meant hidden in the modern sense: secretum in Latin means private, the personal archive of the pope.',\n      facts:['Leo XIII opened it to qualified scholars in 1881','Renamed the Apostolic Archive by Pope Francis in 2019','Roughly twelve centuries of documents on about 85 km of shelving','Pius XII\u2019s pontificate files were opened to researchers in March 2020'] },\n    { id:'bunker', featured:true, x:735, y:166, z:2, v:'bunker', image:'', credit:'',\n      name:'The Archive Bunker', it:'Il Bunker \u00b7 beneath the Cortile della Pigna', date:'Completed 1980',\n      blurb:'Below the lawn of the Cortile della Pigna, the Archive extends two levels underground into a climate-controlled repository of steel shelving. Above, visitors stroll past Pomodoro\u2019s bronze sphere with no sign of what lies beneath their feet.',\n      facts:['Two subterranean floors built under John Paul II','Engineered for stable temperature, humidity, and fire protection','Reached from the Archive\u2019s own buildings, not from the courtyard'] },\n    { id:'tower', featured:true, x:689, y:239, z:74, v:'tower', image:'', credit:'',\n      name:'Tower of the Winds', it:'Torre dei Venti', date:'1578\u20131580',\n      blurb:'Built for Gregory XIII by Ottaviano Mascherino, the tower served as an observatory. In its Meridian Room, a small aperture casts a disc of sunlight across a line set into the floor, proof that the Julian calendar had drifted from the seasons.',\n      facts:['Linked to the Gregorian calendar reform of 1582','A wind vane above turns a pointer on the frescoed ceiling','Today part of the Apostolic Archive complex'] },\n    { id:'library', x:735, y:281, z:32, v:'library', image:'', credit:'',\n      name:'Vatican Apostolic Library', it:'Biblioteca Apostolica Vaticana', date:'Founded 1475',\n      blurb:'Nicholas V gathered the collection; Sixtus IV gave it a formal foundation in 1475. Its great Salone Sistino, built by Domenico Fontana in 1587\u20131589, cuts straight across the Belvedere Courtyard and divided Bramante\u2019s vast space in two.',\n      facts:['Among its treasures is the Codex Vaticanus, one of the oldest Greek Bibles','Tens of thousands of manuscripts and thousands of incunabula','Open to accredited researchers rather than the general public'] },\n    { id:'sistine', x:719, y:480, z:40, v:'sistine', image:'', credit:'',\n      name:'Sistine Chapel', it:'Cappella Sistina', date:'1473\u20131481',\n      blurb:'Built for Sixtus IV to the proportions given for Solomon\u2019s Temple, the chapel is the setting of every papal conclave. Michelangelo painted the ceiling between 1508 and 1512, then returned two decades later for the Last Judgment on the altar wall.',\n      facts:['The Last Judgment was painted 1536\u20131541','Roughly 40 m long and 13 m wide','During a conclave, ballots are burned in a stove vented through a temporary chimney'] },\n    { id:'raphael', x:771, y:444, z:34, v:'raphael', image:'', credit:'',\n      name:'Raphael Rooms', it:'Stanze di Raffaello', date:'1508\u20131524',\n      blurb:'Julius II refused to live in the Borgia Apartments of his predecessor, so he commissioned a young Raphael to fresco a new suite on the floor above. The Stanza della Segnatura, with the School of Athens, was the first finished.',\n      facts:['Four rooms: Constantine, Heliodorus, the Segnatura, and the Fire in the Borgo','Raphael died in 1520; his workshop completed the Sala di Costantino','Visited as part of the Vatican Museums route'] },\n    { id:'palace', x:851, y:446, z:34, v:'palace', image:'', credit:'',\n      name:'Apostolic Palace', it:'Palazzo Apostolico', date:'15th\u201317th centuries',\n      blurb:'A sprawl of halls, chapels, and offices assembled over two centuries, the palace is the official residence of the pope. From a top-floor window overlooking the square, popes have traditionally delivered the Sunday Angelus.',\n      facts:['Contains the Sala Regia, Pauline Chapel, and papal apartments','Also houses offices of the Secretariat of State','Pope Francis chose to live at Casa Santa Marta instead'] },\n    { id:'basilica', x:714, y:580, z:34, v:'basilica', image:'', credit:'',\n      name:'St. Peter\u2019s Basilica', it:'Basilica di San Pietro', date:'1506\u20131626',\n      blurb:'Julius II tore down Constantine\u2019s fourth-century basilica to build anew over the traditional tomb of Peter. Bramante, Michelangelo, and Maderno shaped it across 120 years; Bernini then filled the crossing with his bronze baldacchino.',\n      facts:['Michelangelo designed the dome; Giacomo della Porta completed it in 1590','About 136 m from the floor to the top of the cross','Consecrated by Urban VIII on 18 November 1626'] },\n    { id:'scavi', featured:true, x:628, y:630, z:34, v:'scavi', image:'', credit:'',\n      name:'The Necropolis', it:'Scavi \u00b7 beneath the high altar', date:'Excavated 1939\u20131949',\n      blurb:'Workers preparing a grave for Pius XI uncovered a Roman street of tombs beneath the basilica floor. Pius XII authorized a decade of secret excavations that reached a modest shrine against a plastered wall, directly under the high altar.',\n      facts:['The \u201cRed Wall\u201d and its graffiti lie at the heart of the site','In 1968 Paul VI announced that bones found there were believed to be Peter\u2019s','Visits are limited to small, pre-booked groups through the Excavations Office'] },\n    { id:'square', x:880, y:606, z:0, v:'square', image:'', credit:'',\n      name:'St. Peter\u2019s Square', it:'Piazza San Pietro', date:'1656\u20131667',\n      blurb:'Bernini designed the colonnades as the arms of the Church, embracing anyone who walks in from Rome. Stand on either of the two marked discs between the obelisk and the fountains and each four-deep row of columns aligns into one.',\n      facts:['284 columns topped by 140 statues of saints','The Egyptian obelisk was moved here in 1586 by Domenico Fontana','The square\u2019s mouth marks the border with Italy'] },\n    { id:'museums', x:822, y:162, z:28, v:'museums', image:'', credit:'',\n      name:'Vatican Museums', it:'Musei Vaticani \u00b7 Cortile della Pigna', date:'Begun 1506',\n      blurb:'The collections trace their start to 1506, when Julius II acquired the newly unearthed Laoco\u00f6n. The courtyard takes its name from a four-meter Roman bronze pine cone that once stood near the Pantheon.',\n      facts:['Galleries extend for several kilometers','The Pigna sits in Bramante\u2019s great niche, the Nicchione','Arnaldo Pomodoro\u2019s Sphere within Sphere stands on the lawn'] },\n    { id:'gardens', x:330, y:420, z:0, v:'gardens', image:'', credit:'',\n      name:'Vatican Gardens', it:'Giardini Vaticani', date:'Since the 13th century',\n      blurb:'Lawns, woods, and fountains cover roughly half the city-state. Hidden among them are the Renaissance Casina Pio IV, now home to the Pontifical Academy of Sciences, and stretches of the ninth-century Leonine Wall.',\n      facts:['Casina Pio IV designed by Pirro Ligorio, 1558\u20131562','The Vatican Radio tower stands on the western heights','Visits are by guided tour only'] },\n    { id:'governorate', x:485, y:482, z:30, v:'governorate', image:'', credit:'',\n      name:'Governorate Palace', it:'Palazzo del Governatorato', date:'1927\u20131931',\n      blurb:'Built in the years around the 1929 Lateran Treaty, the palace administers the practical life of the world\u2019s smallest state: utilities, the post office, the museums, and the Gendarmerie.',\n      facts:['Seat of the Pontifical Commission for Vatican City State','Stands behind the apse of St. Peter\u2019s','Overlooks the gardens to the west'] },\n    { id:'santamarta', x:612, y:665, z:30, v:'santamarta', image:'', credit:'',\n      name:'Casa Santa Marta', it:'Domus Sanctae Marthae', date:'1996',\n      blurb:'John Paul II built the guesthouse so cardinals in conclave would no longer sleep on cots in the Apostolic Palace. Pope Francis lived here from his election in 2013 until his death in 2025.',\n      facts:['Lodges cardinal electors during a conclave','Has its own chapel, used for daily papal Masses under Francis','Stands just south of the basilica'] },\n    { id:'passetto', featured:true, x:1030, y:463, z:20, v:'passetto', image:'', credit:'',\n      name:'Passetto di Borgo', it:'Corridore di Borgo \u00b7 Vatican to Castel Sant\u2019Angelo', date:'Completed 1277',\n      blurb:'Nicholas III raised an elevated corridor along the top of the Leonine Wall, giving popes a hidden escape to the fortress of Castel Sant\u2019Angelo. On 6 May 1527, as imperial troops stormed Rome, Clement VII fled along it while the Swiss Guard fought a rearguard on the steps of St. Peter\u2019s.',\n      facts:['Roughly 800 m long, running east from the Apostolic Palace','147 of the 189 Swiss Guards died covering Clement VII\u2019s escape','Alexander VI also used it in 1494, when French troops entered Rome'] },\n    { id:'colonnade', image:'', credit:'',\n      name:'Bernini\u2019s Colonnade', it:'Colonnato del Bernini', date:'1656\u20131667',\n      blurb:'Commissioned by Alexander VII, Gian Lorenzo Bernini wrapped the piazza in two great curving arms of Tuscan columns, four rows deep. He described them as the motherly arms of the Church, reaching out to gather in the faithful, the doubtful, and the curious alike.',\n      facts:['284 columns and 88 pillars carry the two arms','140 statues of saints stand along the balustrade above','From either marked disc in the paving, the four rows line up as one','Bernini planned a third arm to close the square; it was never built'] },\n    { id:'castel', image:'', credit:'',\n      name:'Castel Sant\u2019Angelo', it:'Mausoleum of Hadrian', date:'Begun AD 123',\n      blurb:'Hadrian built this drum of stone as his family tomb. Over the centuries it became a fortress, a prison, and the popes\u2019 refuge, joined to the Vatican by the Passetto. Its name comes from Gregory the Great\u2019s vision in 590 of the Archangel Michael sheathing his sword above it to end a plague.',\n      facts:['Lies outside Vatican City; today an Italian national museum','Clement VII sheltered here through the Sack of Rome in 1527','A bronze Archangel Michael, cast in the 1750s, crowns the terrace','Puccini set the final act of Tosca on its ramparts'] },\n    { id:'apartments', image:'', credit:'',\n      name:'Papal Apartments', it:'Appartamento Pontificio \u00b7 the Angelus window', date:'Top floor, Apostolic Palace',\n      blurb:'On the top floor of the Apostolic Palace, the second window from the right looks down on St. Peter\u2019s Square. At noon on Sundays the pope prays the Angelus from it with the crowd below and gives his blessing. Open this place and he comes to the window.',\n      facts:['Pius XII began the Sunday Angelus from this window in 1954','A red tapestry is hung from the sill whenever the pope appears','The apartment holds the pope\u2019s study, bedroom, chapel, and dining room','The Apostolic Palace has roughly a thousand rooms in all'] },\n    { id:'barracks', image:'', credit:'',\n      name:'Swiss Guard Barracks', it:'Quartiere della Guardia Svizzera Pontificia', date:'Guard founded 1506',\n      blurb:'Just inside St. Anne\u2019s Gate, the world\u2019s oldest standing army lives, trains, and eats in barracks built around a quiet courtyard. Julius II summoned the first 150 Swiss soldiers, who marched into Rome on 22 January 1506.',\n      facts:['Recruits are Swiss Catholic men who have completed Swiss military training','New guards are sworn in each year on 6 May, the anniversary of 1527','The corps was enlarged to 135 men in 2018','The striped uniform dates from 1914, not from Michelangelo'] },\n    { id:'armory', image:'', credit:'',\n      name:'Swiss Guard Armory', it:'Armeria della Guardia Svizzera', date:'Halberds since 1506',\n      blurb:'Inside the barracks, the armory keeps the Guard\u2019s two lives side by side: racks of halberds, swords, breastplates, and plumed morion helmets for ceremony, and the modern equipment the guards train with for close protection of the pope.',\n      facts:['Ceremonial armor is worn for the swearing-in and state occasions','Since 2019 new morion helmets have been 3D-printed','Every guard is trained in modern firearms and close protection','The halberd is still carried on duty at the gates'] },\n    { id:'santanna', image:'', credit:'',\n      name:'St. Anne\u2019s Gate', it:'Porta Sant\u2019Anna', date:'The working entrance',\n      blurb:'Tourists use the basilica doors; Vatican City\u2019s residents and staff come and go through St. Anne\u2019s Gate. Swiss Guards and the Gendarmerie check passes here, and the street beyond leads to the offices, shops, and services of the papal city.',\n      facts:['Named for Sant\u2019Anna dei Palafrenieri, the church just inside, designed by Vignola','The Vatican Pharmacy, founded in 1874, lies a short walk inside','Also leads to the Annona, the Vatican\u2019s own supermarket','Visitors need a reason and a pass to go through'] },\n    { id:'canteen', image:'', credit:'',\n      name:'Staff Canteen', it:'Mensa dei dipendenti', date:'Lunch at the Vatican',\n      blurb:'Clergy and lay employees share long tables over a simple, subsidized lunch. On 25 July 2014, just after noon, Pope Francis walked in unannounced, took a tray, joined the line, and sat down to eat with the staff.',\n      facts:['The pope chose plain pasta, then cod with grilled tomatoes','He asked the employees about themselves and their work','He gave his blessing and posed for a group photo before leaving','The Swiss Guard keep their own mess hall in the barracks'] },\n    { id:'heliport', image:'', credit:'',\n      name:'Vatican Heliport', it:'Eliporto Vaticano', date:'Opened 1976',\n      blurb:'In the westernmost bastion of the Leonine Wall, at the far tip of the Gardens, a small landing pad lets the pope leave the city by air for Castel Gandolfo or Rome\u2019s airports. On the afternoon of 28 February 2013, Benedict XVI lifted off from here for Castel Gandolfo, a few hours before his resignation took effect.',\n      facts:['Built under Paul VI to spare the pope hours on the road','Marks the westernmost point of Vatican City, about 75 m above sea level','In 2011 Benedict XVI flew from here to San Marino, the first direct flight from the Vatican to a country other than Italy'] },\n    { id:'grotto', image:'', credit:'',\n      name:'Lourdes Grotto', it:'Grotta di Lourdes', date:'Dedicated 1902',\n      blurb:'A full-scale copy of the rock grotto at Massabielle, where Bernadette Soubirous saw her visions in 1858, given to Leo XIII by French Catholics. Popes have long come here to close the Marian month of May with the Rosary.',\n      facts:['Built for Leo XIII as a gift of the French faithful','The altar came from the real grotto at Lourdes in 1958','A statue of the Virgin stands in a niche above, as at Lourdes','Tucked into the western Gardens among the umbrella pines'] },\n    { id:'walls', image:'', credit:'',\n      name:'The Vatican Walls', it:'Mura Leonine e Vaticane', date:'From 848',\n      blurb:'After Saracen raiders plundered St. Peter\u2019s in 846, Leo IV raised walls around the Vatican hill, creating the Leonine City. The massive bastions that ring the Gardens today were rebuilt in the sixteenth and seventeenth centuries, when cannon had changed the rules of siege.',\n      facts:['Leo IV\u2019s walls were built between 848 and 852','The Passetto runs along a surviving stretch of the Leonine wall','Vatican City\u2019s border with Italy follows the walls','At St. Peter\u2019s Square the border is a line of travertine in the paving'] }\n  ];\n\n  \/* Questions for Father Dominic, several per place. Each time a card opens,\n     one is chosen at random for the main button and the rest appear under\n     \u201cMore questions.\u201d Add, remove, or reword them freely. *\/\n  var ASK = {\n    archive: [\n      'Father, what is it really like to work inside the Apostolic Archive?',\n      'Why was the Secret Archive renamed the Apostolic Archive in 2019?',\n      'What is the most remarkable document you have ever held in the Archive?',\n      'How does a scholar earn permission to study in the Archive?' ],\n    bunker: [\n      'What is kept in the Archive\u2019s underground Bunker, and who is allowed down there?',\n      'Why was the Bunker dug beneath the Cortile della Pigna?',\n      'How do archivists protect fragile manuscripts from fire, flood, and time?',\n      'Are there documents in the Bunker that no one has opened in centuries?' ],\n    tower: [\n      'How did the Tower of the Winds help reform the calendar?',\n      'How does the sunbeam in the Meridian Room work?',\n      'Who were the astronomers who once worked in the Tower of the Winds?',\n      'What do the frescoed winds inside the tower depict?' ],\n    library: [\n      'What are the greatest treasures of the Vatican Apostolic Library?',\n      'What is the Codex Vaticanus, and why does it matter so much?',\n      'Who founded the Vatican Library, and what was he hoping to build?',\n      'Are there texts in the Library that are rarely, if ever, shown?' ],\n    sistine: [\n      'What really happens inside the Sistine Chapel during a conclave?',\n      'Did Michelangelo really paint the ceiling lying on his back?',\n      'How is the black and white smoke made after each ballot?',\n      'What hidden details should I look for in The Last Judgment?' ],\n    raphael: [\n      'What is the story behind Raphael\u2019s School of Athens?',\n      'Which real people did Raphael paint among the philosophers?',\n      'Why did Pope Julius II hand these rooms to a young Raphael?',\n      'What legend does the Fire in the Borgo fresco tell?' ],\n    palace: [\n      'What is daily life like inside the Apostolic Palace?',\n      'From which window does the pope pray the Angelus on Sundays?',\n      'What ceremonies once took place in the Sala Regia?',\n      'Who works in the Apostolic Palace, and what do they do?' ],\n    basilica: [\n      'Is Saint Peter truly buried beneath the basilica?',\n      'How long did it take to build the new St. Peter\u2019s, and who designed it?',\n      'What is the Holy Door, and when is it opened?',\n      'Did Bernini really strip bronze from the Pantheon for his baldachin?' ],\n    scavi: [\n      'What did the secret excavations beneath St. Peter\u2019s uncover?',\n      'What is the Red Wall, and what was found beside it?',\n      'How were the bones in the graffiti wall identified as Peter\u2019s?',\n      'Can visitors walk through the necropolis today?' ],\n    square: [\n      'What is the secret of the two marked discs in St. Peter\u2019s Square?',\n      'How did an Egyptian obelisk end up in the middle of the square?',\n      'Why did Bernini shape the colonnade like two embracing arms?',\n      'What happened in the square on 13 May 1981?' ],\n    museums: [\n      'Which treasures in the Vatican Museums should no visitor miss?',\n      'How did the Laoco\u00f6n come to the Vatican?',\n      'How long would it take to see everything in the Vatican Museums?',\n      'What is the story of the famous double-spiral staircase?' ],\n    gardens: [\n      'What hidden places lie within the Vatican Gardens?',\n      'Why is there a replica of the Lourdes grotto in the Gardens?',\n      'Do popes still walk and pray in the Vatican Gardens?',\n      'Is there really a railway station inside Vatican City?' ],\n    governorate: [\n      'How is Vatican City actually governed from day to day?',\n      'Does Vatican City have its own police, courts, and post office?',\n      'Who keeps the Vatican running when there is no pope?',\n      'How does the smallest country in the world pay its bills?' ],\n    santamarta: [\n      'Why do the cardinals stay at Casa Santa Marta during a conclave?',\n      'Why did Pope Francis choose to live at Santa Marta instead of the palace?',\n      'What is a day like for a cardinal sequestered during a conclave?',\n      'What stood on this spot before Casa Santa Marta was built?' ],\n    passetto: [\n      'How did Pope Clement VII escape along the Passetto in 1527?',\n      'Why was a hidden corridor built along the top of the Leonine Wall?',\n      'Which other popes have fled along the Passetto?',\n      'Is the Passetto still used today, and can anyone walk it?' ],\n    colonnade: [\n      'Where should I stand to see the columns line up into a single row?',\n      'Who are the 140 saints standing on top of the colonnade?',\n      'How did Bernini win the commission for St. Peter\u2019s Square?',\n      'Was the colonnade ever meant to have a third arm?' ],\n    castel: [\n      'How did Hadrian\u2019s tomb become a papal fortress?',\n      'Why is an angel sheathing a sword on top of the castle?',\n      'Which popes and prisoners were held inside Castel Sant\u2019Angelo?',\n      'Does the Passetto still connect the Vatican to the castle?' ],\n    barracks: [\n      'Father, what is daily life really like for a young Swiss Guard?',\n      'How does someone become a Swiss Guard, and why must they be Swiss?',\n      'Why are new guards sworn in every year on 6 May?',\n      'Who actually designed the famous striped uniforms?' ],\n    armory: [\n      'What weapons does the Swiss Guard really carry today?',\n      'Is the halberd still a practical weapon, or only ceremonial?',\n      'How are the armor and plumed helmets made and cared for?',\n      'Has the Swiss Guard ever had to fight to defend a pope?' ],\n    santanna: [\n      'What happens at St. Anne\u2019s Gate on an ordinary morning?',\n      'Can visitors walk through St. Anne\u2019s Gate?',\n      'Is it true the Vatican has its own pharmacy and supermarket?',\n      'Why is the little church by the gate dedicated to Saint Anne?' ],\n    canteen: [\n      'What is lunch like in the Vatican staff canteen?',\n      'Is it true Pope Francis once stood in line for lunch with the staff?',\n      'Where do the Swiss Guards eat, and what is on the menu?',\n      'Father, where do you like to eat when you leave the Archive at midday?' ],\n    heliport: [\n      'Where does the pope fly from the Vatican heliport?',\n      'Father, have you ever flown aboard Shepherd Two?',\n      'Why did Pope Benedict XVI leave the Vatican by helicopter in 2013?',\n      'How does a helicopter land safely inside such a small city?' ],\n    grotto: [\n      'Why is there a copy of the Lourdes grotto in the Vatican Gardens?',\n      'Is the altar in the grotto really from Lourdes?',\n      'Do the popes still come here to pray?',\n      'What other shrines are hidden among the Gardens?' ],\n    walls: [\n      'Why did Pope Leo IV build walls around the Vatican?',\n      'Where exactly is the border between Vatican City and Italy?',\n      'Could the Vatican walls still defend the city today?',\n      'Are there hidden gates or passages in the Vatican walls?' ],\n    apartments: [\n      'What is it like inside the Papal Apartments?',\n      'Why does the pope pray the Angelus from that particular window?',\n      'Father, have you ever been inside the pope\u2019s private study?',\n      'What do the words of the blessing from the window mean?' ]\n  };\n\n  var TOUR = ['square','colonnade','basilica','scavi','sistine','raphael','palace','apartments','santanna','barracks','armory','canteen','passetto','castel','library','tower','archive','bunker','museums','gardens','grotto','heliport','walls','governorate','santamarta'];\n  var ZOOM = { square:2.4, gardens:2.2, basilica:3.2, passetto:3.4, palace:3.6, museums:3.8, colonnade:2.8, castel:3.2, walls:2.8, apartments:5.5 };\n  var SECRETS = ['archive','bunker','tower','scavi','passetto'];\n  var LIFE = ['apartments','barracks','armory','santanna','canteen','heliport'];\n  var FEATURED = ['apartments'];\n  \/* places the map glides in close on when opened (zoom factor) *\/\n  var CLOSE = { apartments: 7.6 };\n\n  \/* ---------------- plan drawings for the cards ---------------- *\/\n  function wrap(inner){ return '<svg viewBox=\"0 0 320 180\" preserveAspectRatio=\"xMidYMid slice\" aria-hidden=\"true\"><defs>'+\n    '<linearGradient id=\"vgSky\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#f7eed9\"\/><stop offset=\"1\" stop-color=\"#e3d2ae\"\/><\/linearGradient>'+\n    '<linearGradient id=\"vgStone\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#efe4cc\"\/><stop offset=\"1\" stop-color=\"#cbb791\"\/><\/linearGradient>'+\n    '<linearGradient id=\"vgGold\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#f1dc98\"\/><stop offset=\"1\" stop-color=\"#bf9440\"\/><\/linearGradient>'+\n    '<radialGradient id=\"vgVig\" cx=\".5\" cy=\".45\" r=\".75\"><stop offset=\".6\" stop-color=\"#3b2a14\" stop-opacity=\"0\"\/><stop offset=\"1\" stop-color=\"#3b2a14\" stop-opacity=\".38\"\/><\/radialGradient>'+\n    '<\/defs><rect width=\"320\" height=\"180\" fill=\"url(#vgSky)\"\/>' + inner + '<rect width=\"320\" height=\"180\" fill=\"url(#vgVig)\"\/><\/svg>'; }\n  var V = {\n    basilica: function(){ return wrap(\n      '<path class=\"v-fill\" d=\"M60 74 H118 V40 H178 V74 H262 V106 H178 V140 H118 V106 H60 Z\"\/><path class=\"v-fill\" d=\"M60 74 A16 16 0 0 0 60 106 Z\"\/>' +\n      '<rect x=\"262\" y=\"66\" width=\"10\" height=\"48\" class=\"v-dark\"\/><circle cx=\"148\" cy=\"90\" r=\"27\" class=\"v-gold\"\/><circle cx=\"148\" cy=\"90\" r=\"17\" class=\"v-ink\"\/><circle cx=\"148\" cy=\"90\" r=\"4\" class=\"v-red\"\/>' +\n      '<g class=\"v-soft\"><line x1=\"190\" y1=\"74\" x2=\"190\" y2=\"106\"\/><line x1=\"210\" y1=\"74\" x2=\"210\" y2=\"106\"\/><line x1=\"230\" y1=\"74\" x2=\"230\" y2=\"106\"\/><line x1=\"250\" y1=\"74\" x2=\"250\" y2=\"106\"\/><\/g>' +\n      '<text x=\"148\" y=\"160\" class=\"v-txt\" text-anchor=\"middle\">Dome over the crossing \u00b7 high altar above the tomb<\/text>'); },\n    square: function(){ var d=''; for(var i=0;i<44;i++){ var a=Math.PI*0.12+i*(Math.PI*1.76\/43); d+='<circle cx=\"'+(175+Math.cos(a)*92).toFixed(1)+'\" cy=\"'+(92+Math.sin(a)*62).toFixed(1)+'\" r=\"2.4\" class=\"v-dark\"\/>'; }\n      return wrap('<ellipse cx=\"175\" cy=\"92\" rx=\"84\" ry=\"54\" fill=\"#efe5cf\" class=\"v-soft\"\/>' + d + '<path class=\"v-fill\" d=\"M20 60 H64 V124 H20 Z\"\/><path class=\"v-ink\" d=\"M64 64 L95 40 M64 120 L95 144\"\/>' +\n      '<rect x=\"172\" y=\"70\" width=\"6\" height=\"44\" class=\"v-dark\"\/><path d=\"M172 70 L175 62 L178 70 Z\" class=\"v-dark\"\/><circle cx=\"175\" cy=\"48\" r=\"5\" class=\"v-gold\"\/><circle cx=\"175\" cy=\"136\" r=\"5\" class=\"v-gold\"\/>' +\n      '<text x=\"175\" y=\"170\" class=\"v-txt\" text-anchor=\"middle\">Bernini\u2019s colonnades \u00b7 obelisk \u00b7 twin fountains<\/text>'); },\n    sistine: function(){ var p='', x=58, big=true; for(var i=0;i<9;i++){ var w=big?24:16, h=big?58:40, y=90-h\/2; p+='<rect x=\"'+x+'\" y=\"'+y+'\" width=\"'+w+'\" height=\"'+h+'\" class=\"'+(big?'v-gold':'v-fill')+'\"\/>'; x+=w+3; big=!big; }\n      var s=''; for(var j=0;j<6;j++){ var sx=64+j*36; s+='<path class=\"v-ink\" d=\"M'+sx+' 34 L'+(sx+18)+' 52 L'+(sx+36)+' 34\"\/><path class=\"v-ink\" d=\"M'+sx+' 146 L'+(sx+18)+' 128 L'+(sx+36)+' 146\"\/>'; }\n      return wrap('<rect x=\"40\" y=\"30\" width=\"240\" height=\"120\" class=\"v-fill\"\/>' + s + p + '<rect x=\"282\" y=\"30\" width=\"14\" height=\"120\" class=\"v-red\"\/>' +\n      '<text x=\"160\" y=\"170\" class=\"v-txt\" text-anchor=\"middle\">Ceiling plan \u00b7 nine Genesis panels \u00b7 Last Judgment wall<\/text>'); },\n    palace: function(){ var w=''; for(var r=0;r<4;r++){ for(var c=0;c<11;c++){ var lit=(r===0&&c===8); w+='<rect x=\"'+(52+c*20)+'\" y=\"'+(46+r*24)+'\" width=\"9\" height=\"14\" class=\"'+(lit?'v-gold':'v-dark')+'\"\/>'; } }\n      return wrap('<rect x=\"40\" y=\"34\" width=\"240\" height=\"116\" class=\"v-fill\"\/><line x1=\"40\" y1=\"64\" x2=\"280\" y2=\"64\" class=\"v-soft\"\/>' + w +\n      '<path class=\"v-ink\" d=\"M218 38 L222 26 M222 26 L240 26\"\/><text x=\"244\" y=\"29\" class=\"v-txt\">Angelus window<\/text><text x=\"160\" y=\"170\" class=\"v-txt\" text-anchor=\"middle\">Top floor \u00b7 the papal apartments<\/text>'); },\n    raphael: function(){ var names=['Costantino','Eliodoro','Segnatura','Incendio'], o='';\n      for(var i=0;i<4;i++){ var x=24+i*70; o+='<rect x=\"'+x+'\" y=\"60\" width=\"62\" height=\"62\" class=\"v-fill\"\/><path class=\"v-gold\" d=\"M'+(x+8)+' 60 A23 18 0 0 1 '+(x+54)+' 60 Z\"\/><text x=\"'+(x+31)+'\" y=\"98\" text-anchor=\"middle\" class=\"v-txt\">'+names[i]+'<\/text>'; }\n      return wrap(o + '<path class=\"v-redline\" d=\"M177 132 H215\"\/><text x=\"196\" y=\"146\" text-anchor=\"middle\" class=\"v-txt\">School of Athens<\/text><text x=\"160\" y=\"40\" class=\"v-txt\" text-anchor=\"middle\">Four rooms \u00b7 frescoed lunettes<\/text>'); },\n    archive: function(){ var o='', vx=160, vy=88;\n      for(var k=0;k<7;k++){ var x=10+k*20, sc=1-k*0.12, top=vy-70*sc, bot=vy+76*sc;\n        o+='<line x1=\"'+x+'\" y1=\"'+top.toFixed(1)+'\" x2=\"'+x+'\" y2=\"'+bot.toFixed(1)+'\" class=\"v-ink\"\/><line x1=\"'+(320-x)+'\" y1=\"'+top.toFixed(1)+'\" x2=\"'+(320-x)+'\" y2=\"'+bot.toFixed(1)+'\" class=\"v-ink\"\/>';\n        for(var s=0;s<5;s++){ var y=top+(bot-top)*(s+0.55)\/5, h=(bot-top)\/5*0.6;\n          if((k+s)%3===0){ o+='<rect x=\"'+(x+3)+'\" y=\"'+(y-h).toFixed(1)+'\" width=\"'+(14*sc).toFixed(1)+'\" height=\"'+h.toFixed(1)+'\" class=\"'+((k+s)%2?'v-red':'v-gold')+'\"\/><rect x=\"'+(320-x-3-14*sc).toFixed(1)+'\" y=\"'+(y-h).toFixed(1)+'\" width=\"'+(14*sc).toFixed(1)+'\" height=\"'+h.toFixed(1)+'\" class=\"v-gold\"\/>'; } } }\n      for(var t=0;t<6;t++){ var yy=[18,46,74,102,130,164][t]; o+='<line x1=\"0\" y1=\"'+yy+'\" x2=\"'+vx+'\" y2=\"'+(vy+(yy-vy)*0.12).toFixed(1)+'\" class=\"v-soft\"\/><line x1=\"320\" y1=\"'+yy+'\" x2=\"'+vx+'\" y2=\"'+(vy+(yy-vy)*0.12).toFixed(1)+'\" class=\"v-soft\"\/>'; }\n      return wrap(o + '<rect x=\"146\" y=\"64\" width=\"28\" height=\"46\" class=\"v-dark\"\/><rect x=\"152\" y=\"70\" width=\"16\" height=\"34\" fill=\"#f1d58a\"\/>'); },\n    bunker: function(){ var sh=''; for(var i=0;i<12;i++){ sh+='<line x1=\"'+(56+i*18)+'\" y1=\"82\" x2=\"'+(56+i*18)+'\" y2=\"108\" class=\"v-soft\"\/><line x1=\"'+(56+i*18)+'\" y1=\"122\" x2=\"'+(56+i*18)+'\" y2=\"148\" class=\"v-soft\"\/>'; }\n      return wrap('<path d=\"M0 62 H320 V180 H0 Z\" fill=\"#c8b68f\"\/><path d=\"M0 62 H320\" class=\"v-ink\"\/><rect x=\"0\" y=\"56\" width=\"320\" height=\"6\" fill=\"#9fa86a\"\/>' +\n      '<ellipse cx=\"80\" cy=\"42\" rx=\"9\" ry=\"15\" class=\"v-gold\"\/><rect x=\"74\" y=\"56\" width=\"12\" height=\"4\" class=\"v-dark\"\/><circle cx=\"220\" cy=\"42\" r=\"14\" class=\"v-gold\"\/><path class=\"v-ink\" d=\"M210 38 L230 46 M214 50 L228 34\"\/>' +\n      '<rect x=\"48\" y=\"76\" width=\"224\" height=\"36\" class=\"v-fill\"\/><rect x=\"48\" y=\"118\" width=\"224\" height=\"36\" class=\"v-fill\"\/>' + sh +\n      '<path class=\"v-redline\" d=\"M40 66 L40 158\"\/><text x=\"276\" y=\"98\" class=\"v-txt\">\u22121<\/text><text x=\"276\" y=\"140\" class=\"v-txt\">\u22122<\/text><text x=\"160\" y=\"20\" class=\"v-txt\" text-anchor=\"middle\">Cortile della Pigna \u00b7 courtyard level<\/text>'); },\n    tower: function(){ return wrap('<rect x=\"30\" y=\"24\" width=\"260\" height=\"130\" class=\"v-fill\"\/><path d=\"M30 154 L290 154\" class=\"v-ink\"\/><circle cx=\"62\" cy=\"40\" r=\"3.5\" class=\"v-dark\"\/>' +\n      '<path class=\"v-goldline\" d=\"M62 40 L214 150\"\/><ellipse cx=\"214\" cy=\"150\" rx=\"12\" ry=\"4\" fill=\"#f6dc8e\"\/><path class=\"v-redline\" d=\"M60 150 L270 150\"\/>' +\n      '<g class=\"v-soft\"><path d=\"M110 24 A50 22 0 0 0 210 24\"\/><line x1=\"160\" y1=\"24\" x2=\"160\" y2=\"46\"\/><\/g><circle cx=\"160\" cy=\"46\" r=\"6\" class=\"v-gold\"\/><path class=\"v-ink\" d=\"M160 46 L172 38\"\/>' +\n      '<text x=\"160\" y=\"172\" class=\"v-txt\" text-anchor=\"middle\">Sunlight through the aperture strikes the meridian<\/text>'); },\n    library: function(){ var o=''; for(var i=0;i<6;i++){ var w=260-i*38, h=120-i*16, x=160-w\/2, y=150-h; o+='<path class=\"'+(i===0?'v-fill':'v-ink')+'\" d=\"M'+x+' 150 V'+(y+w\/4).toFixed(1)+' A'+(w\/2)+' '+(w\/4)+' 0 0 1 '+(x+w)+' '+(y+w\/4).toFixed(1)+' V150\"\/>'; }\n      return wrap(o + '<path class=\"v-soft\" d=\"M30 150 L160 110 L290 150\"\/><rect x=\"58\" y=\"120\" width=\"12\" height=\"30\" class=\"v-gold\"\/><rect x=\"250\" y=\"120\" width=\"12\" height=\"30\" class=\"v-gold\"\/><text x=\"160\" y=\"170\" class=\"v-txt\" text-anchor=\"middle\">Salone Sistino \u00b7 painted vaults<\/text>'); },\n    museums: function(){ var h=''; for(var i=0;i<7;i++){ h+='<path class=\"v-soft\" d=\"M'+(140+i*6.6)+' 64 L'+(146+i*5)+' 126\"\/>'; }\n      return wrap('<path class=\"v-fill\" d=\"M70 160 V80 A90 64 0 0 1 250 80 V160 Z\"\/><path d=\"M96 160 V88 A64 48 0 0 1 224 88 V160 Z\" fill=\"#cdbf9e\" stroke=\"#2e2416\" stroke-width=\"1.2\"\/>' +\n      '<ellipse cx=\"160\" cy=\"96\" rx=\"22\" ry=\"34\" class=\"v-gold\"\/>' + h + '<rect x=\"138\" y=\"128\" width=\"44\" height=\"32\" class=\"v-fill\"\/><circle cx=\"114\" cy=\"138\" r=\"7\" class=\"v-green\"\/><circle cx=\"206\" cy=\"138\" r=\"7\" class=\"v-green\"\/>' +\n      '<text x=\"160\" y=\"22\" class=\"v-txt\" text-anchor=\"middle\">The Nicchione and the bronze Pigna<\/text>'); },\n    gardens: function(){ var t='', sd=3; function r(){ sd=(sd*9301+49297)%233280; return sd\/233280; }\n      for(var i=0;i<38;i++){ var x=10+r()*300, y=20+r()*140; if(x>200&&x<268&&y>60&&y<112) continue; t+='<circle cx=\"'+x.toFixed(0)+'\" cy=\"'+y.toFixed(0)+'\" r=\"'+(5+r()*7).toFixed(1)+'\" class=\"v-green\"\/>'; }\n      return wrap('<rect width=\"320\" height=\"180\" fill=\"#cfd09c\" opacity=\".7\"\/><path d=\"M0 140 C80 100, 140 160, 220 110 S300 60, 320 70\" fill=\"none\" stroke=\"#efe5cb\" stroke-width=\"8\"\/>' + t +\n      '<rect x=\"208\" y=\"70\" width=\"52\" height=\"34\" class=\"v-fill\"\/><path class=\"v-ink\" d=\"M208 70 L234 58 L260 70\"\/><text x=\"234\" y=\"124\" class=\"v-txt\" text-anchor=\"middle\">Casina Pio IV<\/text>'); },\n    governorate: function(){ var w=''; for(var c=0;c<12;c++){ if(c===5||c===6) continue; w+='<rect x=\"'+(50+c*19)+'\" y=\"70\" width=\"8\" height=\"12\" class=\"v-dark\"\/><rect x=\"'+(50+c*19)+'\" y=\"96\" width=\"8\" height=\"12\" class=\"v-dark\"\/>'; }\n      return wrap('<rect x=\"38\" y=\"58\" width=\"244\" height=\"72\" class=\"v-fill\"\/><rect x=\"130\" y=\"44\" width=\"60\" height=\"86\" class=\"v-fill\"\/>' + w +\n      '<path class=\"v-fill\" d=\"M148 130 V104 A12 12 0 0 1 172 104 V130 Z\"\/><line x1=\"160\" y1=\"44\" x2=\"160\" y2=\"20\" class=\"v-ink\"\/><rect x=\"160\" y=\"20\" width=\"18\" height=\"11\" class=\"v-gold\"\/>' +\n      '<path d=\"M0 130 H320\" class=\"v-ink\"\/><text x=\"160\" y=\"158\" class=\"v-txt\" text-anchor=\"middle\">Seat of civil administration<\/text>'); },\n    scavi: function(){ var m=''; for(var i=0;i<6;i++){ var x=26+i*46; m+='<path class=\"v-fill\" d=\"M'+x+' 166 V140 A16 12 0 0 1 '+(x+32)+' 140 V166 Z\"\/>'; }\n      return wrap('<path d=\"M0 56 H320\" class=\"v-ink\"\/><path class=\"v-fill\" d=\"M140 56 V30 H180 V56\"\/><path class=\"v-ink\" d=\"M136 30 Q160 12 184 30\"\/>' +\n      '<rect x=\"0\" y=\"56\" width=\"320\" height=\"44\" fill=\"#d9cdb1\"\/><text x=\"20\" y=\"82\" class=\"v-txt\">Vatican Grottoes<\/text><path d=\"M0 100 H320\" class=\"v-ink\"\/><rect x=\"0\" y=\"100\" width=\"320\" height=\"80\" fill=\"#c4b38e\"\/>' + m +\n      '<rect x=\"152\" y=\"104\" width=\"16\" height=\"36\" class=\"v-red\"\/><path class=\"v-redline\" d=\"M160 56 V104\"\/><text x=\"176\" y=\"118\" class=\"v-txt\">Red Wall<\/text><text x=\"20\" y=\"118\" class=\"v-txt\">Roman necropolis<\/text>'); },\n    santamarta: function(){ var w=''; for(var r=0;r<5;r++){ for(var c=0;c<10;c++){ w+='<rect x=\"'+(66+c*19)+'\" y=\"'+(42+r*20)+'\" width=\"9\" height=\"11\" class=\"v-dark\"\/>'; } }\n      return wrap('<rect x=\"54\" y=\"30\" width=\"212\" height=\"122\" class=\"v-fill\"\/>' + w + '<rect x=\"146\" y=\"132\" width=\"28\" height=\"20\" class=\"v-gold\"\/>' +\n      '<circle cx=\"30\" cy=\"132\" r=\"14\" class=\"v-green\"\/><circle cx=\"290\" cy=\"128\" r=\"16\" class=\"v-green\"\/><path d=\"M0 152 H320\" class=\"v-ink\"\/><text x=\"160\" y=\"172\" class=\"v-txt\" text-anchor=\"middle\">Guesthouse within the walls<\/text>'); },\n    passetto: function(){ var ar='', mer=''; for(var i=0;i<9;i++){ var x=14+i*26; ar+='<path class=\"v-dark\" d=\"M'+x+' 150 V130 A9 9 0 0 1 '+(x+18)+' 130 V150 Z\"\/>'; }\n      for(var j=0;j<20;j++){ mer+='<rect x=\"'+(8+j*12)+'\" y=\"72\" width=\"7\" height=\"8\" class=\"v-fill\"\/>'; }\n      return wrap('<rect x=\"0\" y=\"150\" width=\"320\" height=\"30\" fill=\"#cdbb96\"\/><rect x=\"6\" y=\"80\" width=\"236\" height=\"70\" class=\"v-fill\"\/>'+mer+ar+'<rect x=\"6\" y=\"92\" width=\"236\" height=\"12\" fill=\"#3a2e1e\" opacity=\".2\"\/>'+\n      '<path class=\"v-fill\" d=\"M236 150 V58 A42 12 0 0 1 320 58 V150 Z\"\/><ellipse cx=\"278\" cy=\"58\" rx=\"42\" ry=\"12\" class=\"v-fill\"\/><rect x=\"262\" y=\"34\" width=\"32\" height=\"24\" class=\"v-fill\"\/><path class=\"v-ink\" d=\"M278 34 V18 M272 22 L284 22\"\/>'+\n      '<text x=\"120\" y=\"64\" class=\"v-txt\" text-anchor=\"middle\">Covered walkway atop the Leonine Wall<\/text><text x=\"278\" y=\"170\" class=\"v-txt\" text-anchor=\"middle\">Castel Sant\u2019Angelo<\/text>'); }\n  };\n\n\n\n  \/* ---------------- elements ---------------- *\/\n  var $ = function(s){ return root.querySelector(s); };\n\n  \/* Copyright years: first year, then a span once a new year begins (e.g. 2026\u20132027) *\/\n  (function(){ var FIRST=2026, now=new Date().getFullYear(), el=root.querySelector('.vm-copy-yr');\n    if(el) el.textContent = now>FIRST ? FIRST+'\\u2013'+now : String(FIRST); })();\n  var stage=$('.vm-stage'), plane=$('.vm-plane'), img=$('.vm-img'), pinsBox=$('.vm-pins'), halo=$('.vm-halo'), spot=$('.vm-spot'),\n      card=$('.vm-card'), cardInner=$('.vm-card-inner'), legend=$('.vm-legend'), legendBody=$('.vm-legend-body'), hint=$('.vm-hint'),\n      tourBtn=$('.vm-tourbtn'), tourBar=$('.vm-tourbar'), below=$('.vm-below'), needle=$('.vm-needle'), tiltBtn=$('.vm-tilt'), msg=$('.vm-msg');\n  var occEl=$('.vm-occ');\n  if (CONFIG.BACKDROP==='light'){ root.classList.remove('is-dark'); root.classList.add('is-light'); }\n  var isTouch = matchMedia('(hover: none)').matches; if (isTouch) root.classList.add('is-touch');\n  var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;\n  hint.textContent = isTouch ? 'Drag to explore \u00b7 pinch to zoom \u00b7 twist to rotate' : 'Drag to explore \u00b7 scroll to zoom \u00b7 Shift-drag to rotate and tilt';\n\n  \/* numbers follow the legend: the secret city, then landmarks, then life behind the walls *\/\n  var BYID={}; PLACES.forEach(function(p){ BYID[p.id]=p; });\n  PLACES.filter(function(p){ return SECRETS.indexOf(p.id)>=0; })\n    .concat(PLACES.filter(function(p){ return SECRETS.indexOf(p.id)<0 && LIFE.indexOf(p.id)<0; }))\n    .concat(PLACES.filter(function(p){ return LIFE.indexOf(p.id)>=0; }))\n    .forEach(function(p,i){ p.n=i+1; });\n  function frac(p){ var q=CONFIG.POSITIONS[p.id]||[50,50]; return [q[0]\/100,q[1]\/100]; }\n\n  \/* ---------------- view state & projection ---------------- *\/\n  var D=Math.PI\/180, IW=1672, IH=941, SW=0, SH=0, W=0, H=0, PERSP=1400;\n  var st={tx:0,ty:0,s:1,rot:0,tilt:0}, MIN_S=0.7, MAX_S=6, MAX_TILT=58;\n  var compact=false, held=null, peek=null, touring=false;\n\n  function fitHeight(){\n    var fs=document.fullscreenElement||document.webkitFullscreenElement;\n    if(fs){ stage.style.height=''; return; }\n    var vh=window.innerHeight, top=root.getBoundingClientRect().top+(window.pageYOffset||0), w=root.clientWidth, h;\n    var hh=headH(), avail=vh-Math.max(hh+8,(top<vh*0.5?top:0))-12;\n    if(compact) h=Math.max(420,Math.min(avail,780));\n    else h=Math.max(460,Math.min(avail,w*0.62));\n    stage.style.height=Math.round(h)+'px';\n  }\n  \/* height of any fixed or sticky bar (the site menu) across the top of the window *\/\n  function headH(){\n    var x=Math.round(window.innerWidth\/2), y=0;\n    for(var k=0;k<3;k++){\n      var el=document.elementFromPoint(x,y+1), f=null;\n      for(var n=el;n&&n!==document.body&&n!==document.documentElement;n=n.parentElement){ if(n===root) return y; var p=getComputedStyle(n).position; if(p===\"fixed\"||p===\"sticky\") f=n; }\n      if(!f) return y; var b=f.getBoundingClientRect().bottom; if(b<=y+1||b>window.innerHeight*0.5) return y; y=Math.round(b);\n    }\n    return y;\n  }\n  var coverRaf=0;\n  function updateCover(){ coverRaf=0; var r=stage.getBoundingClientRect(), c=Math.max(0,Math.min(headH()-r.top,r.height-200)); root.style.setProperty(\"--vm-cover\",Math.round(c)+\"px\"); }\n  window.addEventListener(\"scroll\",function(){ if(!coverRaf) coverRaf=requestAnimationFrame(updateCover); },{passive:true});\n  function layout(){\n    fitHeight();\n    var cp=root.querySelector('.vm-copy'); legend.style.bottom = compact && cp ? (cp.offsetHeight+24)+'px' : '';\n    SW=stage.clientWidth; SH=stage.clientHeight;\n    var m=compact?0.98:0.94, ar=IH\/IW;\n    W=SW*m; H=W*ar; if(H>SH*m){ H=SH*m; W=H\/ar; }\n    plane.style.width=W+'px'; plane.style.height=H+'px'; plane.style.marginLeft=(-W\/2)+'px'; plane.style.marginTop=(-H\/2)+'px';\n    if(occEl){ occEl.style.width=W+'px'; occEl.style.height=H+'px'; occEl.style.marginLeft=(-W\/2)+'px'; occEl.style.marginTop=(-H\/2)+'px'; }\n    PERSP=Math.max(900,SW*1.15); stage.style.perspective=PERSP+'px'; stage.style.perspectiveOrigin='50% 50%';\n    apply(); updateCover(); lifeSize();\n  }\n  function project(fx,fy,v){\n    v=v||st; var u=(fx-0.5)*W*v.s, w=(fy-0.5)*H*v.s, r=v.rot*D, c=Math.cos(r), s=Math.sin(r);\n    var x=u*c-w*s, y=u*s+w*c, t=v.tilt*D, y2=y*Math.cos(t), z=y*Math.sin(t), k=PERSP\/(PERSP-z);\n    return {x:SW\/2+(x+v.tx)*k, y:SH\/2+(y2+v.ty)*k, k:k, rx:x, ry:y2};\n  }\n  function unproject(sx,sy){\n    var X=sx-SW\/2, Y=sy-SH\/2, t=st.tilt*D, a=Math.cos(t), b=Math.sin(t);\n    var y=PERSP*(Y-st.ty)\/(PERSP*a+Y*b);\n    var k=PERSP\/(PERSP-y*b), x=X\/k-st.tx, r=st.rot*D, c=Math.cos(r), s=Math.sin(r);\n    var u=(x*c+y*s)\/st.s, w=(-x*s+y*c)\/st.s;\n    return [u\/W+0.5, w\/H+0.5];\n  }\n  function clampView(v){\n    v.s=Math.max(MIN_S,Math.min(MAX_S,v.s)); v.tilt=Math.max(0,Math.min(MAX_TILT,v.tilt));\n    var lx=W*v.s*0.55+SW*0.2, ly=H*v.s*0.55+SH*0.2; v.tx=Math.max(-lx,Math.min(lx,v.tx)); v.ty=Math.max(-ly,Math.min(ly,v.ty));\n    return v;\n  }\n\n  \/* ---------------- markers & legend ---------------- *\/\n  var pinEls={}, lgEls={};\n  PLACES.forEach(function(p,i){\n    var el=document.createElement('div'); el.className='vm-pin'+(SECRETS.indexOf(p.id)>=0||FEATURED.indexOf(p.id)>=0?' is-featured':'');\n    el.innerHTML='<button type=\"button\" class=\"vm-pin-in vm-ui-pin\" aria-label=\"'+p.n+'. '+esc(p.name)+'\" style=\"animation-delay:'+(reduce?0:(1.3+i*0.07)).toFixed(2)+'s\">'+\n      '<span class=\"vm-pin-tag\">'+esc(p.name)+'<\/span><span class=\"vm-pin-disc\">'+p.n+'<\/span><span class=\"vm-pin-stem\"><\/span><span class=\"vm-pin-foot\"><\/span><\/button>';\n    pinsBox.appendChild(el); pinEls[p.id]=el;\n    var b=el.firstChild;\n    b.addEventListener('mouseenter',function(){ if(!isTouch) preview(p); });\n    b.addEventListener('mouseleave',function(){ if(!isTouch) unpreview(); });\n    b.addEventListener('focus',function(){ preview(p); });\n    b.addEventListener('click',function(e){ e.stopPropagation(); stopTour(); focusOn(p); });\n  });\n  function lgItem(p){ var b=document.createElement('button'); b.type='button'; b.className='vm-lg'+(SECRETS.indexOf(p.id)>=0||FEATURED.indexOf(p.id)>=0?' is-featured':'');\n    b.innerHTML='<b>'+p.n+'<\/b><span>'+esc(p.name)+'<\/span>';\n    b.addEventListener('mouseenter',function(){ if(!isTouch) preview(p); }); b.addEventListener('mouseleave',function(){ if(!isTouch) unpreview(); });\n    b.addEventListener('click',function(){ stopTour(); focusOn(p); if(compact) legend.classList.add('is-closed'); }); lgEls[p.id]=b; return b; }\n  function group(t){ var d=document.createElement('div'); d.className='vm-lg-group'; d.textContent=t; return d; }\n  legendBody.appendChild(group('The secret city'));\n  PLACES.filter(function(p){ return SECRETS.indexOf(p.id)>=0; }).forEach(function(p){ legendBody.appendChild(lgItem(p)); });\n  legendBody.appendChild(group('Landmarks'));\n  PLACES.filter(function(p){ return SECRETS.indexOf(p.id)<0 && LIFE.indexOf(p.id)<0; }).forEach(function(p){ legendBody.appendChild(lgItem(p)); });\n  legendBody.appendChild(group('Life behind the walls'));\n  PLACES.filter(function(p){ return LIFE.indexOf(p.id)>=0; }).forEach(function(p){ legendBody.appendChild(lgItem(p)); });\n  $('.vm-legend-head').addEventListener('click',function(){ var c=legend.classList.toggle('is-closed'); this.setAttribute('aria-expanded',String(!c)); });\n\n  \/* ---------------- render the view ---------------- *\/\n  function apply(){\n    plane.style.transform='translate3d('+st.tx.toFixed(2)+'px,'+st.ty.toFixed(2)+'px,0) rotateX('+st.tilt.toFixed(2)+'deg) rotateZ('+st.rot.toFixed(2)+'deg) scale('+st.s.toFixed(4)+')';\n    if(occEl) occEl.style.transform=plane.style.transform;\n    PLACES.forEach(function(p){ var f=frac(p), q=project(f[0],f[1]), el=pinEls[p.id];\n      var vis=q.k>0 && q.x>-20 && q.x<SW+20 && q.y>-10 && q.y<SH+40;\n      el.classList.toggle('is-off',!vis); el.style.transform='translate('+q.x.toFixed(1)+'px,'+q.y.toFixed(1)+'px)'; el.style.zIndex=Math.round(q.y); });\n    needle.style.transform='rotate('+st.rot.toFixed(1)+'deg)';\n    tiltBtn.setAttribute('aria-pressed',String(st.tilt>4));\n    var a=held||peek;\n    if(held){ var f2=frac(held), q2=project(f2[0],f2[1]);\n      spot.style.background='radial-gradient(circle at '+q2.x.toFixed(0)+'px '+(q2.y-10).toFixed(0)+'px, rgba(10,7,4,0) 0, rgba(10,7,4,0) '+(90*Math.min(2,q2.k*Math.sqrt(st.s\/2.2))).toFixed(0)+'px, rgba(10,7,4,.55) '+(330).toFixed(0)+'px)'; }\n    placeCard();\n  }\n\n  \/* ---------------- animation ---------------- *\/\n  var anim=null;\n  function ease(k){ return k<.5?4*k*k*k:1-Math.pow(-2*k+2,3)\/2; }\n  function animateTo(t,dur,done){\n    if(anim) cancelAnimationFrame(anim); t=clampView(Object.assign({},st,t));\n    if(reduce||!dur){ Object.assign(st,t); apply(); if(done) done(); return; }\n    var s0=Object.assign({},st), dr=((t.rot-s0.rot)%360+540)%360-180, t0=null;\n    function step(ts){ if(t0===null) t0=ts; var k=Math.min(1,(ts-t0)\/dur), e=ease(k);\n      st.tx=s0.tx+(t.tx-s0.tx)*e; st.ty=s0.ty+(t.ty-s0.ty)*e; st.s=s0.s*Math.pow(t.s\/s0.s,e); st.rot=s0.rot+dr*e; st.tilt=s0.tilt+(t.tilt-s0.tilt)*e; apply();\n      if(k<1) anim=requestAnimationFrame(step); else { anim=null; st.rot=((st.rot%360)+360)%360; if(st.rot>180) st.rot-=360; if(done) done(); } }\n    anim=requestAnimationFrame(step);\n  }\n  function stopAnim(){ if(anim){ cancelAnimationFrame(anim); anim=null; } }\n  function viewFor(p,opt){\n    opt=opt||{}; var f=frac(p), v={s:opt.s||Math.max(st.s,2.3), rot:opt.rot!=null?opt.rot:st.rot, tilt:opt.tilt!=null?opt.tilt:st.tilt, tx:0, ty:0};\n    var q=project(f[0],f[1],v), dx=0, dy=compact?-SH*0.26:SH*0.08;\n    if(!compact){ var fl=340, fr=SW-98-330-24; dx=(fr-fl>220)?((fl+fr)\/2-SW\/2):-SW*0.2; }\n    v.tx=dx\/q.k-q.rx; v.ty=dy\/q.k-q.ry; return v;\n  }\n  function zoomAt(k,sx,sy,dur){\n    var ns=Math.max(MIN_S,Math.min(MAX_S,st.s*k)); k=ns\/st.s; var mx=sx-SW\/2, my=sy-SH\/2;\n    animateTo({s:ns, tx:mx-(mx-st.tx)*k, ty:my-(my-st.ty)*k}, dur);\n  }\n  function rotateBy(d){ var r=d*D, c=Math.cos(r), s=Math.sin(r); animateTo({rot:st.rot+d, tx:st.tx*c-st.ty*s, ty:st.tx*s+st.ty*c}, 650); }\n  function homeView(){\n    if(!compact) return {tx:0,ty:0,s:1,rot:0,tilt:0};\n    var v={s:Math.max(1.6,(SH-150)\/H),rot:0,tilt:0,tx:0,ty:0}, q=project(0.5,0.5,v); v.tx=-q.rx; v.ty=-q.ry-20; return v;\n  }\n  function resetView(){ release(); animateTo(homeView(), 1000); }\n\n  \/* ---------------- card ---------------- *\/\n  var hideT=null;\n  function esc(s){ var d=document.createElement('div'); d.textContent=s==null?'':s; return d.innerHTML; }\n  function aerialStyle(p){\n    var f=frac(p), Z=ZOOM[p.id]||4.4, R=Z*(IH\/IW)*(16\/9);\n    var X=Math.max(0,Math.min(100,(f[0]*Z-0.5)\/(Z-1)*100)), Y=Math.max(0,Math.min(100,(f[1]*R-0.5)\/(R-1)*100));\n    var ox=f[0]*Z*100+(1-Z)*X, oy=f[1]*R*100+(1-R)*Y;\n    return 'background-size:'+(Z*100).toFixed(1)+'% auto;background-position:'+X.toFixed(2)+'% '+Y.toFixed(2)+'%;transform-origin:'+ox.toFixed(1)+'% '+oy.toFixed(1)+'%';\n  }\n  function renderCard(p){\n    var hasPlan=!!V[p.v], tabs=[], layers='';\n    if(p.image){ layers+='<img decoding=\"async\" class=\"vm-layer vm-photo\" src=\"'+esc(p.image)+'\" alt=\"'+esc(p.name)+'\" loading=\"lazy\">'; tabs.push(['vm-photo','Photo']); }\n    layers+='<div class=\"vm-layer vm-aerial'+(p.image?' is-hidden':'')+'\" style=\"'+aerialStyle(p)+'\"><\/div>'; tabs.push(['vm-aerial','From above']);\n    if(hasPlan){ layers+='<div class=\"vm-layer vm-plan is-hidden\">'+V[p.v]()+'<\/div>'; tabs.push(['vm-plan','Plan']); }\n    var tb='<div class=\"vm-tabs\">'+tabs.map(function(t,i){ return '<button type=\"button\" data-l=\"'+t[0]+'\"'+(i===0?' class=\"is-on\"':'')+'>'+t[1]+'<\/button>'; }).join('')+'<\/div>';\n    var i=TOUR.indexOf(p.id);\n    cardInner.innerHTML='<div class=\"vm-media\">'+layers+tb+(p.image&&p.credit?'<span class=\"vm-credit\">'+esc(p.credit)+'<\/span>':'')+'<\/div>'+\n      '<div class=\"vm-body\"><p class=\"vm-it\">'+esc(p.it)+'<\/p><h3 class=\"vm-name\">'+esc(p.name)+'<\/h3><span class=\"vm-date\">'+esc(p.date)+'<\/span>'+\n      '<p class=\"vm-blurb\">'+esc(p.blurb)+'<\/p><ul class=\"vm-facts\">'+p.facts.map(function(f){ return '<li>'+esc(f)+'<\/li>'; }).join('')+'<\/ul>'+\n      askBlock(p)+\n      '<div class=\"vm-card-nav\"><button type=\"button\" data-go=\"'+TOUR[(i-1+TOUR.length)%TOUR.length]+'\">\u2039 '+esc(BYID[TOUR[(i-1+TOUR.length)%TOUR.length]].name)+'<\/button><button type=\"button\" data-go=\"'+TOUR[(i+1)%TOUR.length]+'\">'+esc(BYID[TOUR[(i+1)%TOUR.length]].name)+' \u203a<\/button><\/div><\/div>';\n    cardInner.querySelectorAll('.vm-tabs button').forEach(function(b){ b.addEventListener('click',function(e){ e.stopPropagation();\n      cardInner.querySelectorAll('.vm-tabs button').forEach(function(x){ x.classList.toggle('is-on',x===b); });\n      cardInner.querySelectorAll('.vm-layer').forEach(function(l){ l.classList.toggle('is-hidden',!l.classList.contains(b.getAttribute('data-l'))); }); }); });\n    var box=cardInner.querySelector('.vm-askbox');\n    if(box) box.addEventListener('click',function(e){ var b=e.target.closest('button'); if(!b) return; e.stopPropagation();\n      if(b.classList.contains('vm-ask-more')){ var open=b.getAttribute('aria-expanded')!=='true'; b.setAttribute('aria-expanded',open?'true':'false'); box.querySelector('.vm-ask-list').hidden=!open; return; }\n      if(b.hasAttribute('data-own')){ askFather(null,b); return; }\n      if(b.hasAttribute('data-i')) askFather(cardQs[+b.getAttribute('data-i')],b); });\n    cardInner.querySelectorAll('[data-go]').forEach(function(b){ b.addEventListener('click',function(){ var q=BYID[b.getAttribute('data-go')]; if(touring){ tourIdx=TOUR.indexOf(q.id); tourGo(); } else focusOn(q); }); });\n  }\n  \/* ---------------- Ask Father Dominic ---------------- *\/\n  var toastEl=null, toastT=null;\n  function toast(html,ms){\n    if(!toastEl){ toastEl=document.createElement('div'); toastEl.className='vm-toast'; toastEl.setAttribute('role','status'); stage.appendChild(toastEl); }\n    toastEl.innerHTML=html; toastEl.classList.add('is-on'); clearTimeout(toastT); toastT=setTimeout(function(){ toastEl.classList.remove('is-on'); }, ms||5000);\n  }\n  function findBot(){\n    var A=window.MwaiAPI, b=null; if(!A) return null;\n    try{ if(CONFIG.FD_BOT_ID && A.getChatbot) b=A.getChatbot(CONFIG.FD_BOT_ID); }catch(e){}\n    try{ if(!b && A.chatbots && A.chatbots.length) b=A.chatbots[0]; }catch(e){}\n    try{ if(!b && A.getChatbot) b=A.getChatbot(); }catch(e){}\n    return b && typeof b.ask==='function' ? b : null;\n  }\n  var ASK_IC='<svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\"><path d=\"M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.6c-.5.4-1.3.1-1.3-.6V16.9A2.5 2.5 0 0 1 4 14.5z\" fill=\"currentColor\"\/><\/svg>';\n  var cardQs=[];\n  function askBlock(p){\n    var a=ASK[p.id]; if(!a) return ''; a=(typeof a==='string')?[a]:a.slice(); if(!a.length) return '';\n    var k=Math.floor(Math.random()*a.length); cardQs=[a[k]].concat(a.filter(function(x,i){ return i!==k; }));\n    var h='<div class=\"vm-askbox\"><button type=\"button\" class=\"vm-ask\" data-i=\"0\"><span class=\"vm-ask-ic\" aria-hidden=\"true\">'+ASK_IC+'<\/span><span class=\"vm-ask-tx\"><b>Ask Father Dominic<\/b><i>\u201c'+esc(cardQs[0])+'\u201d<\/i><\/span><\/button>';\n    h+='<button type=\"button\" class=\"vm-ask-more\" aria-expanded=\"false\"><span>More questions<\/span><svg viewBox=\"0 0 12 12\" width=\"12\" height=\"12\" aria-hidden=\"true\"><path d=\"M2 4l4 4 4-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\"\/><\/svg><\/button><ul class=\"vm-ask-list\" hidden>';\n    for(var i=1;i<cardQs.length;i++) h+='<li><button type=\"button\" data-i=\"'+i+'\">'+esc(cardQs[i])+'<\/button><\/li>';\n    return h+'<li><button type=\"button\" class=\"vm-ask-own\" data-own=\"1\">Ask your own question\u2026<\/button><\/li><\/ul><\/div>';\n  }\n  var fd=$('.vm-fd'), fdSlot=$('.vm-fd-slot'), fdOpen=false, fdT=null;\n  function dockChat(){\n    \/* move the chatbot from its block below the map into the map's own panel *\/\n    var c=document.querySelector('.mwai-chatbot-container'); if(!c) return false;\n    if(c.querySelector('.mwai-window')) return false;\n    if(c.parentNode!==fdSlot){ var w=c.closest('.elementor-widget-shortcode'); fdSlot.appendChild(c); if(w) w.style.display='none'; }\n    return true;\n  }\n  \/* Reading position: the chatbot normally chases the end of an answer while it\n     is written. In this panel, each new question moves to the top and the page\n     then stays put, so readers scroll down when they are ready. *\/\n  var nativeTop=Object.getOwnPropertyDescriptor(Element.prototype,'scrollTop');\n  function guardScroll(){\n    var cv=fd.querySelector('.mwai-conversation'); if(!cv||cv.__vmGuard||!nativeTop||!nativeTop.set) return;\n    try{ Object.defineProperty(cv,'scrollTop',{configurable:true,get:function(){ return nativeTop.get.call(this); },set:function(){} }); }catch(e){ return; }\n    cv.__vmGuard=true;\n    \/* the newest question rises to the top as the answer arrives, then stops;\n       it also stops the moment the reader scrolls *\/\n    var goal=null;\n    function rise(){ if(goal==null) return; var max=cv.scrollHeight-cv.clientHeight, cur=nativeTop.get.call(cv), to=Math.min(goal,max);\n      if(to>cur) nativeTop.set.call(cv,to); if(to>=goal) goal=null; }\n    function pin(el){ goal=Math.max(0,nativeTop.get.call(cv)+el.getBoundingClientRect().top-cv.getBoundingClientRect().top-10); rise(); }\n    ['wheel','touchstart','pointerdown','keydown'].forEach(function(t){ cv.addEventListener(t,function(){ goal=null; },{passive:true}); });\n    new MutationObserver(function(ms){\n      ms.forEach(function(m){ m.addedNodes.forEach(function(n){ if(n.nodeType===1&&n.parentNode===cv&&n.classList.contains('mwai-user')) pin(n); }); });\n      rise();\n    }).observe(cv,{childList:true,subtree:true,characterData:true});\n  }\n  function stageInView(){ var hh=headH(), r=stage.getBoundingClientRect(); if(r.top<hh||r.bottom>window.innerHeight+2) window.scrollTo({top:Math.max(0,(window.pageYOffset||0)+r.top-hh-8),behavior:'smooth'}); }\n  function openFather(){ clearTimeout(fdT); fd.hidden=false; fdOpen=true; root.classList.add('is-fd'); requestAnimationFrame(function(){ fd.classList.add('is-on'); }); stageInView(); }\n  function askFather(q,btn){\n    stopTour();\n    var bot=findBot();\n    if(!bot){ if(q) fallback(q); else fallback(''); return; }\n    if(btn){ btn.classList.add('is-busy'); setTimeout(function(){ btn.classList.remove('is-busy'); },1500); }\n    if(dockChat()){\n      openFather(); guardScroll();\n      setTimeout(function(){ try{ if(q) bot.ask(q,true); else { var t=fd.querySelector('textarea'); if(t) t.focus(); } }catch(e){ if(q) fallback(q); } }, 120);\n    } else {\n      \/* the chatbot is set to appear as a popup: use its own window *\/\n      var fs=document.fullscreenElement||document.webkitFullscreenElement;\n      if(fs){ try{ (document.exitFullscreen||document.webkitExitFullscreen).call(document); }catch(e){} }\n      try{ if(typeof bot.open==='function') bot.open(); }catch(e){}\n      setTimeout(function(){ try{ if(q) bot.ask(q,true); }catch(e){ if(q) fallback(q); } }, fs?450:250);\n    }\n  }\n  \/* close Father Dominic and return the whole map to its opening state *\/\n  \/* Reset, Escape, or 0: close Father Dominic and any open card, and return the map to its opening view *\/\n  function freshStart(){ if(fdOpen) closeFather(); else { stopTour(); release(); resetView(); } }\n  \/* Escape works wherever the keyboard focus happens to be *\/\n  document.addEventListener('keydown',function(e){ if(e.key!=='Escape'||e.defaultPrevented) return; if(!fdOpen&&!held&&!peek&&!touring) return; e.preventDefault(); freshStart(); });\n  function closeFather(){\n    fdOpen=false; fd.classList.remove('is-on'); root.classList.remove('is-fd'); fdT=setTimeout(function(){ if(!fdOpen) fd.hidden=true; }, 280);\n    try{ var b=findBot(); if(b&&typeof b.clear==='function') b.clear(); }catch(e){}\n    stopTour(); release(); legend.classList.add('is-closed'); var lh=$('.vm-legend-head'); if(lh) lh.setAttribute('aria-expanded','false');\n    resetView(); stageInView(); stage.focus({preventScroll:true});\n  }\n  $('.vm-fd-close').addEventListener('click',function(e){ e.stopPropagation(); closeFather(); });\n  \/* typing, scrolling, and clicking in the chat never move the map *\/\n  ['pointerdown','wheel','dblclick','contextmenu'].forEach(function(t){ fd.addEventListener(t,function(e){ e.stopPropagation(); }); });\n  fd.addEventListener('keydown',function(e){ e.stopPropagation(); if(e.key==='Escape'){ e.preventDefault(); closeFather(); } });\n  function fallback(q){\n    try{ var pr=navigator.clipboard&&navigator.clipboard.writeText(q); if(pr&&pr.catch) pr.catch(function(){}); }catch(e){}\n    var url=CONFIG.FD_PAGE ? CONFIG.FD_PAGE+(CONFIG.FD_PAGE.indexOf('?')<0?'?':'&')+'q='+encodeURIComponent(q) : '';\n    toast('Father Dominic isn\u2019t on this page yet. '+(url?'<a href=\"'+esc(url)+'\" target=\"_blank\" rel=\"noopener\">Ask him on his page<\/a> (the question is copied, ready to paste).':''), 7000);\n  }\n\n  var shown=null;\n  function showCard(p){\n    clearTimeout(hideT);\n    if(shown!==p.id){ shown=p.id; renderCard(p); card.classList.remove('is-on'); }\n    card.hidden=false; root.classList.add('is-sheet'); placeCard(); requestAnimationFrame(function(){ card.classList.add('is-on'); });\n  }\n  function hideCard(){ root.classList.remove('is-sheet'); card.classList.remove('is-on'); shown=null; hideT=setTimeout(function(){ if(!shown) card.hidden=true; }, 330); }\n  function placeCard(){\n    \/* the card is docked at the right edge, clear of the featured place *\/\n  }\n  function markActive(id){ Object.keys(pinEls).forEach(function(k){ pinEls[k].classList.toggle('is-active',k===id); if(lgEls[k]) lgEls[k].classList.toggle('is-active',k===id); }); }\n  function setHalo(p){ if(!p){ halo.classList.remove('is-on'); return; } var f=frac(p); halo.style.left=(f[0]*100)+'%'; halo.style.top=(f[1]*100)+'%'; halo.classList.add('is-on'); }\n\n  function preview(p){ if(held&&held!==p) { Object.keys(pinEls).forEach(function(k){ pinEls[k].classList.toggle('is-peek',k===p.id); }); return; }\n    peek=p; pinEls[p.id].classList.add('is-peek'); markActive(p.id); setHalo(p); if(!compact) showCard(p); fade(); }\n  function unpreview(){ Object.keys(pinEls).forEach(function(k){ pinEls[k].classList.remove('is-peek'); }); if(held) return;\n    peek=null; clearTimeout(hideT); hideT=setTimeout(function(){ if(!peek&&!held){ markActive(null); setHalo(null); hideCard(); } },260); }\n  function focusOn(p,dur){\n    held=p; peek=null; markActive(p.id); setHalo(p); spot.classList.add('is-on'); showCard(p); fade();\n    animateTo(viewFor(p,CLOSE[p.id]?{s:CLOSE[p.id]*(compact?1.3:1),tilt:0}:null), dur||1200);\n    if(compact) stageInView();\n    if(p.id==='apartments') blessStart(); else blessStop();\n  }\n  function release(){ blessStop(); held=null; peek=null; markActive(null); setHalo(null); spot.classList.remove('is-on'); hideCard(); }\n  card.addEventListener('mouseenter',function(){ clearTimeout(hideT); if(peek&&!held) peek=peek; });\n  card.addEventListener('mouseleave',function(){ if(!held) unpreview(); });\n  $('.vm-card-close').addEventListener('click',function(){ stopTour(); release(); });\n\n  \/* ---------------- tour ---------------- *\/\n  var tourIdx=0, tourT=null, tourPaused=false, tourStart=0, progEl=$('.vm-tb-prog b');\n  function tourGo(){\n    clearTimeout(tourT); var p=BYID[TOUR[tourIdx]];\n    $('.vm-tb-count').textContent='Stop '+(tourIdx+1)+' of '+TOUR.length; $('.vm-tb-name').textContent=p.name;\n    var drift = (tourIdx%2?1:-1)*8;\n    focusOn(p,1600); animateTo(viewFor(p,{s:p.id==='gardens'||p.id==='square'?1.9:(CLOSE[p.id]?CLOSE[p.id]*(compact?1.3:1):2.7), rot:CLOSE[p.id]?0:st.rot+drift, tilt:CLOSE[p.id]?0:undefined}),1700);\n    progEl.style.transition='none'; progEl.style.width='0'; void progEl.offsetWidth;\n    if(!tourPaused){ progEl.style.transition='width '+CONFIG.TOUR_SECONDS+'s linear'; progEl.style.width='100%'; tourT=setTimeout(function(){ tourIdx=(tourIdx+1)%TOUR.length; tourGo(); }, CONFIG.TOUR_SECONDS*1000); }\n  }\n  function startTour(){ root.classList.add('is-touring'); touring=true; tourPaused=false; tourIdx=0; tourBar.hidden=false; tourBtn.hidden=true; hint.classList.add('is-gone'); setPauseIcon(); tourGo(); }\n  function stopTour(){ if(!touring) return; root.classList.remove('is-touring'); touring=false; clearTimeout(tourT); tourBar.hidden=true; tourBtn.hidden=false; }\n  function setPauseIcon(){ $('.vm-tb-play').innerHTML=tourPaused?'<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M4 2.5v11l9-5.5z\" fill=\"currentColor\"\/><\/svg>':'<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\"><path d=\"M5 3h2v10H5zM9 3h2v10H9z\" fill=\"currentColor\"\/><\/svg>'; }\n  tourBtn.addEventListener('click',startTour);\n  tourBar.addEventListener('click',function(e){ var b=e.target.closest('button'); if(!b) return; var a=b.getAttribute('data-t');\n    if(a==='end'){ stopTour(); resetView(); }\n    if(a==='next'){ tourIdx=(tourIdx+1)%TOUR.length; tourGo(); }\n    if(a==='prev'){ tourIdx=(tourIdx-1+TOUR.length)%TOUR.length; tourGo(); }\n    if(a==='pause'){ tourPaused=!tourPaused; setPauseIcon(); if(tourPaused){ clearTimeout(tourT); var w=getComputedStyle(progEl).width; progEl.style.transition='none'; progEl.style.width=w; } else tourGo(); } });\n\n  \/* ---------------- controls ---------------- *\/\n  $('.vm-controls').addEventListener('click',function(e){ var b=e.target.closest('button'); if(!b) return; var c=b.getAttribute('data-c'); fade();\n    if(c==='in') zoomAt(1.6,SW\/2,SH\/2,450);\n    if(c==='out') zoomAt(1\/1.6,SW\/2,SH\/2,450);\n    if(c==='cw') rotateBy(30);\n    if(c==='ccw') rotateBy(-30);\n    if(c==='tilt') animateTo({tilt: st.tilt>4?0:48}, 900);\n    if(c==='compass'){ freshStart(); }\n    if(c==='full'){ var fs=document.fullscreenElement||document.webkitFullscreenElement; if(fs){ (document.exitFullscreen||document.webkitExitFullscreen).call(document); } else { (root.requestFullscreen||root.webkitRequestFullscreen||function(){}).call(root); } } });\n  document.addEventListener('fullscreenchange',function(){ setTimeout(layout,60); });\n\n  \/* ---------------- gestures ---------------- *\/\n  var ptrs={}, g=null, moved=0, interacted=false;\n  function fade(){ if(!interacted){ interacted=true; hint.classList.add('is-gone'); } }\n  function pts(){ return Object.keys(ptrs).map(function(k){ return ptrs[k]; }); }\n  function begin(ev){\n    var a=pts(), r=stage.getBoundingClientRect();\n    if(a.length===1){ g={mode:(ev&&(ev.shiftKey||ev.button===2||ev.altKey||ev.ctrlKey))?'orbit':'pan', x0:a[0].x, y0:a[0].y, s0:Object.assign({},st)}; }\n    else if(a.length>=2){ var dx=a[1].x-a[0].x, dy=a[1].y-a[0].y;\n      g={mode:'pinch', d0:Math.hypot(dx,dy), a0:Math.atan2(dy,dx), mx:(a[0].x+a[1].x)\/2-r.left-SW\/2, my:(a[0].y+a[1].y)\/2-r.top-SH\/2, s0:Object.assign({},st)}; }\n    stage.classList.toggle('is-grabbing',!!g&&g.mode!=='orbit'); stage.classList.toggle('is-orbit',!!g&&g.mode==='orbit');\n  }\n  \/* a press on the map belongs to the map: never start the browser\u2019s own drag or a text selection *\/\n  function mapTarget(e){ return !(e.target.closest&&e.target.closest('.vm-fd,.vm-card,input,textarea,select,a,[contenteditable]')); }\n  stage.addEventListener('mousedown',function(e){ if(mapTarget(e)){ e.preventDefault(); e.stopPropagation(); } });\n  root.addEventListener('dragstart',function(e){ if(mapTarget(e)) e.preventDefault(); },true);\n  stage.addEventListener('selectstart',function(e){ if(mapTarget(e)) e.preventDefault(); });\n  stage.addEventListener('pointerdown',function(e){\n    if(e.target.closest('.vm-ui')||e.target.closest('.vm-ui-pin')||e.target.closest('.vm-cal')) return;\n    if(e.pointerType==='mouse'&&e.button!==0&&e.button!==2) return;\n    try{ stage.setPointerCapture(e.pointerId); }catch(err){}\n    ptrs[e.pointerId]={x:e.clientX,y:e.clientY}; moved=0; stopAnim(); if(touring){ tourPaused=true; clearTimeout(tourT); setPauseIcon(); }\n    begin(e); fade(); stage.focus({preventScroll:true});\n  });\n  stage.addEventListener('pointermove',function(e){\n    if(!ptrs[e.pointerId]||!g) return; ptrs[e.pointerId]={x:e.clientX,y:e.clientY}; var a=pts(), r=stage.getBoundingClientRect();\n    if(g.mode==='pan'&&a.length===1){ var dx=a[0].x-g.x0, dy=a[0].y-g.y0; moved=Math.max(moved,Math.hypot(dx,dy)); st.tx=g.s0.tx+dx; st.ty=g.s0.ty+dy; }\n    else if(g.mode==='orbit'&&a.length===1){ var ox=a[0].x-g.x0, oy=a[0].y-g.y0; moved=Math.max(moved,Math.hypot(ox,oy));\n      var d=ox*0.3, rr=d*D, c=Math.cos(rr), s=Math.sin(rr); st.rot=g.s0.rot+d; st.tx=g.s0.tx*c-g.s0.ty*s; st.ty=g.s0.tx*s+g.s0.ty*c; st.tilt=g.s0.tilt-oy*0.25; }\n    else if(g.mode==='pinch'&&a.length>=2){ var ddx=a[1].x-a[0].x, ddy=a[1].y-a[0].y, k=Math.hypot(ddx,ddy)\/g.d0, ang=(Math.atan2(ddy,ddx)-g.a0)\/D;\n      var mx=(a[0].x+a[1].x)\/2-r.left-SW\/2, my=(a[0].y+a[1].y)\/2-r.top-SH\/2; moved=99;\n      var ns=Math.max(MIN_S,Math.min(MAX_S,g.s0.s*k)); k=ns\/g.s0.s; st.s=ns; st.rot=g.s0.rot+ang;\n      var rr2=ang*D, c2=Math.cos(rr2), s2=Math.sin(rr2), bx=g.s0.tx-g.mx, by=g.s0.ty-g.my;\n      st.tx=mx+(bx*c2-by*s2)*k; st.ty=my+(bx*s2+by*c2)*k; }\n    clampView(st); apply();\n  });\n  function end(e){ if(!ptrs[e.pointerId]) return; delete ptrs[e.pointerId]; if(pts().length){ begin(); } else { g=null; stage.classList.remove('is-grabbing','is-orbit');\n      if(moved<4 && e.target===stage || moved<4 && e.target.closest && e.target.closest('.vm-plane,.vm-desk,.vm-spot')){ if(held&&!CAL){ stopTour(); release(); } } } }\n  stage.addEventListener('pointerup',end); stage.addEventListener('pointercancel',end);\n  stage.addEventListener('contextmenu',function(e){ if(!e.target.closest('.vm-ui')) e.preventDefault(); });\n  stage.addEventListener('wheel',function(e){ if(!CONFIG.WHEEL_ZOOM||e.target.closest('.vm-card,.vm-legend')) return; e.preventDefault(); fade(); stopAnim();\n    var r=stage.getBoundingClientRect(), k=Math.exp(-e.deltaY*(e.ctrlKey?0.01:0.0016)); var ns=Math.max(MIN_S,Math.min(MAX_S,st.s*k)); k=ns\/st.s;\n    var mx=e.clientX-r.left-SW\/2, my=e.clientY-r.top-SH\/2; st.s=ns; st.tx=mx-(mx-st.tx)*k; st.ty=my-(my-st.ty)*k; clampView(st); apply(); },{passive:false});\n  stage.addEventListener('dblclick',function(e){ if(e.target.closest('.vm-ui')||e.target.closest('.vm-ui-pin')) return; var r=stage.getBoundingClientRect(); zoomAt(1.8,e.clientX-r.left,e.clientY-r.top,500); });\n  stage.addEventListener('keydown',function(e){\n    if(e.target.closest('.vm-card')&&e.key!=='Escape') return;\n    var k=e.key, h=true;\n    if(k==='ArrowLeft') animateTo({tx:st.tx+80},250); else if(k==='ArrowRight') animateTo({tx:st.tx-80},250);\n    else if(k==='ArrowUp') animateTo({ty:st.ty+80},250); else if(k==='ArrowDown') animateTo({ty:st.ty-80},250);\n    else if(k==='+'||k==='=') zoomAt(1.5,SW\/2,SH\/2,350); else if(k==='-'||k==='_') zoomAt(1\/1.5,SW\/2,SH\/2,350);\n    else if(k==='q'||k==='Q') rotateBy(-15); else if(k==='e'||k==='E') rotateBy(15);\n    else if(k==='w'||k==='W') animateTo({tilt:st.tilt+8},300); else if(k==='s'||k==='S') animateTo({tilt:st.tilt-8},300);\n    else if(k==='t'||k==='T') animateTo({tilt:st.tilt>4?0:48},900);\n    else if(k==='0') { freshStart(); }\n    else if(k==='f'||k==='F') $('[data-c=\"full\"]').click();\n    else if(k==='Escape'){ freshStart(); } else h=false;\n    if(h){ e.preventDefault(); fade(); } });\n\n  \/* ---------------- compact layout ---------------- *\/\n  function setCompact(){\n    var c=root.clientWidth<820, changed=false; MAX_S=8; if(c!==compact){ compact=c; changed=true; root.classList.toggle('is-compact',c);\n      legend.classList.add('is-closed'); }\n    layout();\n    \/* switching between phone and desktop layouts (e.g. turning a tablet): start from the opening view *\/\n    if(changed && plane.classList.contains('is-ready')){ stopTour(); release(); stopAnim(); Object.assign(st,homeView()); apply(); }\n  }\n  var rzT=null; window.addEventListener('resize',function(){ clearTimeout(rzT); rzT=setTimeout(setCompact,80); });\n\n  \/* =================================================================\n     LIVING MAP: pilgrims, Swiss Guards, boats on the Tiber, traffic,\n     swallows, and two rare moments (Shepherd Two landing at the\n     heliport, white smoke from the Sistine Chapel chimney).\n     Everything is drawn on one transparent layer, sized to the\n     painting, and pauses whenever the map is out of view.\n     Paths are in percent across and down the painting, like POSITIONS.\n     ================================================================= *\/\n  var LIFE_GEO = {\n    \/* boats on the Tiber: one lane downstream, one upstream, in at one edge of the\n       painting and out at the other, passing under the three bridges (the bridges are\n       listed as occluders below, so the boats go behind them). *\/\n    boatRoutes:[ {n:4,types:['tour','skiff','barge'],p:[[101.06,40.72],[98.06,42.72],[95.08,44.71],[92.67,46.16],[90.23,47.03],[87.65,48.35],[85.05,50.32],[82.71,52.86],[81.23,55.68],[80.17,57.62],[78.99,59.21],[78.12,60.86],[77.66,63.25],[77.43,65.64],[76.89,68.55],[76.27,71.73],[76.1,75.04],[76.01,78.01],[76.39,81.01],[77.04,84.53],[77.47,88.71],[78.38,92.0],[79.2,95.04],[80.22,98.13],[81.19,101.02],[82.06,104.42]]},\n                 {n:3,types:['tour','skiff','barge'],p:[[84.34,102.58],[83.41,98.98],[82.38,95.87],[81.4,92.96],[80.62,90.0],[79.73,87.29],[79.16,83.47],[78.41,79.99],[78.19,77.39],[77.7,74.96],[77.73,72.27],[78.31,69.45],[78.97,66.36],[79.14,63.75],[79.28,61.94],[79.81,60.99],[81.03,59.58],[82.37,57.92],[83.89,55.74],[85.95,53.68],[88.35,52.25],[90.77,51.37],[93.33,50.44],[95.92,48.89],[98.94,46.88],[101.94,44.88]]} ],\n    \/* traffic: each route is one lane, traced on the painting's asphalt.\n       The Lungotevere runs from the bottom edge up the west bank of the Tiber,\n       past Castel Sant'Angelo and off the top; one lane each way.\n       Via della Conciliazione is a closed circuit (loop:1): down one side from the\n       colonnade to the river, round, and back. bus:0 keeps buses off a route. *\/\n    \/* the river itself, for the moving water: centre line with the half-width of the channel at each point *\/\n    river:[[101.5,42.8,85],[98.5,44.8,85],[95.5,46.8,85],[93,48.3,85],[90.5,49.2,85],[88,50.3,78],[85.5,52,71],[83.3,54.3,68],[81.8,56.8,58],[80.6,58.6,48],[79.4,60.1,44],[78.7,61.4,44],[78.4,63.5,51],[78.2,66,54],[77.6,69,51],[77,72,51],[76.9,75,54],[77.1,77.7,75],[77.4,80.5,71],[78.1,84,75],[78.6,88,82],[79.5,91,85],[80.3,94,85],[81.3,97,85],[82.3,100,85],[83.2,103.5,85]],\n    roads:[ {n:7,bus:1,p:[[77.32,102.87],[76.8,98.78],[75.39,94.74],[74.2,89.77],[73.01,84.84],[72.62,79.92],[72.22,74.97],[72.42,72.12],[72.81,70.17],[73.11,68.18],[73.72,65.1],[73.7,62.23],[74.81,60.44],[76.18,58.48],[78.19,56.47],[79.45,54.36],[80.06,52.33],[81.09,50.25],[81.22,48.13],[81.52,46.43],[82.93,45.43],[85.09,43.76],[87.43,43.17],[89.73,42.97],[92.68,42.16],[94.59,40.67],[95.78,38.19],[96.41,35.16],[96.82,31.76],[96.92,26.99],[96.72,21.95],[96.42,17.49],[95.81,13.64],[94.82,7.46],[94.22,1.91],[93.92,-3.06]]},\n            {n:7,bus:1,p:[[93.28,-2.94],[93.58,2.09],[94.18,7.74],[95.19,13.96],[95.78,17.71],[96.08,22.05],[96.28,27.01],[96.18,31.64],[95.79,34.84],[95.22,37.61],[94.21,39.73],[92.52,41.04],[89.67,41.83],[87.37,42.03],[84.91,42.64],[82.67,44.37],[81.08,45.57],[80.58,47.87],[80.51,49.75],[79.54,51.67],[78.95,53.64],[77.81,55.53],[75.82,57.52],[74.39,59.56],[73.1,61.77],[73.08,64.9],[72.49,67.82],[72.19,69.83],[71.78,71.88],[71.58,75.03],[71.98,80.08],[72.39,85.16],[73.6,90.23],[74.81,95.26],[76.2,99.22],[76.68,103.13]]},\n            {n:6,bus:1,loop:1,p:[[58.8,49.3],[62,49.25],[66,49.2],[70,49.15],[74,49.1],[77.2,49.0],[78.1,48.95],[78.8,48.75],[78.8,48.35],[78.1,48.15],[77.2,48.15],[74,48.15],[70,48.2],[66,48.25],[62,48.3],[59.2,48.35],[58.5,48.6],[58.5,49.1],[58.8,49.3]]} ],\n    \/* things that stand in front of moving figures in this bird's-eye view *\/\n    occluders:[ \/* the obelisk and its pedestal: people crossing behind the shaft pass behind it *\/\n                [[51.75,48.3],[52.05,48.3],[52.1,50],[52.15,52],[52.2,53],[52.5,53.1],[52.5,53.6],[51.3,53.6],[51.3,53.1],[51.6,53],[51.65,52],[51.7,50]],\n                \/* the three bridges: boats pass beneath them *\/\n                [[89.3,45.0],[90.9,45.0],[92.1,53.2],[90.3,53.2]],\n                [[78.6,54.2],[83.0,60.0],[81.8,62.8],[77.4,57.0]],\n                [[73.5,76.4],[80.3,76.4],[80.3,78.6],[77.9,78.6],[77.9,80.6],[76.4,80.6],[76.4,78.6],[73.5,78.6]] ],\n    statues:[],\n    walks:[ {n:5,once:1,p:[[58.2,47.3],[78.4,47.2]]},\n            {n:5,once:1,p:[[58.2,50.2],[78.4,50]]},\n            {n:9,once:1,fwd:1,p:[[59.5,51.6],[57,52],[54.4,51.2],[51,51.6],[48.2,51.9],[46.6,52]]},\n            {n:4,p:[[90.6,45.4],[91,48.6],[91.4,52.2]]},\n            {n:4,once:1,p:[[88.6,43.4],[85.6,44.2],[82.6,46],[81.4,48.6],[80.6,51.2],[79.4,53.6],[78.4,55.2]]},\n            {n:2,p:[[12,42],[15,40],[18,38],[22,36]]},\n            {n:3,p:[[16,50],[20,52],[24,54],[27,56]]},\n            {n:3,p:[[20,30],[24,31],[28,32],[32,33]]} ],\n    loops:[ {n:3,e:[19.5,38.5,2.6,1.6]}, {n:2,e:[14.5,47.5,1.4,1.0]} ],\n    \/* sentries: either side of the Arch of the Bells at the left of the facade, of the Bronze Door, and of St. Anne's Gate *\/\n    guards:[[46.4,57.1],[46.4,58.3],[46.8,45.6],[47.8,45.1],[52.1,30.9],[52.9,31.0]],\n    \/* Swiss Guard parade: out of the Arch of the Bells, up to the obelisk, a halt and salute, then away under the colonnade toward the Bronze Door (the route ends at the colonnade and the guards fade as they pass beneath it) *\/\n    parade:[[46.2,57.6],[47.6,57.1],[49.2,55.6],[50.4,53.8],[50.9,52.2],[50.6,50.4],[49.9,48.8],[49.2,47.4],[48.4,46.3]],\n    chimney:[38.3,41.2], heliport:[6,53], dome:[33.2,48.8], square:[51.9,52.2]\n  };\n  var LV={cv:null,g:null,vis:true,raf:0,last:0,T:0,ppl:[],veh:[],boats:[],birds:[],guards:[],flow:[],heli:null,smoke:null,nextHeli:0,nextSmoke:0};\n  var PW=4000, PH=2251; \/* internal drawing space; the painting is scaled to it *\/\n  var CLOTH=['#efe6d2','#3b4a5e','#8c2f24','#d9b25b','#58693f','#f6f3ec','#2b2b2b','#6d4c7d','#c46a3c','#9aa7b4','#e7c9a9'];\n  var SKIN=['#e6bd9a','#c9936b','#8d5b3b','#f0cfb4'];\n  var CARS=['#f1efe9','#2c2f33','#8a1e1b','#3c5a7a','#c9c4b8','#5c6b4a','#b9b2a4','#e2d6b5'];\n  function pick(a){ return a[Math.floor(Math.random()*a.length)]; }\n  function rnd(a,b){ return a+Math.random()*(b-a); }\n  function PT(a){ return [a[0]\/100*PW, a[1]\/100*PH]; }\n  function poly(pts){ var p=pts.map(PT), L=[0]; for(var i=1;i<p.length;i++) L.push(L[i-1]+Math.hypot(p[i][0]-p[i-1][0],p[i][1]-p[i-1][1])); return {p:p,L:L,len:L[L.length-1]}; } \/* smooth a path through its points (Catmull-Rom), sampled every few painting units, so anything following it turns in a curve instead of snapping at corners *\/ function spath(pts){ var p=pts.map(PT), n=p.length, out=[], i, t; for(i=0;i<n-1;i++){ var p0=p[Math.max(0,i-1)], p1=p[i], p2=p[i+1], p3=p[Math.min(n-1,i+2)], m=Math.max(2,Math.ceil(Math.hypot(p2[0]-p1[0],p2[1]-p1[1])\/6)); for(t=0;t<m;t++){ var u=t\/m, u2=u*u, u3=u2*u, pt=[0,0]; for(var k=0;k<2;k++) pt[k]=0.5*(2*p1[k]+(p2[k]-p0[k])*u+(2*p0[k]-5*p1[k]+4*p2[k]-p3[k])*u2+(3*p1[k]-p0[k]-3*p2[k]+p3[k])*u3); out.push(pt); } } out.push(p[n-1]); var L=[0]; for(i=1;i<out.length;i++) L.push(L[i-1]+Math.hypot(out[i][0]-out[i-1][0],out[i][1]-out[i-1][1])); return {p:out,L:L,len:L[L.length-1]}; } \/* where a vehicle or boat of length len sits: centred between its front and back on the path, facing along it *\/ function pose(path,d,dir,len,off){ var f=at(path,d+dir*len*0.5), r=at(path,d-dir*len*0.5), hx=f.x-r.x, hy=f.y-r.y, l=Math.hypot(hx,hy); if(l<1e-6){ var s0=at(path,d); hx=s0.dx*dir; hy=s0.dy*dir; l=1; } hx\/=l; hy\/=l; return {x:(f.x+r.x)\/2-hy*off, y:(f.y+r.y)\/2+hx*off, hx:hx, hy:hy}; } function at(path,d){ d=Math.max(0,Math.min(path.len,d)); var L=path.L, lo=1, hi=L.length-1; while(lo<hi){ var mid=(lo+hi)>>1; if(L[mid]<d) lo=mid+1; else hi=mid; } var i=lo;\n    var a=path.p[i-1], b=path.p[i], seg=(L[i]-L[i-1])||1, k=(d-L[i-1])\/seg; return {x:a[0]+(b[0]-a[0])*k, y:a[1]+(b[1]-a[1])*k, dx:(b[0]-a[0])\/seg, dy:(b[1]-a[1])\/seg}; }\n  function scr(x,y){ return project(x\/PW,y\/PH); }\n  function unit(q){ return W*st.s*q.k\/PW; }\n  function offscreen(q,m){ m=m||40; return q.k<=0||q.x<-m||q.x>SW+m||q.y<-m||q.y>SH+m; }\n  function endFade(path,d){ return Math.max(0,Math.min(1,Math.min(d,path.len-d)\/60)); }\n  function inSquare(x,y){\n    var ex=(x-51.9)\/4.3, ey=(y-52.2)\/9.8, inE=ex*ex+ey*ey<1, inB=x>45.9&&x<48.2&&y>47.2&&y<57.4, inR=x>56.2&&x<58.5&&y>47.8&&y<55;\n    if(!(inE||inB||inR)) return false;\n    function nb(cx,cy,r){ var dx=x-cx, dy=(y-cy)*1.78; return dx*dx+dy*dy<r*r; }\n    return !nb(52,45.4,0.6)&&!nb(52,59,0.6)&&!nb(51.9,53.1,0.7);\n  }\n  function squarePoint(){ for(var i=0;i<60;i++){ var x=rnd(45.9,58.5), y=rnd(41.5,63); if(inSquare(x,y)) return PT([x,y]); } return PT([51.9,56]); }\n  function courtPoint(){ return PT([rnd(41.8,46.2),rnd(12.5,21)]); }\n\n  function lifeBuild(){\n    var F=(compact?0.5:1)*((navigator.hardwareConcurrency||8)<=4?0.7:1), N=function(n){ return Math.max(1,Math.round(n*F)); }, i, j;\n    function person(o){ o.col=pick(CLOTH); o.skin=pick(SKIN); o.v=o.v||rnd(7,12); o.ph=Math.random()*6; LV.ppl.push(o); return o; }\n    for(i=0;i<N(64);i++){ var s=squarePoint(); person({m:'area',a:squarePoint,x:s[0],y:s[1],t:squarePoint(),wait:rnd(0,4)}); }\n    for(i=0;i<N(2);i++){ var c=squarePoint(), lead=person({m:'area',a:squarePoint,x:c[0],y:c[1],t:squarePoint(),wait:0,v:6});\n      lead.col='#c8102e'; for(j=0;j<N(7);j++) person({m:'follow',lead:lead,ox:rnd(-22,22),oy:rnd(-12,12),x:c[0],y:c[1],v:8}); }\n    for(i=0;i<N(9);i++){ var b=courtPoint(); person({m:'area',a:courtPoint,x:b[0],y:b[1],t:courtPoint(),wait:rnd(0,6),v:rnd(5,8)}); }\n    LIFE_GEO.walks.forEach(function(w){ var path=spath(w.p); for(i=0;i<N(w.n);i++) person({m:w.once?'once':'bounce',path:path,d:Math.random()*path.len,dir:w.fwd?1:(Math.random()<.5?1:-1),fwd:w.fwd,off:rnd(-12,12)}); });\n    LIFE_GEO.loops.forEach(function(l){ var e=l.e, pts=[]; for(var k=0;k<=28;k++){ var t=k\/28*Math.PI*2; pts.push([e[0]+e[2]*Math.cos(t),e[1]+e[3]*Math.sin(t)]); }\n      var path=poly(pts); for(i=0;i<N(l.n);i++) person({m:'loop',path:path,d:Math.random()*path.len,dir:Math.random()<.5?1:-1,off:rnd(-6,6),v:rnd(5,8)}); });\n    LIFE_GEO.guards.forEach(function(g,k){ var p=PT(g); LV.guards.push({x:p[0],y:p[1],ph:k*1.7}); });\n    LIFE_GEO.roads.forEach(function(r,ri){ var path=spath(r.p), nv=N(r.n); for(i=0;i<nv;i++){ var vv=newVeh(path,ri,(i+0.2+Math.random()*0.5)\/nv*path.len,r.bus); vv.cur=vv.v*0.7; vv.loop=!!r.loop; LV.veh.push(vv); } });\n    LIFE_GEO.boatRoutes.forEach(function(rt){ var path=spath(rt.p), nb=N(rt.n); for(i=0;i<nb;i++){ var bt=keepRight(newBoat(path,true,rt.types)); bt.d=(i+Math.random()*0.5)\/nb*path.len; bt.loop=!!rt.loop; LV.boats.push(bt); } });\n    if(LIFE_GEO.river){ var rp=spath(LIFE_GEO.river.map(function(p){ return [p[0],p[1]]; })); LV.flowPath=rp; LV.flowW=LIFE_GEO.river.map(function(p){ return p[2]; });\n      for(i=0;i<N(140);i++) LV.flow.push({d:Math.random()*rp.len,off:rnd(-0.9,0.9),len:rnd(16,44),v:rnd(8,15),ph:Math.random()*6.3,dark:Math.random()<.35}); }\n    var dome=PT(LIFE_GEO.dome), sq=PT(LIFE_GEO.square);\n    for(i=0;i<N(9);i++) LV.birds.push({c:dome,r:rnd(90,180),ang:Math.random()*6.3,w:rnd(.35,.6)*(i%2?1:-1),alt:rnd(140,240),ph:Math.random()*6});\n    for(i=0;i<N(6);i++) LV.birds.push({c:sq,r:rnd(160,300),ang:Math.random()*6.3,w:rnd(.25,.45)*(i%2?-1:1),alt:rnd(110,200),ph:Math.random()*6});\n    var preview=\/[?&]vmap-life=preview\/.test(location.search);\n    \/* the Swiss Guard parade marches once, about 8 s after the map comes into view;\n       the helicopter follows it and then lands roughly once a minute; white smoke now and then.\n       ?vmap-life=preview starts the parade straight away. *\/\n    LV.nextHeli=preview?60:rnd(8,12); LV.nextParade=preview?4:8; LV.nextSmoke=preview?110:rnd(110,140); LV.preview=preview; LV.lastUser=-1e9;\n  }\n  \/* ease off for bends: compare the heading here with the heading a little ahead *\/\n  function bend(path,d){ var a=at(path,d), b=at(path,Math.min(path.len,d+45)); return Math.max(0.32,Math.min(1,0.32+0.68*Math.max(0,a.dx*b.dx+a.dy*b.dy))); }\n  function newVeh(path,road,d,bus){\n    var r=Math.random(), t=r<.12?'bus':r<.32?'vespa':'car', dir=1; if(t==='bus'&&!bus) t='car';\n    return {path:path,road:road,t:t,dir:dir,d:d!=null?d:(dir>0?0:path.len),v:t==='bus'?rnd(24,30):t==='vespa'?rnd(42,52):rnd(32,44),cur:0,\n      L:t==='bus'?52:t==='vespa'?9:19,Wd:t==='bus'?11:t==='vespa'?3.5:8.5,col:t==='bus'?(Math.random()<.5?'#b5382c':'#e9e4d8'):t==='vespa'?pick(['#7fb3c8','#e8d27a','#c43c2c','#f2efe8']):pick(CARS),wait:0,bus:bus};\n  }\n  function newBoat(path,anywhere,types){\n    types=types||['tour','skiff','barge']; var r=Math.random(), t=r<.45?'tour':r<.8?'skiff':'barge', dir=1; if(types.indexOf(t)<0) t=types[0];\n    var tour=[['#f4f2ec','#2d4a63'],['#efe7d4','#1f5a4a'],['#f6f5f1','#8a2a20']][Math.floor(Math.random()*3)];\n    return {path:path,t:t,dir:dir,d:anywhere?Math.random()*path.len:(dir>0?0:path.len),off:0,cur:0,v:t==='skiff'?rnd(22,30):t==='tour'?rnd(16,22):rnd(10,14),\n      L:t==='tour'?120:t==='skiff'?(Math.random()<.6?34:46):150,Wd:t==='tour'?27:t==='skiff'?5:30,wait:anywhere?0:rnd(2,14),ph:Math.random()*6,\n      c1:tour[0],c2:tour[1],rowers:t==='skiff'?(Math.random()<.6?1:2):0,shirt:pick(['#f6f3ec','#8c2f24','#2c4a8a','#e8d27a']),trail:[],tt:0,\n      pax:[pick(CLOTH),pick(CLOTH),pick(CLOTH),pick(CLOTH),pick(CLOTH)],types:types};\n  }\n  function keepRight(b){ b.off=0; b.cur=b.v; return b; }\n  \/* the current: short streaks of light and shadow sliding downstream, brighter mid-channel *\/\n  function flowW(d){ var w=LV.flowW, n=w.length, f=d\/LV.flowPath.len*(n-1), i=Math.max(0,Math.min(n-2,Math.floor(f))), t=f-i; return w[i]*(1-t)+w[i+1]*t; }\n  function drawFlow(){ var P=LV.flowPath; if(!P) return; var g=LV.g; g.lineCap='round';\n    LV.flow.forEach(function(f){ var s=at(P,f.d), w=flowW(f.d), x=s.x-s.dy*f.off*w, y=s.y+s.dx*f.off*w, q=scr(x,y); if(offscreen(q,60)) return; var u=unit(q); if(u<0.22) return;\n      var e=scr(x-s.dx*f.len,y-s.dy*f.len), a=(0.5+0.5*Math.sin(LV.T*1.6+f.ph))*(1-Math.abs(f.off)*0.45);\n      g.strokeStyle=f.dark?'rgba(16,48,70,'+(a*0.3).toFixed(3)+')':'rgba(255,255,255,'+(a*0.42).toFixed(3)+')'; g.lineWidth=Math.max(0.6,(f.dark?1.7:1.15)*u); g.beginPath(); g.moveTo(q.x,q.y); g.lineTo(e.x,e.y); g.stroke(); }); }\n  function boatPos(b){ return pose(b.path,b.d,b.dir,b.L*0.8,b.off); }\n\n  \/* things in the square nobody walks through: the obelisk\u2019s pedestal and the two fountains (painting units) *\/\n  var OBST=[{x:51.9*40,y:53.2*22.51,rx:0.7*40,ry:0.55*22.51},{x:52*40,y:45.4*22.51,rx:0.6*40,ry:0.45*22.51},{x:52*40,y:59*22.51,rx:0.6*40,ry:0.45*22.51}];\n  function obstPush(p,ux,uy){ var vx=0, vy=0, any=false;\n    OBST.forEach(function(o){ var dx=(p.x-o.x)\/o.rx, dy=(p.y-o.y)\/o.ry, d=Math.hypot(dx,dy); if(d>1.6) return; any=true; var nx=dx\/(d||1), ny=dy\/(d||1);\n      \/* only steer when heading toward it: walk round the side nearer the destination *\/\n      if(nx*ux+ny*uy>0.2) return; var side=(nx*uy-ny*ux)>0?1:-1, w=(1.6-d)\/1.6; vx+=(-ny*side)*w*1.4+nx*Math.max(0,1.15-d)*2.5; vy+=(nx*side)*w*1.4+ny*Math.max(0,1.15-d)*2.5; });\n    return any?[vx,vy]:null; }\n  function obstClamp(p){ OBST.forEach(function(o){ var dx=(p.x-o.x)\/o.rx, dy=(p.y-o.y)\/o.ry, d=Math.hypot(dx,dy); if(d<1&&d>0){ p.x=o.x+dx\/d*o.rx; p.y=o.y+dy\/d*o.ry; } }); }\n  function lifeStep(dt){\n    LV.T+=dt;\n    LV.ppl.forEach(function(p){\n      p.ph+=dt*p.v*0.9;\n      if(LV.parade&&(p.m==='area'||p.m==='follow')){ var pc=paradeAvoid(p.x,p.y); if(pc){ p.x+=pc[0]*dt; p.y+=pc[1]*dt; if(p.t&&paradeNear(p.t[0],p.t[1],40)) p.t=p.a(); } }\n      if(LV.parade&&p.path&&p.m!=='loop'){ var ps=at(p.path,p.d); if(paradeNear(ps.x,ps.y,34)) return; }\n      if(p.m==='area'){ if(p.wait>0){ p.wait-=dt; return; } var dx=p.t[0]-p.x, dy=p.t[1]-p.y, dd=Math.hypot(dx,dy);\n        if(dd<2){ p.t=p.a(); p.wait=Math.random()<.5?rnd(1,5):0; return; } var ux=dx\/dd, uy=dy\/dd, pu=obstPush(p,ux,uy); if(pu){ ux+=pu[0]; uy+=pu[1]; var ul=Math.hypot(ux,uy)||1; ux\/=ul; uy\/=ul; }\n        var s=Math.min(dd,p.v*dt); p.x+=ux*s; p.y+=uy*s; obstClamp(p); p.hx=ux; return; }\n      if(p.m==='follow'){ var tx=p.lead.x+p.ox, ty=p.lead.y+p.oy, ex=tx-p.x, ey=ty-p.y, de=Math.hypot(ex,ey); if(de>3){ var st2=Math.min(de,(p.v+de*0.1)*dt); p.x+=ex\/de*st2; p.y+=ey\/de*st2; obstClamp(p); } return; }\n      p.d+=p.dir*p.v*dt;\n      if(p.m==='loop'){ p.d=(p.d+p.path.len)%p.path.len; return; }\n      if(p.d<0||p.d>p.path.len){ if(p.m==='bounce'){ p.dir*=-1; p.d=Math.max(0,Math.min(p.path.len,p.d)); } else { p.dir=p.fwd?1:(Math.random()<.5?1:-1); p.d=p.dir>0?0:p.path.len; p.off=rnd(-12,12); p.col=pick(CLOTH); } }\n    });\n    LV.veh.forEach(function(v){\n      if(v.wait>0){ v.wait-=dt; if(v.wait<=0){ var nv=newVeh(v.path,v.road,null,v.bus);\n        var busy=LV.veh.some(function(o){ return o!==v&&o.wait<=0&&o.road===nv.road&&o.dir===nv.dir&&Math.abs(o.d-nv.d)<o.L\/2+nv.L\/2+60; });\n        if(busy) v.wait=0.8; else { for(var k in nv) v[k]=nv[k]; v.cur=v.v*0.8; } } return; }\n      var lim=v.v*bend(v.path,v.d+v.L*0.3);\n      LV.veh.forEach(function(o){ if(o===v||o.road!==v.road||o.dir!==v.dir||o.wait>0) return; var gap=(o.d-v.d)*v.dir, need=(v.L+o.L)\/2+16;\n        if(gap>0&&gap<need+70) lim=Math.min(lim, Math.max(0,o.cur*(gap-need)\/70+(gap-need)*0.3)); });\n      v.cur+=(lim-v.cur)*Math.min(1,dt*(lim<v.cur?2.2:0.9)); v.d+=v.dir*v.cur*dt;\n      if(v.loop){ if(v.d>v.path.len) v.d-=v.path.len; } else if(v.d<-5||v.d>v.path.len+5){ v.wait=rnd(.5,4); }\n    });\n    LV.boats.forEach(function(b){ if(b.wait>0){ b.wait-=dt; if(b.wait<=0&&LV.boats.some(function(o){ return o!==b&&o.wait<=0&&o.path===b.path&&o.d<(o.L+b.L)\/2+80; })) b.wait=1.5; return; }\n      var lim=b.v; LV.boats.forEach(function(o){ if(o===b||o.wait>0||o.dir!==b.dir||Math.abs(o.off-b.off)>(o.Wd+b.Wd)\/2+14) return;\n        var gap=(o.d-b.d)*b.dir, need=(o.L+b.L)\/2+30; if(gap>0&&gap<need+120) lim=Math.min(lim,Math.max(0,o.cur*(gap-need)\/120+(gap-need)*0.15)); });\n      b.cur+=(lim-b.cur)*Math.min(1,dt*0.8); b.d+=b.dir*b.cur*dt; b.ph+=dt*(b.t==='skiff'?2.4:3);\n      b.tt+=dt; if(b.tt>0.3){ b.tt=0; var bp=boatPos(b); b.trail.unshift([bp.x,bp.y,bp.hx,bp.hy]); if(b.trail.length>18) b.trail.pop(); }\n      if(b.d<0||b.d>b.path.len){ if(b.loop){ b.d=((b.d%b.path.len)+b.path.len)%b.path.len; } else { var nb2=keepRight(newBoat(b.path,false,b.types)); for(var k in nb2) b[k]=nb2[k]; } } });\n    LV.birds.forEach(function(b){ b.ang+=b.w*dt; b.ph+=dt*(9+Math.sin(b.ang*3)*3); });\n    if(LV.flowPath) LV.flow.forEach(function(f){ f.d+=f.v*dt; if(f.d>LV.flowPath.len){ f.d-=LV.flowPath.len; f.off=rnd(-0.9,0.9); f.len=rnd(16,44); } });\n    var busy=LV.heli||LV.smoke||LV.parade;\n    if(!busy&&LV.T>LV.nextParade){ paradeStart(); LV.nextParade=Infinity; busy=true; }\n    if(!busy&&LV.T>LV.nextHeli){ heliStart(); LV.nextHeli=LV.T+32+rnd(40,60); busy=true; }\n    if(!busy&&LV.T>LV.nextSmoke){ LV.smoke={t:0,puffs:[],acc:0}; LV.nextSmoke=LV.T+rnd(200,300); }\n    if(LV.heli){ LV.heli.t+=dt; LV.heli.rot+=dt*(LV.heli.t>13&&LV.heli.t<19?16:42); if(LV.heli.t>32) LV.heli=null; }\n    if(LV.parade) paradeStep(dt);\n    blessStep(dt);\n    if(LV.smoke){ var S=LV.smoke; S.t+=dt; S.acc+=dt; while(S.t<26&&S.acc>0.22){ S.acc-=0.22; S.puffs.push({age:0,life:rnd(6.5,8.5),dx:rnd(-.25,.25)}); }\n      S.puffs.forEach(function(p){ p.age+=dt; }); S.puffs=S.puffs.filter(function(p){ return p.age<p.life; }); if(S.t>26&&!S.puffs.length) LV.smoke=null; }\n  }\n  \/* ---------------- Swiss Guard parade ---------------- *\/\n  var PSC=1.5, FORMATION=[{a:0,l:-6.5,flag:1},{a:0,l:6.5,flag:2}];\n  (function(){ for(var r=0;r<4;r++) for(var c=-1;c<=1;c++) FORMATION.push({a:-14-r*10.5,l:c*9}); })();\n  function paradeStart(){\n    var path=spath(LIFE_GEO.parade), south=0, best=-1;\n    for(var d=0; d<path.len; d+=4){ var s0=at(path,d); if(s0.x>best){ best=s0.x; south=d; } }\n    LV.parade={path:path, d:0, v:16, ph:0, haltAt:south+16, halted:0, done:false};\n    if(camOK()){ LV.cam={saved:{tx:st.tx,ty:st.ty,s:st.s,rot:st.rot,tilt:st.tilt}, s:compact?8:Math.min(6,Math.max(4.6,6600\/W)), tilt:30, phase:'in'};\n      stopAnim(); animateTo(camView(paradeCentre()),2800,function(){ if(LV.cam) LV.cam.phase='follow'; });\n      try{ toast('<b>The Pontifical Swiss Guard<\/b> on parade in St. Peter\u2019s Square',4500); }catch(e){} }\n  }\n  function paradeStep(dt){\n    var P=LV.parade;\n    if(P.halted>0){ P.halted-=dt; return; }\n    if(!P.done&&P.d>=P.haltAt){ P.done=true; P.halted=3.5; return; }\n    P.d+=P.v*dt; P.ph+=dt*P.v*0.9;\n    if(P.d>P.path.len+45){ LV.parade=null; LV.nextHeli=Math.max(LV.nextHeli,LV.T+3); if(LV.cam){ var sv=LV.cam.saved; LV.cam=null; stopAnim(); animateTo(sv,2600); } }\n  }\n  function paradeMembers(){\n    var P=LV.parade, out=[];\n    FORMATION.forEach(function(f){ var dm=P.d+f.a; if(dm<0||dm>P.path.len) return; var s0=at(P.path,dm), k=Math.max(0.65,Math.min(1,Math.min(dm,P.path.len-dm)\/60)), l=f.l*k;\n      out.push({x:s0.x-s0.dy*l, y:s0.y+s0.dx*l, a:Math.min(1,dm\/14,(P.path.len-dm)\/30), flag:f.flag, dx:s0.dx, dy:s0.dy}); });\n    return out;\n  }\n  function paradeCentre(){ var P=LV.parade, s0=at(P.path,Math.max(0,Math.min(P.path.len,P.d-24))); return [s0.x,s0.y]; }\n  function paradeNear(x,y,r){ var P=LV.parade; if(!P) return false; for(var k=0;k<3;k++){ var dm=Math.max(0,Math.min(P.path.len,P.d-k*24)), s0=at(P.path,dm); if(Math.hypot(x-s0.x,y-s0.y)<r) return true; } return false; }\n  function paradeAvoid(x,y){ var P=LV.parade, vx=0, vy=0, hit=false; for(var k=0;k<3;k++){ var dm=Math.max(0,Math.min(P.path.len,P.d-k*24+14)), s0=at(P.path,dm), dx=x-s0.x, dy=y-s0.y, d=Math.hypot(dx,dy)||1;\n      if(d<46){ hit=true; vx+=dx\/d*(46-d)*1.2; vy+=dy\/d*(46-d)*1.2; } } return hit?[vx,vy]:null; }\n  \/* the Swiss Guard flag: cloth trailing behind the bearer, with folds rolling out toward the free edge *\/\n  function drawFlag(x,y,a,sc,which,mdx,mdy){\n    var q=scr(x,y); if(offscreen(q)) return; var u=unit(q), h=7.6*u*sc, g=LV.g; if(h<4) return;\n    var ahead=scr(x+(mdx||0)*30,y+(mdy||0)*30), sdx=ahead.x-q.x, dir=Math.abs(sdx)>0.5?(sdx>0?-1:1):(which===2?1:-1);\n    var px=q.x-h*0.26, top=q.y-h*1.85, fw=h*0.85*dir, fh=h*0.55, t=LV.T*6.5+(which===2?1.7:0), N=10;\n    g.globalAlpha=a; g.strokeStyle='#4a3b26'; g.lineWidth=Math.max(.6,h*0.05); g.beginPath(); g.moveTo(px,q.y-h*0.2); g.lineTo(px,top-h*0.08); g.stroke();\n    g.fillStyle='#d9b25b'; g.beginPath(); g.arc(px,top-h*0.1,Math.max(.6,h*0.05),0,7); g.fill();\n    \/* cloth: a travelling wave that grows toward the free edge, and shortens the cloth as it folds *\/\n    var pts=[]; for(var k=0;k<=N;k++){ var f=k\/N, ph=t-f*5.5, wave=Math.sin(ph), fold=0.08*(1-Math.cos(ph))*f;\n      pts.push({x:px+fw*(f-fold), y:top+wave*h*0.16*f+f*h*0.05, tilt:Math.cos(ph)*f, f:f}); }\n    function quad(k,v0,v1,col,sh){ var A=pts[k], B=pts[k+1]; g.fillStyle=col; g.beginPath(); g.moveTo(A.x,A.y+fh*v0); g.lineTo(B.x,B.y+fh*v0); g.lineTo(B.x,B.y+fh*v1); g.lineTo(A.x,A.y+fh*v1); g.closePath(); g.fill();\n      if(sh){ var light=(A.tilt+B.tilt)\/2*dir; g.fillStyle=light>0?'rgba(255,255,255,'+(light*0.28)+')':'rgba(20,10,40,'+(-light*0.3)+')'; g.fill(); } }\n    for(var k=0;k<N;k++){ var f=(k+0.5)\/N, left=f<0.5, cross=f>0.43&&f<0.57;\n      quad(k,0,0.42,cross?'#ffffff':(left?'#c8102e':'#f2c200'),false); quad(k,0.42,0.58,'#ffffff',false); quad(k,0.58,1,cross?'#ffffff':(left?'#1f4fa8':'#c8102e'),false); quad(k,0,1,'rgba(0,0,0,0)',true); }\n  }\n  \/* ---------------- camera: glide in, follow the platoon, glide back ---------------- *\/\n  function camOK(){ return !held&&!peek&&!touring&&!(typeof fdOpen!=='undefined'&&fdOpen)&&!CAL&&LV.vis&&!document.hidden&&performance.now()-LV.lastUser>9000; }\n  function camView(c){ var v={s:LV.cam.s, rot:LV.cam.saved.rot, tilt:LV.cam.tilt, tx:0, ty:0}, q=project(c[0]\/PW,c[1]\/PH,v); v.tx=-q.rx; v.ty=-q.ry+(compact?SH*0.04:SH*0.08); return v; }\n  function camFollow(dt){\n    if(!LV.cam||LV.cam.phase!=='follow'||anim||!LV.parade) return;\n    if(held||touring||(typeof fdOpen!=='undefined'&&fdOpen)){ LV.cam=null; return; }\n    var v=camView(paradeCentre()), k=Math.min(1,dt*1.4); st.tx+=(v.tx-st.tx)*k; st.ty+=(v.ty-st.ty)*k; apply();\n  }\n  function heliStart(){ var pad=PT(LIFE_GEO.heliport); LV.heli={t:0,rot:0,pad:pad,from:[pad[0]-640,pad[1]-520],to:[pad[0]-700,pad[1]+380],hd:0}; }\n  function heliState(h){\n    var t=h.t, e, x, y, alt;\n    if(t<12){ e=1-Math.pow(1-t\/12,3); x=h.from[0]+(h.pad[0]-h.from[0])*e; y=h.from[1]+(h.pad[1]-h.from[1])*e; alt=300*(1-Math.min(1,t\/11.5)*Math.min(1,t\/11.5)*(3-2*Math.min(1,t\/11.5))); }\n    else if(t<20){ x=h.pad[0]; y=h.pad[1]; alt=0; }\n    else { e=Math.pow((t-20)\/12,2); x=h.pad[0]+(h.to[0]-h.pad[0])*e; y=h.pad[1]+(h.to[1]-h.pad[1])*e; alt=Math.min(340,((t-20)\/12)*340*1.4); }\n    return {x:x,y:y,alt:alt};\n  }\n\n  \/* drawing helpers: shapes are laid out in painting units and projected, so they turn and tilt with the map *\/\n  function shape(pts,col,a){ var g=LV.g; g.globalAlpha=a; g.fillStyle=col; g.beginPath(); for(var i=0;i<pts.length;i++){ var q=scr(pts[i][0],pts[i][1]); if(i) g.lineTo(q.x,q.y); else g.moveTo(q.x,q.y); } g.closePath(); g.fill(); }\n  function box(cx,cy,hx,hy,L,Wd,col,a){ var l=L\/2,w=Wd\/2,nx=-hy,ny=hx;\n    shape([[cx+hx*l+nx*w,cy+hy*l+ny*w],[cx+hx*l-nx*w,cy+hy*l-ny*w],[cx-hx*l-nx*w,cy-hy*l-ny*w],[cx-hx*l+nx*w,cy-hy*l+ny*w]],col,a); }\n  function drawPerson(x,y,col,skin,ph,a,guard,sc){\n    var q=scr(x,y); if(offscreen(q)) return; var u=unit(q), h=7.6*u*(sc||1), g=LV.g; if(h<1.1) return;\n    g.globalAlpha=0.22*a; g.fillStyle='#000'; g.beginPath(); g.ellipse(q.x+h*0.18,q.y,h*0.26,h*0.09,0,0,7); g.fill();\n    g.globalAlpha=a;\n    if(h<5){ g.fillStyle=guard?'#c9902a':col; g.fillRect(q.x-h*0.17,q.y-h*0.8,h*0.34,h*0.8); if(guard){ g.fillStyle='#2c4a8a'; g.fillRect(q.x-h*0.17,q.y-h*0.5,h*0.34,h*0.2); } return; }\n    var sw=Math.sin(ph)*h*0.07;\n    g.fillStyle=guard?'#2c4a8a':col; g.beginPath(); g.ellipse(q.x,q.y-h*0.42,h*0.15,h*0.3,0,0,7); g.fill();\n    if(guard){ g.fillStyle='#d9a22c'; g.fillRect(q.x-h*0.15,q.y-h*0.62,h*0.07,h*0.5); g.fillRect(q.x+h*0.03,q.y-h*0.62,h*0.07,h*0.5); g.fillStyle='#b8231c'; g.fillRect(q.x-h*0.05,q.y-h*0.62,h*0.05,h*0.4); }\n    g.fillStyle=guard?'#2a2a2a':'#3a3128'; g.fillRect(q.x-h*0.09+sw,q.y-h*0.16,h*0.07,h*0.16); g.fillRect(q.x+h*0.02-sw,q.y-h*0.16,h*0.07,h*0.16);\n    g.fillStyle=skin; g.beginPath(); g.arc(q.x,q.y-h*0.82,h*0.11,0,7); g.fill();\n    if(guard){ g.fillStyle='#1e1e1e'; g.beginPath(); g.arc(q.x,q.y-h*0.9,h*0.1,Math.PI,0); g.fill(); if(guard!=='flag'){ g.strokeStyle='#5a4a36'; g.lineWidth=Math.max(.6,h*0.04); g.beginPath(); g.moveTo(q.x+h*0.22,q.y); g.lineTo(q.x+h*0.22,q.y-h*1.25); g.stroke(); g.fillStyle='#c8c8c8'; g.fillRect(q.x+h*0.18,q.y-h*1.3,h*0.12,h*0.1); } }\n  }\n  function drawVeh(v){\n    if(v.wait>0) return; var P=pose(v.path,v.d,v.dir,Math.max(v.L,28),0), hx=P.hx, hy=P.hy, cx=P.x, cy=P.y, q=scr(cx,cy);\n    if(offscreen(q)) return; var u=unit(q); if(v.L*u<2.2) return; var a=endFade(v.path,v.d);\n    box(cx+4,cy+3,hx,hy,v.L,v.Wd,'#000',0.22*a); box(cx,cy,hx,hy,v.L,v.Wd,v.col,a);\n    if(v.L*u>9){ if(v.t==='bus'){ box(cx,cy,hx,hy,v.L*0.9,v.Wd*0.55,'#3a3f44',0.55*a); } else if(v.t==='car'){ box(cx-hx*v.L*0.05,cy-hy*v.L*0.05,hx,hy,v.L*0.48,v.Wd*0.78,'#2e3238',0.5*a); } }\n    if(v.t==='vespa'){ var q2=scr(cx,cy); var hh=7*u; LV.g.globalAlpha=a; LV.g.fillStyle='#2b2b2b'; LV.g.beginPath(); LV.g.arc(q2.x,q2.y-hh*0.6,Math.max(.8,hh*0.16),0,7); LV.g.fill(); }\n  }\n  \/* boats: shaped hulls in painting units, with a Kelvin wake that follows the boat's real track *\/\n  function hullPts(cx,cy,hx,hy,L,Wd){ var nx=-hy, ny=hx, P=[[.5,0],[.4,.26],[.26,.44],[.06,.5],[-.34,.5],[-.46,.44],[-.5,.32]], out=[], i;\n    for(i=0;i<P.length;i++) out.push([cx+hx*L*P[i][0]+nx*Wd*P[i][1], cy+hy*L*P[i][0]+ny*Wd*P[i][1]]);\n    for(i=P.length-1;i>0;i--) out.push([cx+hx*L*P[i][0]-nx*Wd*P[i][1], cy+hy*L*P[i][0]-ny*Wd*P[i][1]]);\n    return out; }\n  function outline(pts,col,a,lw){ var g=LV.g; g.globalAlpha=a; g.strokeStyle=col; g.lineWidth=lw; g.lineJoin='round'; g.beginPath();\n    for(var i=0;i<pts.length;i++){ var q=scr(pts[i][0],pts[i][1]); if(i) g.lineTo(q.x,q.y); else g.moveTo(q.x,q.y); } g.closePath(); g.stroke(); }\n  function seg(x1,y1,x2,y2,col,a,lw){ var g=LV.g, p=scr(x1,y1), q=scr(x2,y2); g.globalAlpha=a; g.strokeStyle=col; g.lineWidth=lw; g.lineCap='round'; g.beginPath(); g.moveTo(p.x,p.y); g.lineTo(q.x,q.y); g.stroke(); }\n  function dot(x,y,r,col,a){ var g=LV.g, q=scr(x,y), rr=r*unit(q); if(rr<0.35) return; g.globalAlpha=a; g.fillStyle=col; g.beginPath(); g.arc(q.x,q.y,rr,0,7); g.fill(); }\n  function drawWake(b,a,u){\n    var tr=b.trail; if(tr.length<2) return; var g=LV.g, sides=[1,-1], k, i;\n    var spread=function(i){ return b.Wd*0.45+i*0.3*b.v*0.36; };\n    for(k=0;k<2;k++){ var sd=sides[k]; g.lineCap='round'; g.lineJoin='round';\n      for(i=1;i<tr.length;i++){ var p0=tr[i-1], p1=tr[i], s0=spread(i-1)*sd, s1=spread(i)*sd; var A=scr(p0[0]-p0[3]*s0-p0[2]*b.L*0.45, p0[1]+p0[2]*s0-p0[3]*b.L*0.45), B=scr(p1[0]-p1[3]*s1-p1[2]*b.L*0.45, p1[1]+p1[2]*s1-p1[3]*b.L*0.45); g.globalAlpha=a*0.5*Math.pow(1-i\/tr.length,1.4); g.strokeStyle='#f3f7f6'; g.lineWidth=Math.max(.5,u*(b.t==='skiff'?1.1:2.4)*(1-i\/tr.length*0.6)); g.beginPath(); g.moveTo(A.x,A.y); g.lineTo(B.x,B.y); g.stroke(); } } if(b.t!=='skiff') for(i=0;i<Math.min(7,tr.length);i++){ var p=tr[i]; dot(p[0]-p[2]*b.L*0.5,p[1]-p[3]*b.L*0.5,b.Wd*(0.28+i*0.06),'#eef4f3',a*0.28*(1-i\/7)); } } function drawBoat(b){ if(b.wait>0) return; var P=boatPos(b), cx=P.x, cy=P.y, hx=P.hx, hy=P.hy, nx=-hy, ny=hx, q=scr(cx,cy);\n    if(offscreen(q,140)) return; var u=unit(q); if(b.L*u<2.5) return;\n    var a=endFade(b.path,b.d);\n    if(a<=0.01) return; var L=b.L, Wd=b.Wd, big=L*u, lw=Math.max(.5,u*0.9), i;\n    drawWake(b,a,u);\n    var hull=hullPts(cx,cy,hx,hy,L,Wd);\n    shape(hullPts(cx+4,cy+6,hx,hy,L*1.02,Wd*1.08),'#16303a',0.3*a);\n    if(b.t!=='skiff'){ seg(cx+hx*L*.5,cy+hy*L*.5,cx+hx*L*.26+nx*Wd*.75,cy+hy*L*.26+ny*Wd*.75,'#f3f7f6',a*.55,Math.max(.5,u*1.6));\n      seg(cx+hx*L*.5,cy+hy*L*.5,cx+hx*L*.26-nx*Wd*.75,cy+hy*L*.26-ny*Wd*.75,'#f3f7f6',a*.55,Math.max(.5,u*1.6)); }\n    if(b.t==='tour'){\n      shape(hull,b.c2,a);\n      shape(hullPts(cx-hx*1.5,cy-hy*1.5,hx,hy,L*0.95,Wd*0.86),b.c1,a);\n      shape(hullPts(cx-hx*1.5+nx*Wd*0.2,cy-hy*1.5+ny*Wd*0.2,hx,hy,L*0.9,Wd*0.4),'#c9c4b8',0.25*a);\n      box(cx-hx*L*0.05,cy-hy*L*0.05,hx,hy,L*0.6,Wd*0.64,'#9fb6c0',a);\n      box(cx-hx*L*0.05,cy-hy*L*0.05,hx,hy,L*0.56,Wd*0.4,'#e4e8e6',a);\n      box(cx-hx*L*0.05+nx*Wd*0.1,cy-hy*L*0.05+ny*Wd*0.1,hx,hy,L*0.56,Wd*0.12,'#ffffff',0.5*a);\n      if(big>26){ for(i=0;i<8;i++){ var t=-0.31+i*0.074; [1,-1].forEach(function(sd){ box(cx+hx*L*t+nx*Wd*0.27*sd,cy+hy*L*t+ny*Wd*0.27*sd,hx,hy,L*0.045,Wd*0.07,'#2f4350',0.85*a); }); }\n        for(i=0;i<5;i++){ dot(cx-hx*L*(0.38+(i%2)*0.05)+nx*Wd*(-0.28+i*0.14),cy-hy*L*(0.38+(i%2)*0.05)+ny*Wd*(-0.28+i*0.14),3.2,b.pax[i],a); } }\n      outline(hull,'#4b4a46',0.45*a,lw);\n    } else if(b.t==='barge'){\n      shape(hull,'#8a2a20',a);\n      shape(hullPts(cx-hx*1.5,cy-hy*1.5,hx,hy,L*0.96,Wd*0.86),'#2f2c28',a);\n      shape(hullPts(cx-hx*2,cy-hy*2,hx,hy,L*0.9,Wd*0.68),'#5a5046',a);\n      box(cx+hx*L*0.1,cy+hy*L*0.1,hx,hy,L*0.52,Wd*0.56,'#55705c',a);\n      if(big>24) for(i=0;i<6;i++){ var tt=-0.14+i*0.09; seg(cx+hx*L*tt+nx*Wd*0.28,cy+hy*L*tt+ny*Wd*0.28,cx+hx*L*tt-nx*Wd*0.28,cy+hy*L*tt-ny*Wd*0.28,'#3e5446',a*0.8,lw); }\n      box(cx-hx*L*0.36,cy-hy*L*0.36,hx,hy,L*0.13,Wd*0.6,'#e6e0cf',a);\n      box(cx-hx*L*0.33,cy-hy*L*0.33,hx,hy,L*0.04,Wd*0.5,'#2f4350',0.8*a);\n      box(cx-hx*L*0.37,cy-hy*L*0.37,hx,hy,L*0.06,Wd*0.66,'#8a2a20',a);\n      outline(hull,'#1c1a17',0.5*a,lw);\n    } else {\n      var sw=Math.sin(b.ph), catchK=Math.max(0,sw);\n      for(var r=0;r<b.rowers;r++){ var rt=b.rowers===1?0:(r?-0.14:0.14), px=cx+hx*L*rt, py=cy+hy*L*rt, ang=sw*0.55; [1,-1].forEach(function(sd){ var ox=-hx*Math.sin(ang), oy=-hy*Math.sin(ang), ex=px+(nx*sd*Math.cos(ang)+ox)*15, ey=py+(ny*sd*Math.cos(ang)+oy)*15; seg(px+nx*sd*Wd*0.4,py+ny*sd*Wd*0.4,ex,ey,'#6b5233',a,Math.max(.4,u*0.8)); box(ex,ey,hx,hy,3.2,1.6,'#c8102e',a); if(catchK>0.85) dot(ex,ey,2.6,'#f3f7f6',a*0.6); }); }\n      shape(hull,'#f1ece0',a);\n      seg(cx+hx*L*0.42,cy+hy*L*0.42,cx-hx*L*0.42,cy-hy*L*0.42,'#b99868',a*0.8,Math.max(.4,u*1));\n      for(r=0;r<b.rowers;r++){ var rt2=b.rowers===1?0:(r?-0.14:0.14), lean=-sw*2.2; dot(cx+hx*(L*rt2+lean),cy+hy*(L*rt2+lean),2.6,b.shirt,a); dot(cx+hx*(L*rt2+lean+1.6),cy+hy*(L*rt2+lean+1.6),1.4,'#e6bd9a',a); } outline(hull,'#7a6a50',0.6*a,Math.max(.4,u*0.6)); } } function drawBird(b){ var x=b.c[0]+b.r*Math.cos(b.ang), y=b.c[1]+b.r*Math.sin(b.ang)*0.55, q=scr(x,y); if(offscreen(q,30)) return; var u=unit(q), g=LV.g; var sx=q.x, sy=q.y-b.alt*u, s=Math.max(2.2,Math.min(9,6.5*u)), f=Math.sin(b.ph)*s*0.45, hd=b.ang+(b.w>0?Math.PI\/2:-Math.PI\/2);\n    g.globalAlpha=0.7; g.strokeStyle='#211a12'; g.lineWidth=Math.max(.7,s*0.16); g.beginPath();\n    var c=Math.cos(hd), sn=Math.sin(hd)*0.55; g.moveTo(sx-sn*s*0.9-c*0.1,sy-f+c*s*0.4); g.lineTo(sx,sy); g.lineTo(sx+sn*s*0.9,sy-f-c*s*0.4); g.stroke();\n  }\n  function drawHeli(){\n    var h=LV.heli, S=heliState(h), q=scr(S.x,S.y); if(offscreen(q,120)) return; var u=unit(q), g=LV.g, t=h.t;\n    var pf=Math.min(1,t\/3,Math.max(0,(32-t)\/3)), pad=scr(h.pad[0],h.pad[1]), pu=unit(pad);\n    g.globalAlpha=0.55*pf; g.strokeStyle='#f4f2ee'; g.lineWidth=Math.max(.8,pu*3); g.beginPath();\n    for(var i=0;i<=24;i++){ var an=i\/24*Math.PI*2, pp=scr(h.pad[0]+Math.cos(an)*34,h.pad[1]+Math.sin(an)*34); if(i) g.lineTo(pp.x,pp.y); else g.moveTo(pp.x,pp.y); } g.stroke();\n    var A=scr(h.pad[0]-12,h.pad[1]-16), B=scr(h.pad[0]-12,h.pad[1]+16), C=scr(h.pad[0]+12,h.pad[1]-16), D2=scr(h.pad[0]+12,h.pad[1]+16), M1=scr(h.pad[0]-12,h.pad[1]), M2=scr(h.pad[0]+12,h.pad[1]);\n    g.beginPath(); g.moveTo(A.x,A.y); g.lineTo(B.x,B.y); g.moveTo(C.x,C.y); g.lineTo(D2.x,D2.y); g.moveTo(M1.x,M1.y); g.lineTo(M2.x,M2.y); g.stroke();\n    function sang(dx,dy){ var l=Math.hypot(dx,dy)||1, b2=scr(h.pad[0]+dx\/l*30,h.pad[1]+dy\/l*30); return Math.atan2(b2.y-pad.y,b2.x-pad.x); }\n    var a1=sang(h.pad[0]-h.from[0],h.pad[1]-h.from[1]), a2=sang(h.to[0]-h.pad[0],h.to[1]-h.pad[1]), dA=Math.atan2(Math.sin(a2-a1),Math.cos(a2-a1)), hd=a1+dA*Math.max(0,Math.min(1,(t-16)\/4));\n    var s=u, bx=q.x, by=q.y-S.alt*u*0.9;\n    g.globalAlpha=0.28*Math.max(.25,1-S.alt\/420); g.fillStyle='#000'; g.beginPath(); g.ellipse(q.x+6*u,q.y+3*u,32*s,13*s,hd,0,7); g.fill();\n    g.save(); g.translate(bx,by); g.rotate(hd); g.globalAlpha=1;\n    g.fillStyle='#e9e6df'; g.fillRect(-64*s,-2.2*s,40*s,4.4*s); g.fillRect(-66*s,-9*s,6*s,18*s);\n    g.fillStyle='#f6f4ef'; g.beginPath(); g.ellipse(0,0,28*s,10*s,0,0,7); g.fill();\n    g.fillStyle='#c9a35a'; g.fillRect(-22*s,-1*s,40*s,2*s);\n    g.fillStyle='#2a3440'; g.beginPath(); g.ellipse(17*s,0,9*s,7*s,0,0,7); g.fill();\n    g.globalAlpha=0.13; g.fillStyle='#1c1c1c'; g.beginPath(); g.arc(0,0,38*s,0,7); g.fill();\n    g.globalAlpha=0.55; g.strokeStyle='#2b2b2b'; g.lineWidth=Math.max(.8,2.2*s); g.beginPath();\n    for(var k=0;k<4;k++){ var ra=h.rot+k*Math.PI\/2; g.moveTo(0,0); g.lineTo(Math.cos(ra)*38*s,Math.sin(ra)*38*s); } g.stroke();\n    g.restore();\n  }\n  function drawSmoke(){\n    var S=LV.smoke, c=PT(LIFE_GEO.chimney), q=scr(c[0],c[1]); if(offscreen(q,200)) return; var u=unit(q), g=LV.g, by=q.y-20*u;\n    S.puffs.forEach(function(p){ var k=p.age\/p.life, r=(7+p.age*7.5)*u, x=q.x+(p.dx*30+p.age*6)*u, y=by-(p.age*15)*u;\n      g.globalAlpha=0.6*(1-k)*Math.min(1,p.age*2); g.fillStyle='#fbfaf6'; g.beginPath(); g.arc(x,y,Math.max(1,r),0,7); g.fill();\n      g.globalAlpha=0.12*(1-k); g.fillStyle='#8a8478'; g.beginPath(); g.arc(x+r*0.25,y+r*0.25,Math.max(1,r*0.8),0,7); g.fill(); });\n  }\n  function lifeDraw(){\n    var g=LV.g; g.clearRect(0,0,SW,SH);\n    \/* boats come and go at the edge of the painting *\/\n    g.save(); g.beginPath(); [[0,0],[PW,0],[PW,PH],[0,PH]].forEach(function(c,i){ var q=scr(c[0],c[1]); if(i) g.lineTo(q.x,q.y); else g.moveTo(q.x,q.y); }); g.closePath();\n    g.clip(); drawFlow(); LV.boats.forEach(drawBoat); g.restore();\n    \/* traffic is drawn only on the painting, and passes behind buildings that stand in front of the road *\/\n    g.save(); g.beginPath(); [[0,0],[PW,0],[PW,PH],[0,PH]].forEach(function(c,i){ var q=scr(c[0],c[1]); if(i) g.lineTo(q.x,q.y); else g.moveTo(q.x,q.y); }); g.closePath();\n    if(!LV.occOK) LIFE_GEO.occluders.forEach(function(o){ o.forEach(function(p,i){ var c=PT(p), q=scr(c[0],c[1]); if(i) g.lineTo(q.x,q.y); else g.moveTo(q.x,q.y); }); g.closePath(); });\n    g.clip('evenodd'); LV.veh.forEach(drawVeh); g.restore();\n    var list=[];\n    LV.ppl.forEach(function(p){ var x,y,a=1; if(p.path){ var s=at(p.path,p.d); x=s.x-s.dy*p.off; y=s.y+s.dx*p.off; if(p.m==='once') a=endFade(p.path,p.d); } else { x=p.x; y=p.y; } list.push([y,x,p,a]); });\n    LV.guards.forEach(function(gd){ list.push([gd.y,gd.x,gd,1,1]); });\n    if(LV.parade) paradeMembers().forEach(function(m){ list.push([m.y,m.x,m,m.a,2]); });\n    list.sort(function(a,b){ return a[0]-b[0]; });\n    list.forEach(function(it){ var p=it[2]; if(it[4]===2){ drawPerson(it[1],it[0],'#2c4a8a','#e6bd9a',LV.parade.ph,it[3],p.flag?'flag':true,PSC); if(p.flag) drawFlag(it[1],it[0],it[3],PSC,p.flag,p.dx,p.dy); return; } if(it[4]) drawPerson(it[1]+Math.sin(LV.T*0.25+p.ph)*2,it[0],'#2c4a8a','#e6bd9a',0,1,true); else drawPerson(it[1],it[0],p.col,p.skin,p.ph,it[3],false); });\n    if(BLESS) drawBless();\n    if(LV.smoke) drawSmoke();\n    if(LV.heli) drawHeli();\n    LV.birds.forEach(drawBird);\n    g.globalAlpha=1;\n  }\n  function lifeSize(){ if(!LV.cv) return; var dpr=Math.min(2,window.devicePixelRatio||1); LV.cv.width=Math.max(1,Math.round(SW*dpr)); LV.cv.height=Math.max(1,Math.round(SH*dpr)); LV.g.setTransform(dpr,0,0,dpr,0,0); }\n  function lifeFrame(ts){ LV.raf=requestAnimationFrame(lifeFrame); if(!LV.last){ LV.last=ts; return; } var el=ts-LV.last; if(el<15) return; LV.last=ts; lifeStep(Math.min(0.1,el\/1000)); camFollow(Math.min(0.1,el\/1000)); lifeDraw(); }\n  function lifeRun(){ var go=LV.vis&&!document.hidden; if(go&&!LV.raf){ LV.last=0; LV.raf=requestAnimationFrame(lifeFrame); } else if(!go&&LV.raf){ cancelAnimationFrame(LV.raf); LV.raf=0; } }\n  \/* copy the painting\u2019s statues, the bell tower and the corner building into a layer above the traffic *\/\n  function buildOcc(){\n    if(!occEl) return false;\n    try{\n      var NW=img.naturalWidth, NH=img.naturalHeight;\n      LIFE_GEO.occluders.forEach(function(o,oi){\n      var xs=o.map(function(p){ return p[0]; }), ys=o.map(function(p){ return p[1]; }), R=[Math.min.apply(null,xs)-0.3,Math.min.apply(null,ys)-0.3,Math.max.apply(null,xs)+0.3,Math.max.apply(null,ys)+0.3];\n      var ox=R[0]\/100*NW, oy=R[1]\/100*NH, w=Math.round((R[2]-R[0])\/100*NW), h=Math.round((R[3]-R[1])\/100*NH);\n      var c=document.createElement('canvas'); c.width=w; c.height=h; var x=c.getContext('2d');\n      function L(p){ return [p[0]\/100*NW-ox, p[1]\/100*NH-oy]; }\n      x.save(); x.beginPath(); o.forEach(function(p,i){ var q=L(p); if(i) x.lineTo(q[0],q[1]); else x.moveTo(q[0],q[1]); }); x.closePath(); x.clip();\n      x.drawImage(img,ox,oy,w,h,0,0,w,h); x.restore();\n      var t=document.createElement('canvas'), tx=t.getContext('2d');\n      if(oi===0) LIFE_GEO.statues.forEach(function(r){ var a=L([r[0],r[1]]), b=L([r[2],r[3]]), sw=Math.max(1,Math.round(b[0]-a[0])), sh=Math.max(1,Math.round(b[1]-a[1]));\n        t.width=sw; t.height=sh; tx.clearRect(0,0,sw,sh); tx.drawImage(img,a[0]+ox,a[1]+oy,sw,sh,0,0,sw,sh);\n        var d=tx.getImageData(0,0,sw,sh), p=d.data; for(var i=0;i<p.length;i+=4){ var lum=0.3*p[i]+0.59*p[i+1]+0.11*p[i+2]; p[i+3]=Math.max(0,Math.min(255,(lum-128)*12)); } tx.putImageData(d,0,0); x.drawImage(t,Math.round(a[0]),Math.round(a[1])); }); c.style.left=R[0]+'%'; c.style.top=R[1]+'%'; c.style.width=(R[2]-R[0])+'%'; c.style.height=(R[3]-R[1])+'%'; occEl.appendChild(c); }); occEl.classList.add('is-ready'); return true; }catch(e){ return false; } } \/* ---------------- the blessing from the Angelus window ---------------- Opening the Papal Apartments brings a figure in white to the second window from the right. He greets the square, gives the blessing in Italian, and withdraws; the words appear beside the window with their English. *\/ var BLESS=null, blessEl=root.querySelector('.vm-bless'); var BLESS_WIN=[47.0,42.3], BLESS_SILL=42.55; var BLESS_LINES=[[1.5,'Cari fratelli e sorelle, buongiorno!','Dear brothers and sisters, good morning!'], [5.2,'Vi benedica Dio onnipotente,','May almighty God bless you,'], [8.6,'il Padre, il Figlio e lo Spirito Santo.','the Father, the Son and the Holy Spirit.'], [12.6,'Amen.','Amen.'], [14.2,'Buona domenica a tutti!','A good Sunday to you all!']]; function blessStart(){ if(!LV.cv) return; BLESS={t:0, line:-1}; } function blessStop(){ BLESS=null; if(blessEl){ blessEl.classList.remove('is-on'); blessEl.hidden=true; } } function blessStep(dt){ if(!BLESS) return; BLESS.t+=dt; if(BLESS.t>20.5){ if(touring){ BLESS.t=0; return; } \/* on the tour the card moves on by itself *\/\n      stopTour(); release(); resetView(); return; } \/* blessing over: back to the opening view, as if Reset were pressed *\/\n    var t=BLESS.t, cur=-1; for(var i=0;i<BLESS_LINES.length;i++) if(t>=BLESS_LINES[i][0]&&t<BLESS_LINES[i][0]+3.4) cur=i;\n    if(blessEl){ if(cur!==BLESS.line){ BLESS.line=cur; if(cur<0){ blessEl.classList.remove('is-on'); } else { blessEl.hidden=false; blessEl.querySelector('i').textContent=BLESS_LINES[cur][1]; blessEl.querySelector('span').textContent=BLESS_LINES[cur][2]; blessEl.classList.add('is-on'); } }\n      if(!blessEl.hidden){ var w=PT(BLESS_WIN), q=scr(w[0],w[1]), u=unit(q); blessEl.style.transform='translate(-50%,-100%) translate('+q.x.toFixed(1)+'px,'+(q.y-26*u-14).toFixed(1)+'px)'; } }\n  }\n  function drawBless(){\n    var t=BLESS.t, w=PT(BLESS_WIN), q=scr(w[0],w[1]); if(offscreen(q,80)) return; var u=unit(q)*1.2, g=LV.g; if(u<0.4) return;\n    var sill=scr(w[0],BLESS_SILL\/100*PH), rise=Math.min(1,t\/1.6), down=t>17?Math.min(1,(t-17)\/1.6):0, vis=rise-down; if(vis<=0) return;\n    \/* red tapestry over the sill *\/\n    g.globalAlpha=Math.min(1,t\/1.2)*(1-down); g.fillStyle='#8c1d18'; g.fillRect(sill.x-6.2*u,sill.y-0.5*u,12.4*u,11*u); g.fillStyle='#c9a35a'; g.fillRect(sill.x-6.2*u,sill.y+10*u,12.4*u,1.2*u);\n    g.fillStyle='rgba(255,220,150,.35)'; g.fillRect(sill.x-1.2*u,sill.y+2*u,2.4*u,6*u);\n    \/* the figure in white, rising from the sill *\/\n    g.save(); g.beginPath(); g.rect(0,0,SW,sill.y); g.clip(); g.globalAlpha=1;\n    var base=sill.y+16*u*(1-vis), cx=q.x, h=17*u;\n    g.fillStyle='rgba(0,0,0,.18)'; g.fillRect(cx-5*u,base-h*0.72,10*u,h*0.72);\n    g.fillStyle='#f7f4ee'; g.beginPath(); g.moveTo(cx-4.6*u,base); g.lineTo(cx-4.2*u,base-h*0.62); g.quadraticCurveTo(cx,base-h*0.78,cx+4.2*u,base-h*0.62); g.lineTo(cx+4.6*u,base); g.closePath(); g.fill();\n    g.fillStyle='#e3b792'; g.beginPath(); g.arc(cx,base-h*0.86,2.6*u,0,7); g.fill();\n    g.fillStyle='#f7f4ee'; g.beginPath(); g.arc(cx,base-h*0.93,2.3*u,Math.PI,0); g.fill();\n    g.fillStyle='#c9a35a'; g.fillRect(cx-0.7*u,base-h*0.66,1.4*u,h*0.2);\n    \/* right arm: raised, then the sign of the cross, then a wave *\/\n    var ax=cx+3.6*u, ay=base-h*0.6, ex, ey;\n    if(t<8.6){ var k=Math.min(1,Math.max(0,(t-1.2)\/1.2)); ex=ax+3*u*k; ey=ay-7*u*k; }\n    else if(t<12.6){ var s2=(t-8.6)\/4, c=s2<0.5?[0,-9+s2*2*7]:[-3+((s2-0.5)*2)*6,-5]; ex=ax+c[0]*u; ey=ay+c[1]*u; }\n    else if(t<14.2){ ex=ax+3*u; ey=ay-7*u; }\n    else { ex=ax+4*u+Math.sin(t*5)*2.6*u; ey=ay-7.5*u; }\n    g.strokeStyle='#f7f4ee'; g.lineWidth=Math.max(1,2.4*u); g.lineCap='round'; g.beginPath(); g.moveTo(ax,ay); g.lineTo(ex,ey); g.stroke();\n    g.fillStyle='#e3b792'; g.beginPath(); g.arc(ex,ey,1.4*u,0,7); g.fill();\n    g.restore();\n  }\n  function lifeInit(){\n    if(!CONFIG.LIFE||reduce||LV.cv) return; var cv=root.querySelector('.vm-life'); if(!cv||!cv.getContext) return;\n    LV.cv=cv; LV.g=cv.getContext('2d'); lifeSize(); lifeBuild(); LV.occOK=buildOcc();\n    if('IntersectionObserver' in window) new IntersectionObserver(function(en){ LV.vis=en[0].isIntersecting; lifeRun(); }).observe(stage);\n    document.addEventListener('visibilitychange',lifeRun); lifeRun();\n    ['pointerdown','wheel','keydown','touchstart'].forEach(function(t){ stage.addEventListener(t,function(){ LV.lastUser=performance.now(); LV.cam=null; },{capture:true,passive:true}); });\n  }\n\n  \/* ---------------- start ---------------- *\/\n  var CAL = CONFIG.CALIBRATE || \/[?&]vmap-calibrate=1\/.test(location.search);\n  function intro(){\n    plane.classList.add('is-ready');\n    if(reduce){ Object.assign(st,homeView()); apply(); return; }\n    Object.assign(st,{tx:0,ty:SH*0.06,s:0.82,rot:-14,tilt:42}); apply();\n    setTimeout(function(){ animateTo(homeView(),2000); },120);\n  }\n  if(!CONFIG.BASE_IMAGE || CONFIG.BASE_IMAGE.indexOf('YOUR-'+'SITE')>=0){\n    msg.hidden=false; msg.innerHTML='<strong>Almost there.<\/strong><br>Paste the web address of your painting into <code>BASE_IMAGE<\/code> in the settings at the top of the script.';\n  }\n  root.style.setProperty('--vm-img','url(\"'+CONFIG.BASE_IMAGE+'\")');\n  img.addEventListener('load',function(){ IW=img.naturalWidth||IW; IH=img.naturalHeight||IH; setCompact(); intro(); lifeInit(); if(CAL) calibrate(); });\n  img.addEventListener('error',function(){ if(msg.hidden){ msg.hidden=false; msg.innerHTML='<strong>The painting could not be loaded.<\/strong><br>Check that the address in <code>BASE_IMAGE<\/code> opens in a new browser tab.'; } });\n  setCompact();\n  img.src=CONFIG.BASE_IMAGE;\n\n  \/* ---------------- marker-placement tool ---------------- *\/\n  function calibrate(){\n    var cur=0, pos=JSON.parse(JSON.stringify(CONFIG.POSITIONS));\n    var pane=document.createElement('div'); pane.className='vm-cal';\n    pane.innerHTML='<strong>Marker placement<\/strong><p>Pick a location, then click the spot on the painting where its marker should stand. Press Copy and paste the result over POSITIONS in the settings.<\/p><select><\/select><div><button type=\"button\" data-a=\"prev\">\u2039 Prev<\/button><button type=\"button\" data-a=\"next\">Next \u203a<\/button><button type=\"button\" data-a=\"copy\">Copy<\/button><\/div><textarea readonly rows=\"5\"><\/textarea>';\n    stage.appendChild(pane); hint.textContent='Placement tool: click the painting to place the selected marker'; hint.classList.remove('is-gone');\n    var sel=pane.querySelector('select'), ta=pane.querySelector('textarea');\n    PLACES.forEach(function(p,i){ var o=document.createElement('option'); o.value=i; o.textContent=p.n+'. '+p.name; sel.appendChild(o); });\n    function out(){ ta.value='POSITIONS: {\\n'+PLACES.map(function(p){ var q=pos[p.id]||[50,50]; return '      '+p.id+':['+q[0]+', '+q[1]+']'; }).join(',\\n')+'\\n    }'; }\n    function pick(i){ cur=(i+PLACES.length)%PLACES.length; sel.value=cur; markActive(PLACES[cur].id); setHalo(PLACES[cur]); }\n    sel.addEventListener('change',function(){ pick(+sel.value); });\n    pane.addEventListener('pointerdown',function(e){ e.stopPropagation(); });\n    pane.addEventListener('click',function(e){ var a=e.target.getAttribute('data-a'); if(!a) return;\n      if(a==='prev') pick(cur-1); if(a==='next') pick(cur+1);\n      if(a==='copy'){ ta.select(); try{ navigator.clipboard.writeText(ta.value); }catch(err){ document.execCommand('copy'); } e.target.textContent='Copied'; setTimeout(function(){ e.target.textContent='Copy'; },1500); } });\n    stage.addEventListener('click',function(e){ if(moved>4||e.target.closest('.vm-ui,.vm-cal,.vm-ui-pin')) return;\n      var r=stage.getBoundingClientRect(), f=unproject(e.clientX-r.left,e.clientY-r.top), p=PLACES[cur];\n      pos[p.id]=[+(f[0]*100).toFixed(1), +(f[1]*100).toFixed(1)]; CONFIG.POSITIONS[p.id]=pos[p.id]; apply(); out(); pick(cur+1); });\n    out(); pick(0);\n  }\n})();\n<\/script> \t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-457f36d elementor-widget elementor-widget-shortcode\" data-id=\"457f36d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div class='mwai-chatbot-container' data-params='{&quot;aiName&quot;:&quot;Father Michael Dominic&quot;,&quot;userName&quot;:&quot;Researcher&quot;,&quot;guestName&quot;:&quot;Researcher&quot;,&quot;aiAvatar&quot;:true,&quot;aiAvatarUrl&quot;:&quot;https:\\\/\\\/garymcavoy.com\\\/files\\\/Michael-Dominic-Avatar.jpg&quot;,&quot;textSend&quot;:&quot;Send&quot;,&quot;textClear&quot;:&quot;Clear&quot;,&quot;imageUpload&quot;:false,&quot;fileUpload&quot;:false,&quot;multiUpload&quot;:false,&quot;maxUploads&quot;:20,&quot;fileUploads&quot;:0,&quot;mode&quot;:&quot;chat&quot;,&quot;textInputPlaceholder&quot;:&quot;Type your message...&quot;,&quot;textEmptyHint&quot;:&quot;&quot;,&quot;textInputMaxLength&quot;:512,&quot;textCompliance&quot;:&quot;&quot;,&quot;startSentence&quot;:&quot;Hi! How may I help you?&quot;,&quot;localMemory&quot;:false,&quot;themeId&quot;:&quot;chatgpt&quot;,&quot;window&quot;:false,&quot;icon&quot;:&quot;&quot;,&quot;iconText&quot;:&quot;&quot;,&quot;iconTextDelay&quot;:1,&quot;iconTextDuration&quot;:0,&quot;iconTextOnce&quot;:&quot;session&quot;,&quot;iconAlt&quot;:&quot;AI Engine Chatbot&quot;,&quot;iconPosition&quot;:&quot;bottom-right&quot;,&quot;centerOpen&quot;:false,&quot;width&quot;:&quot;&quot;,&quot;openDelay&quot;:&quot;&quot;,&quot;iconBubble&quot;:false,&quot;windowAnimation&quot;:&quot;zoom&quot;,&quot;fullscreen&quot;:false,&quot;copyButton&quot;:true,&quot;pdfButton&quot;:false,&quot;headerSubtitle&quot;:&quot;Discuss with&quot;,&quot;containerType&quot;:&quot;standard&quot;,&quot;headerType&quot;:&quot;standard&quot;,&quot;messagesType&quot;:&quot;standard&quot;,&quot;inputType&quot;:&quot;standard&quot;,&quot;footerType&quot;:&quot;standard&quot;}' data-system='{&quot;botId&quot;:&quot;default&quot;,&quot;customId&quot;:null,&quot;userData&quot;:null,&quot;sessionId&quot;:null,&quot;restNonce&quot;:null,&quot;contextId&quot;:null,&quot;pluginUrl&quot;:&quot;https:\\\/\\\/garymcavoy.com\\\/wp-content\\\/plugins\\\/ai-engine-pro&quot;,&quot;restUrl&quot;:&quot;https:\\\/\\\/garymcavoy.com\\\/de\\\/wp-json&quot;,&quot;stream&quot;:true,&quot;debugMode&quot;:false,&quot;eventLogs&quot;:false,&quot;speech_recognition&quot;:false,&quot;speech_synthesis&quot;:false,&quot;typewriter&quot;:false,&quot;crossSite&quot;:false,&quot;texts&quot;:{&quot;Ask me anything!&quot;:&quot;Ask me anything!&quot;,&quot;Jump to the latest message&quot;:&quot;Jump to the latest message&quot;,&quot;Try again&quot;:&quot;Try again&quot;,&quot;Conversation cleared.&quot;:&quot;Conversation cleared.&quot;,&quot;Undo&quot;:&quot;Undo&quot;,&quot;Done!&quot;:&quot;Done!&quot;,&quot;New Chat&quot;:&quot;New Chat&quot;,&quot;No messages yet&quot;:&quot;No messages yet&quot;,&quot;Rename&quot;:&quot;Rename&quot;,&quot;Delete&quot;:&quot;Delete&quot;,&quot;Your text was cut at %d characters.&quot;:&quot;Your text was cut at %d characters.&quot;,&quot;Hold to Talk&quot;:&quot;Hold to Talk&quot;,&quot;Release to Send&quot;:&quot;Release to Send&quot;,&quot;Press Space to talk&quot;:&quot;Press Space to talk&quot;,&quot;Start session to upload images&quot;:&quot;Start session to upload images&quot;,&quot;Usage limit exceeded&quot;:&quot;Usage limit exceeded&quot;,&quot;Connection failed&quot;:&quot;Connection failed&quot;,&quot;Connection failed. Please check your network and try again.&quot;:&quot;Connection failed. Please check your network and try again.&quot;,&quot;Connection lost. Reconnecting...&quot;:&quot;Connection lost. Reconnecting...&quot;,&quot;Connection lost while uploading image. Please try again.&quot;:&quot;Connection lost while uploading image. Please try again.&quot;,&quot;Connection timeout: The server took too long to respond.&quot;:&quot;Connection timeout: The server took too long to respond.&quot;,&quot;Could not start realtime session.&quot;:&quot;Could not start realtime session.&quot;,&quot;An error occurred while starting the realtime session.&quot;:&quot;An error occurred while starting the realtime session.&quot;,&quot;An error occurred while processing your request. Please try again.&quot;:&quot;An error occurred while processing your request. Please try again.&quot;,&quot;An error occurred while committing the stats.&quot;:&quot;An error occurred while committing the stats.&quot;,&quot;An error occurred while committing the discussion.&quot;:&quot;An error occurred while committing the discussion.&quot;,&quot;An error occurred while executing the function.&quot;:&quot;An error occurred while executing the function.&quot;,&quot;Authentication failed: Your session has expired. Please refresh the page.&quot;:&quot;Authentication failed: Your session has expired. Please refresh the page.&quot;,&quot;Error uploading image. Please try again.&quot;:&quot;Error uploading image. Please try again.&quot;,&quot;Failed to access microphone: &quot;:&quot;Failed to access microphone: &quot;,&quot;Failed to access microphone. Please ensure microphone permissions are granted and try again.&quot;:&quot;Failed to access microphone. Please ensure microphone permissions are granted and try again.&quot;,&quot;Failed to establish connection with OpenAI servers. Please try again.&quot;:&quot;Failed to establish connection with OpenAI servers. Please try again.&quot;,&quot;Failed to read image file.&quot;:&quot;Failed to read image file.&quot;,&quot;Failed to send image. Please try again.&quot;:&quot;Failed to send image. Please try again.&quot;,&quot;Failed to upload image.&quot;:&quot;Failed to upload image.&quot;,&quot;Image file size must be less than 20MB.&quot;:&quot;Image file size must be less than 20MB.&quot;,&quot;Internal server error: An unexpected error occurred. Please try again.&quot;:&quot;Internal server error: An unexpected error occurred. Please try again.&quot;,&quot;Invalid API key: Please check your OpenAI API key in settings.&quot;:&quot;Invalid API key: Please check your OpenAI API key in settings.&quot;,&quot;Invalid request: The message format was not recognized by the server.&quot;:&quot;Invalid request: The message format was not recognized by the server.&quot;,&quot;MediaDevices API not available. Please ensure you are using HTTPS and a modern browser.&quot;:&quot;MediaDevices API not available. Please ensure you are using HTTPS and a modern browser.&quot;,&quot;Model overloaded: The AI model is currently experiencing high demand.&quot;:&quot;Model overloaded: The AI model is currently experiencing high demand.&quot;,&quot;Network error: Failed to establish connection to the AI service.&quot;:&quot;Network error: Failed to establish connection to the AI service.&quot;,&quot;Please select an image file.&quot;:&quot;Please select an image file.&quot;,&quot;Please start a session before uploading images.&quot;:&quot;Please start a session before uploading images.&quot;,&quot;Quota exceeded: You have reached your usage limit for this period.&quot;:&quot;Quota exceeded: You have reached your usage limit for this period.&quot;,&quot;Rate limit exceeded: Too many requests. Please try again later.&quot;:&quot;Rate limit exceeded: Too many requests. Please try again later.&quot;,&quot;Service unavailable: The AI service is temporarily down for maintenance.&quot;:&quot;Service unavailable: The AI service is temporarily down for maintenance.&quot;},&quot;actions&quot;:[],&quot;blocks&quot;:[],&quot;shortcuts&quot;:[]}' data-theme='{&quot;type&quot;:&quot;internal&quot;,&quot;name&quot;:&quot;ChatGPT&quot;,&quot;themeId&quot;:&quot;chatgpt&quot;,&quot;settings&quot;:[],&quot;style&quot;:&quot;&quot;,&quot;cssUrl&quot;:&quot;https:\\\/\\\/garymcavoy.com\\\/wp-content\\\/plugins\\\/ai-engine-pro\\\/themes\\\/chatgpt.css&quot;}'><\/div><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Stato della Citt\u00e0 del Vaticano Innerhalb der Mauern Vierundzwanzig Orte in und um die p\u00e4pstliche Stadt, von den Archivgew\u00f6lben bis zur Kaserne der Schweizergarde. Sehensw\u00fcrdigkeiten Zur Tour N 3D Tour beenden \u00d7 \u00d7 Kartendesign Copyright \u00a9 2026 Gary McAvoy. Alle Rechte vorbehalten.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"iawp_total_views":2,"footnotes":""},"class_list":["post-15995","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/pages\/15995","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/comments?post=15995"}],"version-history":[{"count":1,"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/pages\/15995\/revisions"}],"predecessor-version":[{"id":15996,"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/pages\/15995\/revisions\/15996"}],"wp:attachment":[{"href":"https:\/\/garymcavoy.com\/de\/wp-json\/wp\/v2\/media?parent=15995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}