diff --git a/internal/check-packet-render.mjs b/internal/check-packet-render.mjs index 87fb02742..31aa433a4 100644 --- a/internal/check-packet-render.mjs +++ b/internal/check-packet-render.mjs @@ -117,8 +117,11 @@ const layout = await page.evaluate(() => { const tb = rng.getBoundingClientRect() if (tb.width < 20 || box.width < 50 || box.width - tb.width < 12) continue if (cs.direction === 'rtl') out.rtlComputed += 1 - if (Math.round(box.right - tb.right) <= 1) out.pinnedRight += 1 - else if (Math.round(tb.left - box.left) <= 1) out.pinnedLeft += 1 + // Against the CONTENT box: a padded table cell (the pace table's) starts its run at its padding, which is + // still the left (or right) edge the direction pins it to. + const pl = parseFloat(cs.paddingLeft) || 0, pr = parseFloat(cs.paddingRight) || 0 + if (Math.round(box.right - pr - tb.right) <= 1) out.pinnedRight += 1 + else if (Math.round(tb.left - box.left - pl) <= 1) out.pinnedLeft += 1 out.sampled += 1 if (out.sampled >= 25) break } @@ -252,6 +255,8 @@ const r = await page.evaluate(() => { christianSheets: document.querySelectorAll('.sheet-christian').length, lifeCells: document.querySelectorAll('.lc-frame .lc-c').length, prayBoxes: document.querySelectorAll('.pray-box').length, + fdTopOver: (() => { const b = document.querySelector('.fd-top'); if (!b) return 0; const top = b.getBoundingClientRect().top + return Math.round(Math.max(0, ...[...b.children].map((k) => k.getBoundingClientRect().bottom + parseFloat(getComputedStyle(k).marginBottom))) - top - b.clientHeight) })(), funnelTip: document.querySelectorAll('.funnel-tip').length, lifeShaded: document.querySelectorAll('.lc-frame .lc-reached').length, // ★ FILLED FROM THE TOP, in reading order (the packet's design), measured on the DOM order of the cells: @@ -730,17 +735,24 @@ if (!boxes.length) { // sheets — a 100-year life in weeks, then the SAME grid shaded by the evangelical share of these // groups' population — so they are DETECTED and added as known terms for exactly the reason the // funnel was, and for the reason stated above: a tolerance here would hide a dropped list page. -const PER_PAGE = 20 +// THE PAGE SIZES ARE THE RENDERER'S, read from it rather than retyped: the first list page of each packet +// gives rows to the explanation band (2026-10-02), so a typed number drifted the moment the band changed. +const { createPacketRenderer: makeR } = await import(resolve(dirname(fileURLToPath(import.meta.url)), '../library/packet/packet-render.js')) +const RR = makeR({ strings: catalog, lang: 'en' }) +const PER_PAGE = RR.PER_PAGE const funnelSheets = r.funnel ? 1 : 0 const lifeSheets = (r.lifeSheets || 0) + (r.christianSheets || 0) // ⚠ AND THE SETS PAGES (bounded, centered): back matter, DETECTED for the same reason as the rest. // Before they were counted the arithmetic only held when a fixture omitted set data. const setsSheets = r.setsSheets || 0 -// The worksheet paginates 11 rows on its first page and 18 after (packet-render WS_FIRST / WS_REST; the first page -// gave five rows to its description and pace table on 2026-10-02; 20 and 24 -// before its rows gained a photo and a description, 2026-09-30). -const wsPages = (n) => (n <= 0 ? 0 : 1 + Math.ceil(Math.max(0, n - 11) / 18)) -const listSheets = r.cards ? Math.ceil(r.cards / PER_PAGE) : wsPages(r.wsRows) +// Both lists give their first page to the explanation band: the worksheet holds WS_FIRST rows there and +// WS_REST after; the profile pages FD_FIRST, then PER_PAGE. +const wsPages = (n) => (n <= 0 ? 0 : 1 + Math.ceil(Math.max(0, n - RR.WS_FIRST) / RR.WS_REST)) +const fdPages = (n) => (n <= 0 ? 0 : 1 + Math.ceil(Math.max(0, n - RR.FD_FIRST) / PER_PAGE)) +const listSheets = r.cards ? fdPages(r.cards) : wsPages(r.wsRows) +// The Full detail's first page reserves a block for the explanation and CLIPS what outgrows it (rather than +// let it overlap the rows): only a measurement sees a clipped line, so measure it. +if (r.fdTopOver > 0) fails.push(`the Full detail's explanation block outgrows its reserved height by ${r.fdTopOver}px — text is clipped (raise FD_TOP_H)`) if (r.wsRows && r.wsSheets !== wsPages(r.wsRows)) fails.push(`${r.wsRows} worksheet rows should take ${wsPages(r.wsRows)} page(s) but the packet has ${r.wsSheets}`) // + 2 again (2026-09-30, the second revision): point 4's Mark 5:18-20 and the Father's-heart list are back ON the // points page, so the back matter is the wheel and the points. diff --git a/internal/check-packet-variants.mjs b/internal/check-packet-variants.mjs index 781981a9d..66f55da3a 100644 --- a/internal/check-packet-variants.mjs +++ b/internal/check-packet-variants.mjs @@ -97,7 +97,7 @@ ok(count(light, /sheet-sets-(bounded|centered)/g) === 0, 'lightweight still carr // ⚠ THE DELTA IS DERIVED, never relaxed into a range: lightweight drops four back pages (life, % grid, // bounded, centered) AND lists the same people as a worksheet, whose pages hold more rows than profiles. { - const profilePages = Math.ceil(45 / R.PER_PAGE) + const profilePages = 1 + Math.ceil(Math.max(0, 45 - R.FD_FIRST) / R.PER_PAGE) const worksheetPages = count(light, /
]+>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 200)}`)
- ok(!/no pace to keep/.test(light), 'the lightweight list should no longer say there is no pace to keep')
- ok(count(light, /class="ws-box"/g) === 45 * 3, `every worksheet row should carry three tally cells, got ${count(light, /class="ws-box"/g)}`)
+ const band = html.indexOf('
${esc(t('pace_note'))} ${esc(t('light_intro'))} +${esc(t('howto_bless'))} +${esc(t('blessing_text'))}${esc(t('blessing_credit'))}+ ${esc(t('howto_bless_more'))} ${refs}
+ ${esc(t('howto_wheel'))} ${esc(t(p.key))} | `
+ + `${esc(t(p.word))} | ${esc(paceLoad(n, p.days))} | ${esc(t('pace_title'))}
+ ${esc(t('pace_lead'))} ${esc(t('pace_note'))} ${esc(t('howto_title'))}
+
${esc(t('example_title'))}
+ ${PRAY_COLS.map((k) => `${esc(t(k))}`).join('')}
+ ${[7, 3, 2].map((m) => `${tallySvg(m)}`).join('')}
+ ${esc(t('example_note'))} ${esc(zone.label || zone.id)}
${esc(fill(t('map_page_sub'), { count: num(groups.length) }))}${esc(t('light_intro'))} ${worksheetHowTo(groups.length)}` + ${explainTop()}${explainBand(groups.length, { w: PRAY_COLS.length * WS_TALLY_W + (PRAY_COLS.length - 1) * 8, + cols: `repeat(${PRAY_COLS.length},${WS_TALLY_W}px)`, gap: 8, cell: 'xb-cell xb-cell-ws' })}` : `${esc(zone.label || zone.id)}${esc(fill(t('list_header'),
{ from: num(start + 1), to: num(Math.min(start + per, groups.length)), count: num(groups.length) }))} `;
pages.push(sheet(`${top}${head}${rows}${esc(t('privacy_note'))} `, 'sheet-worksheet sheet-flow'));
@@ -1653,5 +1727,5 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
// VARIANTS is exported so the UI enumerates the packets it can print instead of hardcoding two
// strings in a menu — add a third variant here and the caret gains an entry with no UI change.
- return { buildPacket, mapPage, lifePage, christianPage, funnelPage, listPages, pointsPage, wheelPage, css, mapCss, liftMap, mapFromImage, mapSheetFiles, PER_PAGE, W, H, VARIANTS };
+ return { buildPacket, mapPage, lifePage, christianPage, funnelPage, listPages, pointsPage, wheelPage, css, mapCss, liftMap, mapFromImage, mapSheetFiles, PER_PAGE, FD_FIRST, WS_FIRST, WS_REST, W, H, VARIANTS };
}
diff --git a/library/scripts/posters/packet-strings.json b/library/scripts/posters/packet-strings.json
index da826257a..625fd45c7 100644
--- a/library/scripts/posters/packet-strings.json
+++ b/library/scripts/posters/packet-strings.json
@@ -318,7 +318,10 @@
"pace_month": "about {n} a month",
"pace_note": "Praying for every group daily is for gifted intercessors who give about three hours a day to prayer. For most of us, weekly is a healthy, steady pace.",
"blessing_text": "“The LORD bless you, and keep you. The LORD make his face to shine on you, and be gracious to you. The LORD lift up his face towards you, and give you peace.”",
- "blessing_credit": "Numbers 6:24–26 · World English Bible, British Edition (public domain) · ebible.org"
+ "blessing_credit": "Numbers 6:24–26 · World English Bible, British Edition (public domain) · ebible.org",
+ "howto_bless_col": "Bless them by name, with the blessing above or another from Scripture.",
+ "example_title": "Example",
+ "example_note": "One mark each time you pray it; the fifth mark crosses the four before it."
},
"es": {
"map_page_kicker": "GRUPOS ÉTNICOS NO EVANGELIZADOS",
@@ -623,7 +626,10 @@
"pace_month": "unos {n} al mes",
"pace_note": "Orar cada día por todos los pueblos es para intercesores con ese don, que dedican unas tres horas diarias a la oración. Para la mayoría de nosotros, cada semana es un ritmo sano y constante.",
"blessing_text": "«Jehová te bendiga, y te guarde: Haga resplandecer Jehová su rostro sobre ti, y haya de ti misericordia: Jehová alce á ti su rostro, y ponga en ti paz.»",
- "blessing_credit": "Números 6:24–26 · Reina Valera 1909 (dominio público) · ebible.org"
+ "blessing_credit": "Números 6:24–26 · Reina Valera 1909 (dominio público) · ebible.org",
+ "howto_bless_col": "Bendícelos por su nombre, con la bendición de arriba u otra de las Escrituras.",
+ "example_title": "Ejemplo",
+ "example_note": "Una marca cada vez que lo ores; la quinta cruza las cuatro anteriores."
},
"fr": {
"map_page_kicker": "GROUPES ETHNIQUES NON ATTEINTS",
@@ -928,7 +934,10 @@
"pace_month": "environ {n} par mois",
"pace_note": "Prier chaque jour pour tous ces peuples convient aux intercesseurs qui en ont reçu le don et consacrent environ trois heures par jour à la prière. Pour la plupart d’entre nous, chaque semaine est un rythme sain et régulier.",
"blessing_text": "« L'Éternel te bénisse et te garde! L'Éternel fasse luire sa face sur toi et te fasse grâce! L'Éternel tourne sa face vers toi et te donne la paix! »",
- "blessing_credit": "Nombres 6:24–26 · French Ostervald Bible (domaine public) · ebible.org"
+ "blessing_credit": "Nombres 6:24–26 · French Ostervald Bible (domaine public) · ebible.org",
+ "howto_bless_col": "Bénissez-les par leur nom, avec la bénédiction ci-dessus ou une autre tirée des Écritures.",
+ "example_title": "Exemple",
+ "example_note": "Un trait chaque fois que vous le priez ; le cinquième barre les quatre précédents."
},
"pt": {
"map_page_kicker": "GRUPOS ÉTNICOS NÃO ALCANÇADOS",
@@ -1230,7 +1239,10 @@
"pace_month": "cerca de {n} por mês",
"pace_note": "Orar todo dia por todos os povos é para intercessores com esse dom, que dedicam cerca de três horas por dia à oração. Para a maioria de nós, toda semana é um ritmo saudável e constante.",
"blessing_text": "“Yahweh te abençoe, e te guarde. Yahweh faz o seu rosto para brilhar em você, e seja gracioso com você. Yahweh levanta o rosto na sua direção, e lhe dar paz.”",
- "blessing_credit": "Números 6:24–26 · World Portuguese Bible (domínio público) · ebible.org"
+ "blessing_credit": "Números 6:24–26 · World Portuguese Bible (domínio público) · ebible.org",
+ "howto_bless_col": "Abençoe-os pelo nome, com a bênção acima ou outra das Escrituras.",
+ "example_title": "Exemplo",
+ "example_note": "Um risco cada vez que você orar; o quinto cruza os quatro anteriores."
},
"de": {
"map_page_kicker": "UNERREICHTE VOLKSGRUPPEN",
@@ -1535,7 +1547,10 @@
"pace_month": "etwa {n} im Monat",
"pace_note": "Täglich für jede Volksgruppe zu beten ist für begabte Fürbitter, die dem Gebet etwa drei Stunden am Tag widmen. Für die meisten von uns ist wöchentlich ein gesunder, beständiger Rhythmus.",
"blessing_text": "„Der HERR segne dich und behüte dich; der HERR lasse sein Angesicht leuchten über dir und sei dir gnädig; der HERR hebe sein Angesicht über dich und gebe dir Frieden.“",
- "blessing_credit": "4. Mose 6,24–26 · German Luther Bible 1912 (gemeinfrei) · ebible.org"
+ "blessing_credit": "4. Mose 6,24–26 · German Luther Bible 1912 (gemeinfrei) · ebible.org",
+ "howto_bless_col": "Segnen Sie sie mit Namen, mit dem Segen oben oder einem anderen aus der Schrift.",
+ "example_title": "Beispiel",
+ "example_note": "Ein Strich für jedes Gebet; der fünfte Strich kreuzt die vier davor."
},
"it": {
"map_page_kicker": "GRUPPI ETNICI NON RAGGIUNTI",
@@ -1837,7 +1852,10 @@
"pace_month": "circa {n} al mese",
"pace_note": "Pregare ogni giorno per tutti i popoli è per gli intercessori che ne hanno il dono e dedicano circa tre ore al giorno alla preghiera. Per la maggior parte di noi, ogni settimana è un ritmo sano e costante.",
"blessing_text": "«Il Signore ti benedica e ti guardi. Il Signore faccia risplendere le sua faccia verso te, e ti sia propizio. Alzi il Signore la sua faccia verso te, e ti stabilisca la pace.»",
- "blessing_credit": "Numeri 6:24–26 · Italian Diodati Bible (pubblico dominio) · ebible.org"
+ "blessing_credit": "Numeri 6:24–26 · Italian Diodati Bible (pubblico dominio) · ebible.org",
+ "howto_bless_col": "Benedicili chiamandoli per nome, con la benedizione qui sopra o un'altra dalle Scritture.",
+ "example_title": "Esempio",
+ "example_note": "Un trattino ogni volta che lo preghi; il quinto attraversa i quattro precedenti."
},
"ro": {
"map_page_kicker": "GRUPURI ETNICE NEATINSE",
@@ -2137,7 +2155,10 @@
"pace_day": "cam {n} pe zi",
"pace_week": "cam {n} pe săptămână",
"pace_month": "cam {n} pe lună",
- "pace_note": "Rugăciunea zilnică pentru toate popoarele este pentru mijlocitorii care au acest dar și dedică rugăciunii cam trei ore pe zi. Pentru cei mai mulți dintre noi, săptămânal este un ritm sănătos și constant."
+ "pace_note": "Rugăciunea zilnică pentru toate popoarele este pentru mijlocitorii care au acest dar și dedică rugăciunii cam trei ore pe zi. Pentru cei mai mulți dintre noi, săptămânal este un ritm sănătos și constant.",
+ "howto_bless_col": "Binecuvântează-i pe nume, cu binecuvântarea de mai sus sau cu alta din Scriptură.",
+ "example_title": "Exemplu",
+ "example_note": "O liniuță de fiecare dată când te rogi; a cincea le taie pe cele patru dinainte."
},
"ru": {
"map_page_kicker": "НЕОХВАЧЕННЫЕ НАРОДЫ",
@@ -2449,7 +2470,10 @@
"Psalm 28:11",
"Psalm 120:7",
"Genesis 12:3"
- ]
+ ],
+ "howto_bless_col": "Благословляйте их по имени — словами выше или другими словами из Писания.",
+ "example_title": "Пример",
+ "example_note": "Одна черточка за каждую молитву; пятая перечёркивает четыре предыдущие."
},
"ar": {
"map_page_kicker": "شعوب غير مبلَّغة",
@@ -2754,7 +2778,10 @@
"pace_month": "نحو {n} في الشهر",
"pace_note": "الصلاة اليومية لأجل كل الشعوب للمتشفّعين الذين نالوا هذه الموهبة ويخصّصون للصلاة نحو ثلاث ساعات يوميًا. ولمعظمنا، الصلاة الأسبوعية إيقاع صحّي وثابت.",
"blessing_text": "«يُبَارِكُكَ الرَّبُّ وَيَحْرُسُكَ. يُضِيءُ الرَّبُّ بِوَجْهِهِ عَلَيْكَ وَيَرْحَمُكَ. يَرْفَعُ الرَّبُّ وَجْهَهُ عَلَيْكَ وَيَمْنَحُكَ سَلَامًا.»",
- "blessing_credit": "العدد ٦:٢٤–٢٦ · Arabic Van Dyck Bible (ملك عام) · ebible.org"
+ "blessing_credit": "العدد ٦:٢٤–٢٦ · Arabic Van Dyck Bible (ملك عام) · ebible.org",
+ "howto_bless_col": "باركهم بأسمائهم، بالبركة التي في الأعلى أو بغيرها من الكتاب المقدس.",
+ "example_title": "مثال",
+ "example_note": "خطّ واحد كلما صلّيت؛ والخطّ الخامس يقطع الأربعة التي قبله."
},
"hi": {
"map_page_kicker": "अनछुए जनसमूह",
@@ -3054,7 +3081,10 @@
"pace_day": "लगभग {n} प्रतिदिन",
"pace_week": "लगभग {n} प्रति सप्ताह",
"pace_month": "लगभग {n} प्रति माह",
- "pace_note": "हर जनसमूह के लिए प्रतिदिन प्रार्थना उन मध्यस्थों के लिए है जिन्हें यह वरदान मिला है और जो प्रार्थना में दिन के लगभग तीन घंटे लगाते हैं। हममें से अधिकांश के लिए साप्ताहिक प्रार्थना एक स्वस्थ, स्थिर गति है।"
+ "pace_note": "हर जनसमूह के लिए प्रतिदिन प्रार्थना उन मध्यस्थों के लिए है जिन्हें यह वरदान मिला है और जो प्रार्थना में दिन के लगभग तीन घंटे लगाते हैं। हममें से अधिकांश के लिए साप्ताहिक प्रार्थना एक स्वस्थ, स्थिर गति है।",
+ "howto_bless_col": "उनके नाम लेकर उन्हें आशीष दें — ऊपर दी गई आशीष से या पवित्रशास्त्र की किसी और आशीष से।",
+ "example_title": "उदाहरण",
+ "example_note": "हर बार प्रार्थना करने पर एक लकीर; पाँचवीं लकीर पिछली चार को काटती है।"
},
"zh": {
"map_page_kicker": "未得之民",
@@ -3356,6 +3386,9 @@
"pace_month": "每月约 {n} 个",
"pace_note": "每天为每一个族群祷告,适合有代祷恩赐、每天约用三小时祷告的人。对我们大多数人来说,每周一次是健康而稳定的节奏。",
"blessing_text": "“愿耶和华赐福给你,保护你。愿耶和华使他的脸光照你,赐恩给你。愿耶和华向你仰脸,赐你平安。”",
- "blessing_credit": "民数记 6:24–26 · Chinese Union Version (公有领域) · ebible.org"
+ "blessing_credit": "民数记 6:24–26 · Chinese Union Version (公有领域) · ebible.org",
+ "howto_bless_col": "按着名字祝福他们,可以用上面的祝福,或圣经中的其他祝福。",
+ "example_title": "示例",
+ "example_note": "每祷告一次画一道;第五道横穿前面四道。"
}
}
|
|---|