From eb45fba466dc8d25ea76a585ea3dee425fdeeccf Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Tue, 1 Sep 2026 07:40:13 +0100 Subject: [PATCH 1/2] feat(templates): add the Payments paginating invoice preset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A lavender-and-navy invoice: a diagonal band crossing the masthead, a half-split issuer and metadata header, two addressed parties on discs, a marked service-line table, a settlement row pairing bank details against the totals, a note block and a two-cell document footer. Ships as invoice.presets.PaymentsInvoice on the existing StructuredInvoiceData model. It is the first preset in the family built to flow: the table's header repeats on every page it reaches, a continuation page reserves a deeper bottom margin than page one, and every page carries its number. The table is one column, not five. The design shows an outer box and a rule between rows with no interior verticals, which is exactly what a single-column table draws; the five columns are a row inside each cell. The other construction would leave every continuation page ending in an empty bordered strip, because a section's box fills its page fragment rather than hugging its rows. The lockup beside the title is the caller's — a logo drawn to the design's measured height, or the brand's name as a wordmark. Figures are written with the locale stated rather than inherited, because both the grouping of a number and the symbol for a currency code change with it. Guarded by a 15-case smoke test, an exact layout snapshot and a pixel-parity gate. --- CHANGELOG.md | 29 + .../readme/examples/invoice-payments-v2.pdf | Bin 0 -> 32645 bytes .../demcha/examples/GenerateAllExamples.java | 2 + .../support/PaymentsInvoiceSampleData.java | 156 + .../examples/support/ShowcaseMetadata.java | 1 + .../invoice/v2/PaymentsInvoiceV2Example.java | 54 + .../presets/PaymentsInvoiceFixtures.java | 154 + .../PaymentsInvoiceLayoutSnapshotTest.java | 33 + .../presets/PaymentsInvoiceSmokeTest.java | 268 + .../PaymentsInvoiceVisualParityTest.java | 41 + .../invoice/payments_invoice_layout.json | 5357 +++++++++++++++++ .../payments_invoice-page-0.png | Bin 0 -> 100748 bytes .../invoice/presets/PaymentsClosing.java | 289 + .../invoice/presets/PaymentsIcons.java | 94 + .../invoice/presets/PaymentsInvoice.java | 167 + .../invoice/presets/PaymentsLines.java | 237 + .../invoice/presets/PaymentsMasthead.java | 319 + .../invoice/presets/PaymentsParties.java | 127 + .../invoice/presets/PaymentsSettlement.java | 273 + .../invoice/presets/PaymentsStyles.java | 456 ++ .../invoice/presets/PaymentsText.java | 62 + .../invoice/presets/PaymentsWidgets.java | 129 + .../templates/invoice/payments/icons/bank.svg | 1 + .../invoice/payments/icons/bill-to.svg | 1 + .../invoice/payments/icons/calendar.svg | 1 + .../invoice/payments/icons/card-settings.svg | 1 + .../templates/invoice/payments/icons/card.svg | 1 + .../invoice/payments/icons/document.svg | 1 + .../invoice/payments/icons/globe.svg | 1 + .../invoice/payments/icons/headset.svg | 1 + .../invoice/payments/icons/mobile.svg | 1 + .../invoice/payments/icons/shield.svg | 1 + .../invoice/payments/icons/ship-to.svg | 1 + .../invoice/payments/icons/support.svg | 1 + 34 files changed, 8260 insertions(+) create mode 100644 assets/readme/examples/invoice-payments-v2.pdf create mode 100644 examples/src/main/java/com/demcha/examples/support/PaymentsInvoiceSampleData.java create mode 100644 examples/src/main/java/com/demcha/examples/templates/invoice/v2/PaymentsInvoiceV2Example.java create mode 100644 qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceFixtures.java create mode 100644 qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceLayoutSnapshotTest.java create mode 100644 qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceSmokeTest.java create mode 100644 qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceVisualParityTest.java create mode 100644 qa/src/test/resources/layout-snapshots/canonical-templates/invoice/payments_invoice_layout.json create mode 100644 qa/src/test/resources/visual-baselines/invoice-v2-layered/payments_invoice-page-0.png create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsClosing.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsIcons.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoice.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsLines.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsMasthead.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsParties.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsSettlement.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsStyles.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsText.java create mode 100644 templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsWidgets.java create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/bank.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/bill-to.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/calendar.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/card-settings.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/card.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/document.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/globe.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/headset.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/mobile.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/shield.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/ship-to.svg create mode 100644 templates/src/main/resources/templates/invoice/payments/icons/support.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 693f4b206..984bb6b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,35 @@ follow semantic versioning; release dates are ISO 8601. ### Templates +- **A paginating invoice preset: `PaymentsInvoice`.** A lavender-and-navy sheet with a + diagonal band crossing the masthead, a half-split issuer and metadata header, two + addressed parties on discs, a marked service-line table, a settlement row pairing bank + details against the totals, a note block and a two-cell document footer. Ships as + `invoice.presets.PaymentsInvoice` on the existing `StructuredInvoiceData` model, + porting the rendered layout of a published standalone template. It is the first preset + in the family built to **flow**: the design shows six service lines and a real billing + month brings dozens, so the table's header repeats on every page it reaches, a + continuation page reserves a deeper bottom margin than page one, and every page + carries its number — a financial record that runs over has to make a missing page + detectable. The table is one column, not five: the design shows an outer box and a + rule between rows with no interior verticals, which is exactly what a single-column + table draws, and the five columns are a row inside each cell. Building it the other + way round would leave every continuation page ending in an empty bordered strip, + because a section's box fills its page fragment rather than hugging its rows. The + lockup beside the title is the caller's: the design's mark occupies a measured + 136 × 55.3 px box, a document that brings a logo has it drawn to that height, and one + that brings only a name has the name set as a wordmark — the templates artifact + carries no mark of its own. Figures are written with the locale stated rather than + inherited, because both the grouping of a number and the symbol for a currency code + change with it and a preset that let the JVM decide would render a different sheet on + a different machine. Guarded by a smoke test (including the unknown-mark data error, a + line with no mark, the wordmark fallback, the currency named once and carried, the + uppercased due line, a trunk prefix printed but not dialled, the support contacts as + annotations, a missing ship-to and a missing note block, an empty document, and a + thirty-line invoice that runs on, repeats its column names and numbers its pages), an + exact layout snapshot and a pixel-parity gate; the examples showcase gains + `invoice-payments-v2`. + - **A navy-plate CV preset: `MidnightNavy`.** A one-page sheet on a full-height navy plate: an outlined monogram over a two-weight name and a tracked role line, then contact, education, metered skills and dotted languages down the plate, beside a diff --git a/assets/readme/examples/invoice-payments-v2.pdf b/assets/readme/examples/invoice-payments-v2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..043843ec7f08bf45c73d02f6fc3a1247c51857e0 GIT binary patch literal 32645 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

_0ug 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 W$<5*S5*Zm7=-D8NiG^iFApaLGNqM6H literal 0 HcmV?d00001 diff --git a/examples/src/main/java/com/demcha/examples/GenerateAllExamples.java b/examples/src/main/java/com/demcha/examples/GenerateAllExamples.java index 9a7049ba2..54f713e62 100644 --- a/examples/src/main/java/com/demcha/examples/GenerateAllExamples.java +++ b/examples/src/main/java/com/demcha/examples/GenerateAllExamples.java @@ -109,6 +109,7 @@ import com.demcha.examples.templates.invoice.ClassicInvoiceV2Example; import com.demcha.examples.templates.invoice.ConsultingInvoiceV2Example; import com.demcha.examples.templates.invoice.LumaStudioInvoiceV2Example; +import com.demcha.examples.templates.invoice.PaymentsInvoiceV2Example; import com.demcha.examples.templates.invoice.InvoiceCinematicFileExample; import com.demcha.examples.templates.invoice.ModernInvoiceV2Example; import com.demcha.examples.templates.proposal.CinematicProposalFileExample; @@ -190,6 +191,7 @@ public static void main(String[] args) throws Exception { System.out.println("Generated: " + ClassicInvoiceV2Example.generate()); System.out.println("Generated: " + ConsultingInvoiceV2Example.generate()); System.out.println("Generated: " + LumaStudioInvoiceV2Example.generate()); + System.out.println("Generated: " + PaymentsInvoiceV2Example.generate()); // Proposals System.out.println("Generated: " + ProposalCinematicFileExample.generate()); diff --git a/examples/src/main/java/com/demcha/examples/support/PaymentsInvoiceSampleData.java b/examples/src/main/java/com/demcha/examples/support/PaymentsInvoiceSampleData.java new file mode 100644 index 000000000..3f786c57e --- /dev/null +++ b/examples/src/main/java/com/demcha/examples/support/PaymentsInvoiceSampleData.java @@ -0,0 +1,156 @@ +package com.demcha.examples.support; + +import com.demcha.compose.document.templates.data.invoice.InvoiceBrand; +import com.demcha.compose.document.templates.data.invoice.InvoiceContactBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceMasthead; +import com.demcha.compose.document.templates.data.invoice.InvoiceNotesBlock; +import com.demcha.compose.document.templates.data.invoice.InvoicePaymentBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceRecipient; +import com.demcha.compose.document.templates.data.invoice.InvoiceServiceLines; +import com.demcha.compose.document.templates.data.invoice.InvoiceSummaryBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceTotalsBlock; +import com.demcha.compose.document.templates.data.invoice.StructuredInvoiceData; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * Shared sample data for the Payments invoice example. + * + *

Kept in lockstep with the qa module's {@code PaymentsInvoiceFixtures} — the + * two modules cannot share a source file, so a content change here belongs + * there too.

+ */ +public final class PaymentsInvoiceSampleData { + + private PaymentsInvoiceSampleData() { + } + + /** + * The sample invoice — seven metadata rows, two addressed parties, six + * marked service lines, seven payment fields, two summed rows and a + * two-line note. + * + * @return the document the example renders + */ + public static StructuredInvoiceData sample() { + return new StructuredInvoiceData( + brand(), supplier(), masthead(), billTo(), shipTo(), + new InvoiceSummaryBlock("", "", ""), + serviceLines(), totals(), payment(), notes(), "GBP"); + } + + /** No logo: the wordmark is what a document without one falls back to. */ + private static InvoiceBrand brand() { + return new InvoiceBrand(null, "Meridian", "", "", "", ""); + } + + private static InvoiceContactBlock supplier() { + return new InvoiceContactBlock( + "Meridian Payments Ltd.", + List.of("1 Harbour Exchange", "Canary Wharf", "London E14 9GE", + "United Kingdom"), + "", "", "", + "", "Company No. 09048900", + "", "VAT No. GB 123 4567 89"); + } + + private static InvoiceMasthead masthead() { + List entries = new ArrayList<>(); + entries.add(new InvoiceMasthead.Entry("Invoice Number", "INV-2025-05-10472", false)); + entries.add(new InvoiceMasthead.Entry("Invoice Date", "10 May 2025", false)); + entries.add(new InvoiceMasthead.Entry("Billing Period", "1 - 30 April 2025", false)); + entries.add(new InvoiceMasthead.Entry("Account ID", "acct_4Q8xTb2mKp", false)); + entries.add(new InvoiceMasthead.Entry("Payment Terms", "Net 30", false)); + entries.add(new InvoiceMasthead.Entry("Due Date", "14 June 2025", false)); + entries.add(new InvoiceMasthead.Entry("Status", "UNPAID", true)); + return new InvoiceMasthead("INVOICE", entries); + } + + /** The subline is where a billed party's registration goes on this sheet. */ + private static InvoiceRecipient billTo() { + return new InvoiceRecipient("BILL TO", "Northwind Ltd.", + "VAT No. GB 987 6543 21", + List.of("Attention: Finance Team", "42 Bridgewater Street", + "Manchester M15 4QT", "United Kingdom"), + "", ""); + } + + private static InvoiceRecipient shipTo() { + return new InvoiceRecipient("SHIP TO", "Northwind Ltd.", "", + List.of("Operations Centre", "7 Kingsway Park", + "Leeds LS12 6BD", "United Kingdom"), + "", ""); + } + + private static InvoiceServiceLines serviceLines() { + InvoiceServiceLines.Columns columns = new InvoiceServiceLines.Columns( + "", "DESCRIPTION", "", "QUANTITY", "UNIT PRICE", "AMOUNT", "VAT"); + List lines = new ArrayList<>(); + lines.add(line(1, "Subscription Billing", + "Subscription management and recurring billing", + "1", "250.00", "250.00", "20%", "card")); + lines.add(line(2, "Payment Processing", + "Online card payments processing (volume tier)", + "1", "1,180.00", "1,180.00", "20%", "card-settings")); + lines.add(line(3, "Fraud Screening", + "Advanced fraud screening and rules", + "1", "320.00", "320.00", "20%", "shield")); + lines.add(line(4, "Company Formation", + "Incorporation and compliance filings", + "1", "180.00", "180.00", "20%", "globe")); + lines.add(line(5, "In-Person Terminals", + "Terminal rental and firmware updates", + "4", "39.00", "156.00", "20%", "mobile")); + lines.add(line(6, "Priority Support", + "Named engineer, one-hour response", + "1", "100.00", "100.00", "20%", "headset")); + return new InvoiceServiceLines(columns, lines); + } + + private static InvoiceServiceLines.Line line(int number, String title, String description, + String quantity, String unitPrice, + String amount, String vat, String icon) { + return new InvoiceServiceLines.Line(number, title, description, "", + decimal(quantity), "", decimal(unitPrice), decimal(amount), vat, icon); + } + + private static InvoiceTotalsBlock totals() { + List rows = new ArrayList<>(); + rows.add(new InvoiceTotalsBlock.Row("Subtotal (excl. VAT)", decimal("2,186.00"))); + rows.add(new InvoiceTotalsBlock.Row("VAT at 20%", decimal("437.20"))); + return new InvoiceTotalsBlock(rows, "TOTAL DUE", decimal("2,623.20")); + } + + private static InvoicePaymentBlock payment() { + List fields = new ArrayList<>(); + fields.add(new InvoicePaymentBlock.Field("Bank Name", "Harbour Bank plc")); + fields.add(new InvoicePaymentBlock.Field("Account Name", "Meridian Payments Ltd.")); + fields.add(new InvoicePaymentBlock.Field("Sort Code", "40-02-50")); + fields.add(new InvoicePaymentBlock.Field("Account Number", "71295408")); + fields.add(new InvoicePaymentBlock.Field("IBAN", "GB29 HRBK 4002 5071 2954 08")); + fields.add(new InvoicePaymentBlock.Field("SWIFT / BIC", "HRBKGB2L")); + fields.add(new InvoicePaymentBlock.Field("Reference", "INV-2025-05-10472")); + return new InvoicePaymentBlock("PAYMENT DETAILS", fields, + "Please include the invoice number as payment reference.", + "Due by 14 June 2025", + "Payment due by 14 June 2025", + "", + "Questions? We're here to help."); + } + + private static InvoiceNotesBlock notes() { + return new InvoiceNotesBlock("NOTES", + List.of("Thank you for your business. This invoice covers services and " + + "fees for the period stated above.", + "Late payment may incur interest at the statutory rate."), + "support@meridianpayments.example", + "+44 (0) 20 3966 1900"); + } + + /** A printed figure back to a number: the grouping comes off. */ + private static BigDecimal decimal(String printed) { + return new BigDecimal(printed.replace(",", "")); + } +} diff --git a/examples/src/main/java/com/demcha/examples/support/ShowcaseMetadata.java b/examples/src/main/java/com/demcha/examples/support/ShowcaseMetadata.java index 554b07dc5..98e18d416 100644 --- a/examples/src/main/java/com/demcha/examples/support/ShowcaseMetadata.java +++ b/examples/src/main/java/com/demcha/examples/support/ShowcaseMetadata.java @@ -99,6 +99,7 @@ record Entry(String title, String description, List tags, String codeUrl invoice("invoice-cinematic", "InvoiceCinematicFileExample", "Cinematic Invoice", "Layered ModernInvoice preset with theme-driven layout, advanced tables, and totals.", "invoice", "cinematic"); invoice("invoice-consulting-v2", "v2/ConsultingInvoiceV2Example", "Consulting Invoice", "The ConsultingInvoice preset on the structured invoice model — brand lockup with the caller's logo, labelled masthead metadata, priced service lines with service periods, a totals stack and bank payment fields.", "invoice"); invoice("invoice-luma-studio-v2", "v2/LumaStudioInvoiceV2Example", "Luma Studio Invoice", "The LumaStudioInvoice preset on the structured invoice model — a cream sidebar carrying the brand lockup and its ornament, a billed-to / shipped-to pair, priced service lines with a VAT column, and the notes and bank details above a sign-off band.", "invoice"); + invoice("invoice-payments-v2", "v2/PaymentsInvoiceV2Example", "Payments Invoice", "The PaymentsInvoice preset on the structured invoice model — a diagonal band crossing the masthead, a half-split issuer and metadata header, two addressed parties, marked service lines that repeat their header across pages, and a settlement row pairing bank details against the totals.", "invoice"); invoice("invoice-modern-v2", "v2/ModernInvoiceV2Example", "Modern Invoice", "The ModernInvoice preset composed straight from an InvoiceDocumentSpec — line items, totals and payment block driven by the BrandTheme rather than per-document styling.", "invoice"); invoice("invoice-classic-v2", "v2/ClassicInvoiceV2Example", "Classic Invoice", "The ClassicInvoice preset — letterhead header band, TOTAL DUE hero strip, BILL TO / FROM columns, and a dedicated Summary table after the line items.", "invoice"); diff --git a/examples/src/main/java/com/demcha/examples/templates/invoice/v2/PaymentsInvoiceV2Example.java b/examples/src/main/java/com/demcha/examples/templates/invoice/v2/PaymentsInvoiceV2Example.java new file mode 100644 index 000000000..278ac8ad1 --- /dev/null +++ b/examples/src/main/java/com/demcha/examples/templates/invoice/v2/PaymentsInvoiceV2Example.java @@ -0,0 +1,54 @@ +package com.demcha.examples.templates.invoice; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.templates.api.DocumentTemplate; +import com.demcha.compose.document.templates.data.invoice.StructuredInvoiceData; +import com.demcha.compose.document.templates.invoice.presets.PaymentsInvoice; +import com.demcha.examples.support.ExampleOutputPaths; +import com.demcha.examples.support.PaymentsInvoiceSampleData; + +import java.nio.file.Path; + +/** + * Renders the layered {@code invoice.v2} Payments preset against the design + * sample. + * + *

Output: + * {@code examples/target/generated-pdfs/templates/invoice/invoice-payments-v2.pdf}.

+ * + *

The preset owns its page geometry and its pagination — the table's header + * repeats and a continuation page reserves a deeper bottom margin — so the + * session starts unconfigured. The sample brings no logo, so the lockup box + * beside the title is filled with the brand's name as a wordmark.

+ */ +public final class PaymentsInvoiceV2Example { + + private PaymentsInvoiceV2Example() { + } + + /** + * @return absolute path of the rendered PDF + * @throws Exception if rendering fails + */ + public static Path generate() throws Exception { + Path outputFile = ExampleOutputPaths.prepare("templates/invoice", + "invoice-payments-v2.pdf"); + StructuredInvoiceData data = PaymentsInvoiceSampleData.sample(); + DocumentTemplate template = PaymentsInvoice.create(); + + try (DocumentSession document = GraphCompose.document(outputFile).create()) { + template.compose(document, data); + document.buildPdf(); + } + return outputFile; + } + + /** + * @param args ignored + * @throws Exception if rendering fails + */ + public static void main(String[] args) throws Exception { + System.out.println("Generated: " + generate()); + } +} diff --git a/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceFixtures.java b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceFixtures.java new file mode 100644 index 000000000..8ee074ca7 --- /dev/null +++ b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceFixtures.java @@ -0,0 +1,154 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.templates.data.invoice.InvoiceBrand; +import com.demcha.compose.document.templates.data.invoice.InvoiceContactBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceMasthead; +import com.demcha.compose.document.templates.data.invoice.InvoiceNotesBlock; +import com.demcha.compose.document.templates.data.invoice.InvoicePaymentBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceRecipient; +import com.demcha.compose.document.templates.data.invoice.InvoiceServiceLines; +import com.demcha.compose.document.templates.data.invoice.InvoiceSummaryBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceTotalsBlock; +import com.demcha.compose.document.templates.data.invoice.StructuredInvoiceData; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * Shared fixture data for the {@link PaymentsInvoice} gates — the SAME document + * feeds the pixel parity test and the layout snapshot test, so a geometry shift + * the pixel budget absorbs still trips the exact snapshot, and vice versa. + */ +final class PaymentsInvoiceFixtures { + + private PaymentsInvoiceFixtures() { + } + + /** + * The canonical one-page invoice — seven metadata rows, two addressed + * parties, six marked service lines, seven payment fields, two summed rows + * and a two-line note. + * + * @return the document + */ + static StructuredInvoiceData canonicalInvoice() { + return new StructuredInvoiceData( + brand(), supplier(), masthead(), billTo(), shipTo(), + new InvoiceSummaryBlock("", "", ""), + serviceLines(), totals(), payment(), notes(), "GBP"); + } + + /** No logo: the wordmark is what a document without one falls back to. */ + static InvoiceBrand brand() { + return new InvoiceBrand(null, "Meridian", "", "", "", ""); + } + + static InvoiceContactBlock supplier() { + return new InvoiceContactBlock( + "Meridian Payments Ltd.", + List.of("1 Harbour Exchange", "Canary Wharf", "London E14 9GE", + "United Kingdom"), + "", "", "", + "", "Company No. 09048900", + "", "VAT No. GB 123 4567 89"); + } + + static InvoiceMasthead masthead() { + List entries = new ArrayList<>(); + entries.add(new InvoiceMasthead.Entry("Invoice Number", "INV-2025-05-10472", false)); + entries.add(new InvoiceMasthead.Entry("Invoice Date", "10 May 2025", false)); + entries.add(new InvoiceMasthead.Entry("Billing Period", "1 - 30 April 2025", false)); + entries.add(new InvoiceMasthead.Entry("Account ID", "acct_4Q8xTb2mKp", false)); + entries.add(new InvoiceMasthead.Entry("Payment Terms", "Net 30", false)); + entries.add(new InvoiceMasthead.Entry("Due Date", "14 June 2025", false)); + entries.add(new InvoiceMasthead.Entry("Status", "UNPAID", true)); + return new InvoiceMasthead("INVOICE", entries); + } + + /** The subline is where a billed party's registration goes on this sheet. */ + static InvoiceRecipient billTo() { + return new InvoiceRecipient("BILL TO", "Northwind Ltd.", + "VAT No. GB 987 6543 21", + List.of("Attention: Finance Team", "42 Bridgewater Street", + "Manchester M15 4QT", "United Kingdom"), + "", ""); + } + + static InvoiceRecipient shipTo() { + return new InvoiceRecipient("SHIP TO", "Northwind Ltd.", "", + List.of("Operations Centre", "7 Kingsway Park", + "Leeds LS12 6BD", "United Kingdom"), + "", ""); + } + + static InvoiceServiceLines serviceLines() { + InvoiceServiceLines.Columns columns = new InvoiceServiceLines.Columns( + "", "DESCRIPTION", "", "QUANTITY", "UNIT PRICE", "AMOUNT", "VAT"); + List lines = new ArrayList<>(); + lines.add(line(1, "Subscription Billing", + "Subscription management and recurring billing", + "1", "250.00", "250.00", "20%", "card")); + lines.add(line(2, "Payment Processing", + "Online card payments processing (volume tier)", + "1", "1,180.00", "1,180.00", "20%", "card-settings")); + lines.add(line(3, "Fraud Screening", + "Advanced fraud screening and rules", + "1", "320.00", "320.00", "20%", "shield")); + lines.add(line(4, "Company Formation", + "Incorporation and compliance filings", + "1", "180.00", "180.00", "20%", "globe")); + lines.add(line(5, "In-Person Terminals", + "Terminal rental and firmware updates", + "4", "39.00", "156.00", "20%", "mobile")); + lines.add(line(6, "Priority Support", + "Named engineer, one-hour response", + "1", "100.00", "100.00", "20%", "headset")); + return new InvoiceServiceLines(columns, lines); + } + + private static InvoiceServiceLines.Line line(int number, String title, String description, + String quantity, String unitPrice, + String amount, String vat, String icon) { + return new InvoiceServiceLines.Line(number, title, description, "", + decimal(quantity), "", decimal(unitPrice), decimal(amount), vat, icon); + } + + static InvoiceTotalsBlock totals() { + List rows = new ArrayList<>(); + rows.add(new InvoiceTotalsBlock.Row("Subtotal (excl. VAT)", decimal("2,186.00"))); + rows.add(new InvoiceTotalsBlock.Row("VAT at 20%", decimal("437.20"))); + return new InvoiceTotalsBlock(rows, "TOTAL DUE", decimal("2,623.20")); + } + + static InvoicePaymentBlock payment() { + List fields = new ArrayList<>(); + fields.add(new InvoicePaymentBlock.Field("Bank Name", "Harbour Bank plc")); + fields.add(new InvoicePaymentBlock.Field("Account Name", "Meridian Payments Ltd.")); + fields.add(new InvoicePaymentBlock.Field("Sort Code", "40-02-50")); + fields.add(new InvoicePaymentBlock.Field("Account Number", "71295408")); + fields.add(new InvoicePaymentBlock.Field("IBAN", "GB29 HRBK 4002 5071 2954 08")); + fields.add(new InvoicePaymentBlock.Field("SWIFT / BIC", "HRBKGB2L")); + fields.add(new InvoicePaymentBlock.Field("Reference", "INV-2025-05-10472")); + return new InvoicePaymentBlock("PAYMENT DETAILS", fields, + "Please include the invoice number as payment reference.", + "Due by 14 June 2025", + "Payment due by 14 June 2025", + "", + "Questions? We're here to help."); + } + + static InvoiceNotesBlock notes() { + return new InvoiceNotesBlock("NOTES", + List.of("Thank you for your business. This invoice covers services and " + + "fees for the period stated above.", + "Late payment may incur interest at the statutory rate."), + "support@meridianpayments.example", + "+44 (0) 20 3966 1900"); + } + + /** A printed figure back to a number: the grouping comes off. */ + private static BigDecimal decimal(String printed) { + return new BigDecimal(printed.replace(",", "")); + } +} diff --git a/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceLayoutSnapshotTest.java b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceLayoutSnapshotTest.java new file mode 100644 index 000000000..b97d53c9b --- /dev/null +++ b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceLayoutSnapshotTest.java @@ -0,0 +1,33 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.templates.TemplateTestSupport; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Exact layout snapshot gate for {@link PaymentsInvoice} — freezes the resolved + * geometry of the canonical one-page invoice, which the pixel budget cannot + * see: a small column or spacing shift stays under the visual-diff budget but + * changes the snapshot. + * + *

The preset owns its page geometry, so the session starts unconfigured.

+ * + *

Refresh with {@code -Dgraphcompose.updateSnapshots=true} after a + * deliberate layout change, and commit the JSON with the change.

+ */ +class PaymentsInvoiceLayoutSnapshotTest { + + @Test + void canonicalInvoiceMatchesLayoutSnapshot() throws Exception { + try (DocumentSession session = GraphCompose.document().create()) { + PaymentsInvoice.create().compose(session, + PaymentsInvoiceFixtures.canonicalInvoice()); + assertThat(session.layoutSnapshot().totalPages()).as("total pages").isEqualTo(1); + TemplateTestSupport.assertCanonicalSnapshot( + session, "payments_invoice_layout", "invoice"); + } + } +} diff --git a/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceSmokeTest.java b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceSmokeTest.java new file mode 100644 index 000000000..aed6a269d --- /dev/null +++ b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceSmokeTest.java @@ -0,0 +1,268 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.templates.api.DocumentTemplate; +import com.demcha.compose.document.templates.data.invoice.InvoiceBrand; +import com.demcha.compose.document.templates.data.invoice.InvoiceNotesBlock; +import com.demcha.compose.document.templates.data.invoice.InvoicePaymentBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceRecipient; +import com.demcha.compose.document.templates.data.invoice.InvoiceServiceLines; +import com.demcha.compose.document.templates.data.invoice.InvoiceSummaryBlock; +import com.demcha.compose.document.templates.data.invoice.StructuredInvoiceData; +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.interactive.action.PDActionURI; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink; +import org.apache.pdfbox.text.PDFTextStripper; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Smoke test for {@link PaymentsInvoice} — proves the preset renders a + * {@link StructuredInvoiceData} end-to-end with its packaged marks, falls back + * from a logo to a wordmark, writes its figures with the locale stated rather + * than inherited, reports an unknown mark as a data error, repeats the table + * header when the lines run past a page, and carries the support contacts as + * link annotations, which move no pixel and no layout node so neither gate + * would notice them going missing. + */ +class PaymentsInvoiceSmokeTest { + + private static byte[] render(StructuredInvoiceData data) throws Exception { + // The preset owns its page geometry, so the session starts unconfigured. + try (DocumentSession session = GraphCompose.document().create()) { + PaymentsInvoice.create().compose(session, data); + assertThat(session.roots()).isNotEmpty(); + byte[] pdfBytes = session.toPdfBytes(); + assertThat(pdfBytes).isNotEmpty(); + return pdfBytes; + } + } + + private static String textOf(byte[] pdfBytes) throws Exception { + try (PDDocument document = Loader.loadPDF(pdfBytes)) { + return new PDFTextStripper().getText(document); + } + } + + private static int pagesOf(StructuredInvoiceData data) throws Exception { + try (DocumentSession session = GraphCompose.document().create()) { + PaymentsInvoice.create().compose(session, data); + return session.layoutSnapshot().totalPages(); + } + } + + private static List linkTargets(byte[] pdfBytes) throws Exception { + List targets = new ArrayList<>(); + try (PDDocument document = Loader.loadPDF(pdfBytes)) { + for (PDPage page : document.getPages()) { + for (PDAnnotation annotation : page.getAnnotations()) { + if (annotation instanceof PDAnnotationLink link + && link.getAction() instanceof PDActionURI uri) { + targets.add(uri.getURI()); + } + } + } + } + return targets; + } + + /** The canonical invoice with its service lines replaced. */ + private static StructuredInvoiceData withLines(InvoiceServiceLines lines) { + StructuredInvoiceData base = PaymentsInvoiceFixtures.canonicalInvoice(); + return new StructuredInvoiceData(base.brand(), base.supplier(), base.masthead(), + base.billTo(), base.shipTo(), base.summary(), lines, base.totals(), + base.payment(), base.notes(), base.currencyCode()); + } + + @Test + void exposesStableIdentity() { + DocumentTemplate template = PaymentsInvoice.create(); + assertThat(template.id()).isEqualTo(PaymentsInvoice.ID); + assertThat(template.displayName()).isEqualTo(PaymentsInvoice.DISPLAY_NAME); + } + + @Test + void rendersCanonicalInvoiceWithPackagedMarks() throws Exception { + render(PaymentsInvoiceFixtures.canonicalInvoice()); + } + + @Test + void canonicalRenderCarriesEveryBlocksText() throws Exception { + String text = textOf(render(PaymentsInvoiceFixtures.canonicalInvoice())); + assertThat(text) + .contains("INVOICE") + .contains("Meridian Payments Ltd.") + .contains("Company No. 09048900") + .contains("VAT No. GB 123 4567 89") + .contains("Invoice Number") + .contains("BILL TO") + .contains("SHIP TO") + .contains("Northwind Ltd.") + .contains("Subscription Billing") + .contains("PAYMENT DETAILS") + .contains("GB29 HRBK 4002 5071 2954 08") + .contains("TOTAL DUE") + .contains("NOTES") + .contains("Questions? We're here to help."); + } + + @Test + void aDocumentWithNoLogoFallsBackToItsName() throws Exception { + // The preset carries no mark of its own, so a document that brings only + // a name still gets a lockup rather than an empty box. + assertThat(textOf(render(PaymentsInvoiceFixtures.canonicalInvoice()))) + .contains("Meridian"); + } + + @Test + void figuresAreWrittenWithTheCurrencyStatedOnceAndCarried() throws Exception { + // The column names the currency; each figure carries its symbol. Both + // come from the ISO code rather than from a formatted string. + String text = textOf(render(PaymentsInvoiceFixtures.canonicalInvoice())); + assertThat(text).contains("(GBP)").contains("£2,623.20").contains("£1,180.00"); + } + + @Test + void theDueLineIsSetInCapitalsWhateverCaseTheDocumentUses() throws Exception { + // The design sets the footer's due line in capitals, so the preset is + // what uppercases it rather than the document having to. + assertThat(textOf(render(PaymentsInvoiceFixtures.canonicalInvoice()))) + .contains("PAYMENT DUE BY 14 JUNE 2025"); + } + + @Test + void theSupportContactsAreClickable() throws Exception { + List targets = linkTargets(render(PaymentsInvoiceFixtures.canonicalInvoice())); + assertThat(targets) + .contains("mailto:support@meridianpayments.example") + .contains("tel:+442039661900"); + } + + @Test + void aTrunkPrefixIsPrintedButNotDialled() throws Exception { + // "(0)" is for a domestic dialler; left in the digits it would make a + // number that reaches nobody. The fixture's own number carries one, so + // the sheet prints it and the annotation drops it. + byte[] pdfBytes = render(PaymentsInvoiceFixtures.canonicalInvoice()); + // The stripper's own spacing is not the design's, so the printed form + // is compared without it. + assertThat(textOf(pdfBytes).replaceAll("(?U)\\s", "")) + .contains("+44(0)2039661900"); + assertThat(linkTargets(pdfBytes)) + .contains("tel:+442039661900") + .doesNotContain("tel:+4402039661900"); + } + + @Test + void anUnknownMarkIsReportedAsADataError() { + InvoiceServiceLines wrong = new InvoiceServiceLines( + PaymentsInvoiceFixtures.serviceLines().columns(), + List.of(new InvoiceServiceLines.Line(1, "Telepathy", "Reading minds", "", + BigDecimal.ONE, "", BigDecimal.TEN, BigDecimal.TEN, "20%", "telescope"))); + + assertThatThrownBy(() -> render(withLines(wrong))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("telescope") + .hasMessageContaining("shield"); + } + + @Test + void aLineWithoutAMarkIsDrawnWithoutOne() throws Exception { + InvoiceServiceLines unmarked = new InvoiceServiceLines( + PaymentsInvoiceFixtures.serviceLines().columns(), + List.of(new InvoiceServiceLines.Line(1, "Consulting", "A day of it", "", + BigDecimal.ONE, "", new BigDecimal("1200"), new BigDecimal("1200"), + "20%"))); + + assertThat(textOf(render(withLines(unmarked)))).contains("Consulting"); + } + + @Test + void aLongerInvoiceRunsOnAndRepeatsItsTableHeader() throws Exception { + // The table is the region that grows, so the sheet flows rather than + // refusing — and a continuation page has to say what its columns are. + List many = new ArrayList<>(); + for (int index = 1; index <= 30; index++) { + many.add(new InvoiceServiceLines.Line(index, "Service " + index, + "A line of description for it", "", + BigDecimal.ONE, "", new BigDecimal("120"), new BigDecimal("120"), + "20%", "card")); + } + StructuredInvoiceData longer = withLines(new InvoiceServiceLines( + PaymentsInvoiceFixtures.serviceLines().columns(), many)); + + assertThat(pagesOf(longer)).isGreaterThan(1); + byte[] pdfBytes = render(longer); + assertThat(textOf(pdfBytes)).contains("Service 30"); + try (PDDocument document = Loader.loadPDF(pdfBytes)) { + PDFTextStripper stripper = new PDFTextStripper(); + stripper.setStartPage(2); + stripper.setEndPage(2); + assertThat(stripper.getText(document)) + .as("the second page names its columns") + .contains("DESCRIPTION") + .contains("UNIT PRICE"); + } + } + + @Test + void everyPageCarriesItsNumber() throws Exception { + List many = new ArrayList<>(); + for (int index = 1; index <= 30; index++) { + many.add(new InvoiceServiceLines.Line(index, "Service " + index, "", "", + BigDecimal.ONE, "", new BigDecimal("120"), new BigDecimal("120"), + "20%", "card")); + } + String text = textOf(render(withLines(new InvoiceServiceLines( + PaymentsInvoiceFixtures.serviceLines().columns(), many)))); + assertThat(text).contains("Page 1 of").contains("Page 2 of"); + } + + @Test + void anInvoiceWithNoShipToDrawsOneParty() throws Exception { + StructuredInvoiceData base = PaymentsInvoiceFixtures.canonicalInvoice(); + StructuredInvoiceData single = new StructuredInvoiceData(base.brand(), base.supplier(), + base.masthead(), base.billTo(), + new InvoiceRecipient("", "", "", List.of(), "", ""), + base.summary(), base.serviceLines(), base.totals(), base.payment(), + base.notes(), base.currencyCode()); + + String text = textOf(render(single)); + assertThat(text).contains("BILL TO").doesNotContain("SHIP TO"); + } + + @Test + void anInvoiceWithNoNotesDropsTheBlockRatherThanLeavingItsDisc() throws Exception { + StructuredInvoiceData base = PaymentsInvoiceFixtures.canonicalInvoice(); + StructuredInvoiceData bare = new StructuredInvoiceData(base.brand(), base.supplier(), + base.masthead(), base.billTo(), base.shipTo(), base.summary(), + base.serviceLines(), base.totals(), base.payment(), + new InvoiceNotesBlock("NOTES", List.of(), "ops@example.test", ""), + base.currencyCode()); + + String text = textOf(render(bare)); + assertThat(text).doesNotContain("Late payment may incur interest"); + assertThat(linkTargets(render(bare))).contains("mailto:ops@example.test"); + } + + @Test + void anEmptyDocumentStillRenders() throws Exception { + // Every block absent: the preset draws its furniture and nothing else, + // rather than failing on the first missing field. + render(new StructuredInvoiceData(new InvoiceBrand(null, "", "", ""), null, null, + null, null, new InvoiceSummaryBlock("", "", ""), + new InvoiceServiceLines(null, List.of()), null, + new InvoicePaymentBlock("", List.of(), "", "", "", "", ""), + new InvoiceNotesBlock("", List.of(), "", ""), "")); + } +} diff --git a/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceVisualParityTest.java b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceVisualParityTest.java new file mode 100644 index 000000000..9b6046383 --- /dev/null +++ b/qa/src/test/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoiceVisualParityTest.java @@ -0,0 +1,41 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.testing.visual.PdfVisualRegression; +import org.junit.jupiter.api.Test; + +import java.nio.file.Path; + +/** + * Pixel-diff visual parity gate for {@link PaymentsInvoice} — the canonical + * one-page invoice against a checked-in baseline. + * + *

Re-blessing baselines — after a deliberate visual change, + * re-run with {@code -Dgraphcompose.visual.approve=true} and commit the updated + * PNG with the change.

+ */ +class PaymentsInvoiceVisualParityTest { + + private static final Path BASELINE_ROOT = Path.of( + "src", "test", "resources", "visual-baselines", "invoice-v2-layered"); + + private static final long PIXEL_DIFF_BUDGET = 50_000L; + private static final int PER_PIXEL_TOLERANCE = 8; + + @Test + void rendersWithinPixelDiffBudget() throws Exception { + byte[] pdfBytes; + try (DocumentSession document = GraphCompose.document().create()) { + PaymentsInvoice.create().compose(document, + PaymentsInvoiceFixtures.canonicalInvoice()); + pdfBytes = document.toPdfBytes(); + } + + PdfVisualRegression.standard() + .baselineRoot(BASELINE_ROOT) + .perPixelTolerance(PER_PIXEL_TOLERANCE) + .mismatchedPixelBudget(PIXEL_DIFF_BUDGET) + .assertMatchesBaseline("payments_invoice", pdfBytes); + } +} diff --git a/qa/src/test/resources/layout-snapshots/canonical-templates/invoice/payments_invoice_layout.json b/qa/src/test/resources/layout-snapshots/canonical-templates/invoice/payments_invoice_layout.json new file mode 100644 index 000000000..ffcebc4f9 --- /dev/null +++ b/qa/src/test/resources/layout-snapshots/canonical-templates/invoice/payments_invoice_layout.json @@ -0,0 +1,5357 @@ +{ + "formatVersion" : "2.0", + "canvas" : { + "pageWidth" : 595.276, + "pageHeight" : 841.89, + "innerWidth" : 537.159, + "innerHeight" : 808.035, + "margin" : { + "top" : 15.799, + "right" : 29.341, + "bottom" : 18.056, + "left" : 28.776 + } + }, + "totalPages" : 1, + "nodes" : [ { + "path" : "PaymentsInvoice[0]", + "entityName" : "PaymentsInvoice", + "entityKind" : "ContainerNode", + "parentPath" : null, + "childIndex" : 0, + "depth" : 1, + "layer" : 1, + "computedX" : 28.776, + "computedY" : 34.229, + "placementX" : 28.776, + "placementY" : 34.229, + "placementWidth" : 537.159, + "placementHeight" : 791.862, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 791.862, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]", + "entityName" : "MastheadStack", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 0, + "depth" : 2, + "layer" : 2, + "computedX" : 28.776, + "computedY" : 622.964, + "placementX" : 28.776, + "placementY" : 622.964, + "placementWidth" : 537.159, + "placementHeight" : 203.127, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 203.127, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]", + "entityName" : "HeaderBand", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 217.459, + "computedY" : 638.763, + "placementX" : 217.459, + "placementY" : 638.763, + "placementWidth" : 96.26, + "placementHeight" : 203.127, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 96.26, + "contentHeight" : 203.127, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]/HeaderBandLayers[0]", + "entityName" : "HeaderBandLayers", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 217.459, + "computedY" : 638.763, + "placementX" : 217.459, + "placementY" : 638.763, + "placementWidth" : 96.26, + "placementHeight" : 203.127, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 96.26, + "contentHeight" : 203.127, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]/HeaderBandLayers[0]/BandLavender[0]", + "entityName" : "BandLavender", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]/HeaderBandLayers[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 217.459, + "computedY" : 638.763, + "placementX" : 217.459, + "placementY" : 638.763, + "placementWidth" : 96.26, + "placementHeight" : 203.127, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 96.26, + "contentHeight" : 203.127, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]/HeaderBandLayers[0]/BandNavy[1]", + "entityName" : "BandNavy", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderBand[0]/HeaderBandLayers[0]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 217.459, + "computedY" : 638.763, + "placementX" : 217.459, + "placementY" : 638.763, + "placementWidth" : 96.26, + "placementHeight" : 203.127, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 96.26, + "contentHeight" : 203.127, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/AccentBarHolder[1]", + "entityName" : "AccentBarHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]", + "childIndex" : 1, + "depth" : 3, + "layer" : 3, + "computedX" : 16.363, + "computedY" : 651.176, + "placementX" : 16.363, + "placementY" : 651.176, + "placementWidth" : 1.128, + "placementHeight" : 174.915, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 1.128, + "contentHeight" : 174.915, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/AccentBarHolder[1]/HeaderAccentBar[0]", + "entityName" : "HeaderAccentBar", + "entityKind" : "LineNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/AccentBarHolder[1]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 16.363, + "computedY" : 651.176, + "placementX" : 16.363, + "placementY" : 651.176, + "placementWidth" : 1.128, + "placementHeight" : 174.915, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 1.128, + "contentHeight" : 174.915, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]", + "entityName" : "HeaderContent", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]", + "childIndex" : 2, + "depth" : 3, + "layer" : 3, + "computedX" : 28.776, + "computedY" : 646.402, + "placementX" : 28.776, + "placementY" : 646.402, + "placementWidth" : 537.159, + "placementHeight" : 179.689, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 179.689, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]", + "entityName" : "Masthead", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 28.776, + "computedY" : 770.962, + "placementX" : 28.776, + "placementY" : 770.962, + "placementWidth" : 537.159, + "placementHeight" : 44.973, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 44.973, + "margin" : { + "top" : 10.156, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]/BrandLockup[0]", + "entityName" : "BrandLockup", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 28.776, + "computedY" : 789.713, + "placementX" : 28.776, + "placementY" : 789.713, + "placementWidth" : 94.178, + "placementHeight" : 26.222, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 94.178, + "contentHeight" : 26.222, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 6.771 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]/BrandLockup[0]/BrandWordmark[0]", + "entityName" : "BrandWordmark", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]/BrandLockup[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 35.547, + "computedY" : 789.713, + "placementX" : 35.547, + "placementY" : 789.713, + "placementWidth" : 87.407, + "placementHeight" : 26.222, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 87.407, + "contentHeight" : 26.222, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]/InvoiceTitle[1]", + "entityName" : "InvoiceTitle", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/Masthead[0]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 360.551, + "computedY" : 770.962, + "placementX" : 360.551, + "placementY" : 770.962, + "placementWidth" : 149.064, + "placementHeight" : 43.575, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 149.064, + "contentHeight" : 43.575, + "margin" : { + "top" : 1.397, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]", + "entityName" : "HeaderSplit", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 28.776, + "computedY" : 646.402, + "placementX" : 28.776, + "placementY" : 646.402, + "placementWidth" : 537.159, + "placementHeight" : 119.2, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 119.2, + "margin" : { + "top" : 5.36, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]", + "entityName" : "IssuerBlock", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 28.776, + "computedY" : 664.414, + "placementX" : 28.776, + "placementY" : 664.414, + "placementWidth" : 127.249, + "placementHeight" : 101.188, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 127.249, + "contentHeight" : 101.188, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 6.207 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerName[0]", + "entityName" : "IssuerName", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 34.983, + "computedY" : 751.882, + "placementX" : 34.983, + "placementY" : 751.882, + "placementWidth" : 121.042, + "placementHeight" : 13.72, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 121.042, + "contentHeight" : 13.72, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]", + "entityName" : "IssuerAddress", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]", + "childIndex" : 1, + "depth" : 6, + "layer" : 6, + "computedX" : 34.983, + "computedY" : 700.333, + "placementX" : 34.983, + "placementY" : 700.333, + "placementWidth" : 78.364, + "placementHeight" : 46.576, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 78.364, + "contentHeight" : 46.576, + "margin" : { + "top" : 4.972, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]/IssuerAddressLine1[0]", + "entityName" : "IssuerAddressLine1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 736.439, + "placementX" : 34.983, + "placementY" : 736.439, + "placementWidth" : 78.364, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 78.364, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]/IssuerAddressLine2[1]", + "entityName" : "IssuerAddressLine2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 724.404, + "placementX" : 34.983, + "placementY" : 724.404, + "placementWidth" : 53.766, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 53.766, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]/IssuerAddressLine3[2]", + "entityName" : "IssuerAddressLine3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]", + "childIndex" : 2, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 712.369, + "placementX" : 34.983, + "placementY" : 712.369, + "placementWidth" : 65.118, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 65.118, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]/IssuerAddressLine4[3]", + "entityName" : "IssuerAddressLine4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerAddress[1]", + "childIndex" : 3, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 700.333, + "placementX" : 34.983, + "placementY" : 700.333, + "placementWidth" : 62.544, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 62.544, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerRegistration[2]", + "entityName" : "IssuerRegistration", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]", + "childIndex" : 2, + "depth" : 6, + "layer" : 6, + "computedX" : 34.983, + "computedY" : 664.414, + "placementX" : 34.983, + "placementY" : 664.414, + "placementWidth" : 99.383, + "placementHeight" : 22.32, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 99.383, + "contentHeight" : 22.32, + "margin" : { + "top" : 13.6, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerRegistration[2]/IssuerRegistrationLine1[0]", + "entityName" : "IssuerRegistrationLine1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerRegistration[2]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 676.263, + "placementX" : 34.983, + "placementY" : 676.263, + "placementWidth" : 95.186, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 95.186, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerRegistration[2]/IssuerRegistrationLine2[1]", + "entityName" : "IssuerRegistrationLine2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/IssuerBlock[0]/IssuerRegistration[2]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 34.983, + "computedY" : 664.414, + "placementX" : 34.983, + "placementY" : 664.414, + "placementWidth" : 99.383, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 99.383, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]", + "entityName" : "InvoiceMeta", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 205.384, + "placementHeight" : 119.2, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 205.384, + "contentHeight" : 119.2, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 6.207, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]", + "entityName" : "MetaGridLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 205.384, + "placementHeight" : 112.993, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 205.384, + "contentHeight" : 112.993, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]", + "entityName" : "MetaGridHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 205.384, + "placementHeight" : 112.993, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 205.384, + "contentHeight" : 112.993, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]", + "entityName" : "MetaGrid", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 205.384, + "placementHeight" : 112.993, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 205.384, + "contentHeight" : 112.993, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "entityName" : "MetaLabels", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 64.446, + "placementHeight" : 112.993, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 64.446, + "contentHeight" : 112.993, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel1[0]", + "entityName" : "MetaLabel1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 748.541, + "placementX" : 360.551, + "placementY" : 748.541, + "placementWidth" : 64.446, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 64.446, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel2[1]", + "entityName" : "MetaLabel2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 1, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 731.518, + "placementX" : 360.551, + "placementY" : 731.518, + "placementWidth" : 51.123, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 51.123, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel3[2]", + "entityName" : "MetaLabel3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 2, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 714.495, + "placementX" : 360.551, + "placementY" : 714.495, + "placementWidth" : 53.574, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 53.574, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel4[3]", + "entityName" : "MetaLabel4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 3, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 697.471, + "placementX" : 360.551, + "placementY" : 697.471, + "placementWidth" : 45.542, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 45.542, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel5[4]", + "entityName" : "MetaLabel5", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 4, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 680.448, + "placementX" : 360.551, + "placementY" : 680.448, + "placementWidth" : 63.234, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 63.234, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel6[5]", + "entityName" : "MetaLabel6", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 5, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 663.425, + "placementX" : 360.551, + "placementY" : 663.425, + "placementWidth" : 38.686, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 38.686, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]/MetaLabel7[6]", + "entityName" : "MetaLabel7", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaLabels[0]", + "childIndex" : 6, + "depth" : 10, + "layer" : 10, + "computedX" : 360.551, + "computedY" : 646.402, + "placementX" : 360.551, + "placementY" : 646.402, + "placementWidth" : 25.371, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 25.371, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "entityName" : "MetaValues", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]", + "childIndex" : 1, + "depth" : 9, + "layer" : 9, + "computedX" : 440.955, + "computedY" : 646.402, + "placementX" : 440.955, + "placementY" : 646.402, + "placementWidth" : 88.384, + "placementHeight" : 112.993, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 88.384, + "contentHeight" : 112.993, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 13.26 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue1[0]", + "entityName" : "MetaValue1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 749.614, + "placementX" : 454.215, + "placementY" : 749.614, + "placementWidth" : 75.124, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 75.124, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue2[1]", + "entityName" : "MetaValue2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 1, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 732.591, + "placementX" : 454.215, + "placementY" : 732.591, + "placementWidth" : 48.366, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 48.366, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue3[2]", + "entityName" : "MetaValue3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 2, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 715.568, + "placementX" : 454.215, + "placementY" : 715.568, + "placementWidth" : 61.407, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 61.407, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue4[3]", + "entityName" : "MetaValue4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 3, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 698.545, + "placementX" : 454.215, + "placementY" : 698.545, + "placementWidth" : 69.345, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 69.345, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue5[4]", + "entityName" : "MetaValue5", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 4, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 681.522, + "placementX" : 454.215, + "placementY" : 681.522, + "placementWidth" : 24.998, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 24.998, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue6[5]", + "entityName" : "MetaValue6", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 5, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 664.498, + "placementX" : 454.215, + "placementY" : 664.498, + "placementWidth" : 49.385, + "placementHeight" : 9.781, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 49.385, + "contentHeight" : 9.781, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]/MetaValue7[6]", + "entityName" : "MetaValue7", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/MastheadStack[0]/HeaderContent[2]/HeaderSplit[1]/InvoiceMeta[1]/MetaGridLayer[0]/MetaGridHolder[0]/MetaGrid[0]/MetaValues[1]", + "childIndex" : 6, + "depth" : 10, + "layer" : 10, + "computedX" : 454.215, + "computedY" : 646.402, + "placementX" : 454.215, + "placementY" : 646.402, + "placementWidth" : 35.149, + "placementHeight" : 10.854, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 35.149, + "contentHeight" : 10.854, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/HeaderRule[1]", + "entityName" : "HeaderRule", + "entityKind" : "LineNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 1, + "depth" : 2, + "layer" : 2, + "computedX" : 16.927, + "computedY" : 638.198, + "placementX" : 16.927, + "placementY" : 638.198, + "placementWidth" : 557.471, + "placementHeight" : 1.128, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 557.471, + "contentHeight" : 1.128, + "margin" : { + "top" : -16.363, + "right" : -8.464, + "bottom" : 9.592, + "left" : -11.849 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]", + "entityName" : "PartiesRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 2, + "depth" : 2, + "layer" : 2, + "computedX" : 28.776, + "computedY" : 522.368, + "placementX" : 28.776, + "placementY" : 522.368, + "placementWidth" : 537.159, + "placementHeight" : 106.238, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 106.238, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]", + "entityName" : "Party1", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 28.776, + "computedY" : 522.368, + "placementX" : 28.776, + "placementY" : 522.368, + "placementWidth" : 268.579, + "placementHeight" : 106.238, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 268.579, + "contentHeight" : 106.238, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 5.078 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]", + "entityName" : "PartyHeadLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 33.855, + "computedY" : 606.036, + "placementX" : 33.855, + "placementY" : 606.036, + "placementWidth" : 263.501, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 263.501, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]", + "entityName" : "PartyHeadHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 33.855, + "computedY" : 606.036, + "placementX" : 33.855, + "placementY" : 606.036, + "placementWidth" : 263.501, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 263.501, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "entityName" : "PartyHead", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 33.855, + "computedY" : 606.036, + "placementX" : 33.855, + "placementY" : 606.036, + "placementWidth" : 263.501, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 263.501, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]", + "entityName" : "PartyDisc", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 33.855, + "computedY" : 606.036, + "placementX" : 33.855, + "placementY" : 606.036, + "placementWidth" : 22.57, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]", + "entityName" : "Discbill-to", + "entityKind" : "ShapeContainerNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 33.855, + "computedY" : 606.036, + "placementX" : 33.855, + "placementY" : 606.036, + "placementWidth" : 22.57, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]", + "entityName" : "Glyphbill-to", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 33.855, + "computedY" : 609.422, + "placementX" : 33.855, + "placementY" : 609.422, + "placementWidth" : 22.57, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 33.855, + "computedY" : 609.422, + "placementX" : 33.855, + "placementY" : 609.422, + "placementWidth" : 22.57, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]/Align[0]", + "childIndex" : 0, + "depth" : 11, + "layer" : 11, + "computedX" : 37.24, + "computedY" : 609.422, + "placementX" : 37.24, + "placementY" : 609.422, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discbill-to[0]/Glyphbill-to[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 12, + "layer" : 12, + "computedX" : 37.24, + "computedY" : 609.422, + "placementX" : 37.24, + "placementY" : 609.422, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyLabel[1]", + "entityName" : "PartyLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 66.581, + "computedY" : 613.055, + "placementX" : 66.581, + "placementY" : 613.055, + "placementWidth" : 31.052, + "placementHeight" : 10.217, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 31.052, + "contentHeight" : 10.217, + "margin" : { + "top" : 5.334, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]", + "entityName" : "PartyBody", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 33.855, + "computedY" : 522.368, + "placementX" : 33.855, + "placementY" : 522.368, + "placementWidth" : 132.109, + "placementHeight" : 83.668, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 132.109, + "contentHeight" : 83.668, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 32.726 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyName[0]", + "entityName" : "PartyName", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 66.581, + "computedY" : 593.759, + "placementX" : 66.581, + "placementY" : 593.759, + "placementWidth" : 69.419, + "placementHeight" : 12.278, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 69.419, + "contentHeight" : 12.278, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]", + "entityName" : "PartyAddress", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 66.581, + "computedY" : 544.374, + "placementX" : 66.581, + "placementY" : 544.374, + "placementWidth" : 94.506, + "placementHeight" : 45.51, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 94.506, + "contentHeight" : 45.51, + "margin" : { + "top" : 3.875, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]/PartyAddressLine1[0]", + "entityName" : "PartyAddressLine1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 66.581, + "computedY" : 579.413, + "placementX" : 66.581, + "placementY" : 579.413, + "placementWidth" : 94.506, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 94.506, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]/PartyAddressLine2[1]", + "entityName" : "PartyAddressLine2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 1, + "depth" : 6, + "layer" : 6, + "computedX" : 66.581, + "computedY" : 567.733, + "placementX" : 66.581, + "placementY" : 567.733, + "placementWidth" : 85.039, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 85.039, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]/PartyAddressLine3[2]", + "entityName" : "PartyAddressLine3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 2, + "depth" : 6, + "layer" : 6, + "computedX" : 66.581, + "computedY" : 556.054, + "placementX" : 66.581, + "placementY" : 556.054, + "placementWidth" : 85.553, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 85.553, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]/PartyAddressLine4[3]", + "entityName" : "PartyAddressLine4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 3, + "depth" : 6, + "layer" : 6, + "computedX" : 66.581, + "computedY" : 544.374, + "placementX" : 66.581, + "placementY" : 544.374, + "placementWidth" : 62.544, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 62.544, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]/PartySubline[2]", + "entityName" : "PartySubline", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party1[0]/PartyBody[1]", + "childIndex" : 2, + "depth" : 5, + "layer" : 5, + "computedX" : 66.581, + "computedY" : 522.368, + "placementX" : 66.581, + "placementY" : 522.368, + "placementWidth" : 99.383, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 99.383, + "contentHeight" : 10.471, + "margin" : { + "top" : 11.535, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]", + "entityName" : "Party2", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]", + "childIndex" : 1, + "depth" : 3, + "layer" : 3, + "computedX" : 297.356, + "computedY" : 544.374, + "placementX" : 297.356, + "placementY" : 544.374, + "placementWidth" : 268.579, + "placementHeight" : 84.232, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 268.579, + "contentHeight" : 84.232, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 22.57 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]", + "entityName" : "PartyHeadLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 319.925, + "computedY" : 606.036, + "placementX" : 319.925, + "placementY" : 606.036, + "placementWidth" : 246.01, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 246.01, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]", + "entityName" : "PartyHeadHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 319.925, + "computedY" : 606.036, + "placementX" : 319.925, + "placementY" : 606.036, + "placementWidth" : 246.01, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 246.01, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "entityName" : "PartyHead", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 319.925, + "computedY" : 606.036, + "placementX" : 319.925, + "placementY" : 606.036, + "placementWidth" : 246.01, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 246.01, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]", + "entityName" : "PartyDisc", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 319.925, + "computedY" : 606.036, + "placementX" : 319.925, + "placementY" : 606.036, + "placementWidth" : 22.57, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]", + "entityName" : "Discship-to", + "entityKind" : "ShapeContainerNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 319.925, + "computedY" : 606.036, + "placementX" : 319.925, + "placementY" : 606.036, + "placementWidth" : 22.57, + "placementHeight" : 22.57, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 22.57, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]", + "entityName" : "Glyphship-to", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 319.925, + "computedY" : 609.422, + "placementX" : 319.925, + "placementY" : 609.422, + "placementWidth" : 22.57, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 319.925, + "computedY" : 609.422, + "placementX" : 319.925, + "placementY" : 609.422, + "placementWidth" : 22.57, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.57, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]/Align[0]", + "childIndex" : 0, + "depth" : 11, + "layer" : 11, + "computedX" : 323.311, + "computedY" : 609.422, + "placementX" : 323.311, + "placementY" : 609.422, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyDisc[0]/Discship-to[0]/Glyphship-to[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 12, + "layer" : 12, + "computedX" : 323.311, + "computedY" : 609.422, + "placementX" : 323.311, + "placementY" : 609.422, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]/PartyLabel[1]", + "entityName" : "PartyLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyHeadLayer[0]/PartyHeadHolder[0]/PartyHead[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 352.651, + "computedY" : 613.055, + "placementX" : 352.651, + "placementY" : 613.055, + "placementWidth" : 33.095, + "placementHeight" : 10.217, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 33.095, + "contentHeight" : 10.217, + "margin" : { + "top" : 5.334, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]", + "entityName" : "PartyBody", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 319.925, + "computedY" : 544.374, + "placementX" : 319.925, + "placementY" : 544.374, + "placementWidth" : 104.004, + "placementHeight" : 61.663, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 104.004, + "contentHeight" : 61.663, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 32.726 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyName[0]", + "entityName" : "PartyName", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 352.651, + "computedY" : 593.759, + "placementX" : 352.651, + "placementY" : 593.759, + "placementWidth" : 69.419, + "placementHeight" : 12.278, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 69.419, + "contentHeight" : 12.278, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]", + "entityName" : "PartyAddress", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 352.651, + "computedY" : 544.374, + "placementX" : 352.651, + "placementY" : 544.374, + "placementWidth" : 71.278, + "placementHeight" : 45.51, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 71.278, + "contentHeight" : 45.51, + "margin" : { + "top" : 3.875, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]/PartyAddressLine1[0]", + "entityName" : "PartyAddressLine1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 352.651, + "computedY" : 579.413, + "placementX" : 352.651, + "placementY" : 579.413, + "placementWidth" : 71.278, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 71.278, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]/PartyAddressLine2[1]", + "entityName" : "PartyAddressLine2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 1, + "depth" : 6, + "layer" : 6, + "computedX" : 352.651, + "computedY" : 567.733, + "placementX" : 352.651, + "placementY" : 567.733, + "placementWidth" : 63.478, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 63.478, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]/PartyAddressLine3[2]", + "entityName" : "PartyAddressLine3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 2, + "depth" : 6, + "layer" : 6, + "computedX" : 352.651, + "computedY" : 556.054, + "placementX" : 352.651, + "placementY" : 556.054, + "placementWidth" : 63.521, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 63.521, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]/PartyAddressLine4[3]", + "entityName" : "PartyAddressLine4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/PartiesRow[2]/Party2[1]/PartyBody[1]/PartyAddress[1]", + "childIndex" : 3, + "depth" : 6, + "layer" : 6, + "computedX" : 352.651, + "computedY" : 544.374, + "placementX" : 352.651, + "placementY" : 544.374, + "placementWidth" : 62.544, + "placementHeight" : 10.471, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 62.544, + "contentHeight" : 10.471, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/LineItemsBox[3]", + "entityName" : "LineItemsBox", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 3, + "depth" : 2, + "layer" : 2, + "computedX" : 28.776, + "computedY" : 272.254, + "placementX" : 28.776, + "placementY" : 272.254, + "placementWidth" : 537.159, + "placementHeight" : 233.751, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 233.751, + "margin" : { + "top" : 16.363, + "right" : 0.0, + "bottom" : 10.156, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/LineItemsBox[3]/LineItems[0]", + "entityName" : "LineItems", + "entityKind" : "TableNode", + "parentPath" : "PaymentsInvoice[0]/LineItemsBox[3]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 28.776, + "computedY" : 272.254, + "placementX" : 28.776, + "placementY" : 272.254, + "placementWidth" : 537.159, + "placementHeight" : 233.751, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 233.751, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]", + "entityName" : "SettlementRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 4, + "depth" : 2, + "layer" : 2, + "computedX" : 28.776, + "computedY" : 153.463, + "placementX" : 28.776, + "placementY" : 153.463, + "placementWidth" : 537.159, + "placementHeight" : 108.635, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 108.635, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]", + "entityName" : "PaymentDetails", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 28.776, + "computedY" : 153.82, + "placementX" : 28.776, + "placementY" : 153.82, + "placementWidth" : 248.267, + "placementHeight" : 108.278, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 248.267, + "contentHeight" : 108.278, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 2.821, + "right" : 11.285, + "bottom" : 7.617, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]", + "entityName" : "CardHeadLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 28.776, + "computedY" : 237.835, + "placementX" : 28.776, + "placementY" : 237.835, + "placementWidth" : 236.982, + "placementHeight" : 21.441, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.982, + "contentHeight" : 21.441, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]", + "entityName" : "CardHeadHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 28.776, + "computedY" : 237.835, + "placementX" : 28.776, + "placementY" : 237.835, + "placementWidth" : 236.982, + "placementHeight" : 21.441, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.982, + "contentHeight" : 21.441, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]", + "entityName" : "CardHead", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 28.776, + "computedY" : 237.835, + "placementX" : 28.776, + "placementY" : 237.835, + "placementWidth" : 236.982, + "placementHeight" : 21.441, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.982, + "contentHeight" : 21.441, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]", + "entityName" : "CardDisc", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 28.776, + "computedY" : 237.835, + "placementX" : 28.776, + "placementY" : 237.835, + "placementWidth" : 28.494, + "placementHeight" : 21.441, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 28.494, + "contentHeight" : 21.441, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 7.053 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]", + "entityName" : "Discbank", + "entityKind" : "ShapeContainerNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 35.829, + "computedY" : 237.835, + "placementX" : 35.829, + "placementY" : 237.835, + "placementWidth" : 21.441, + "placementHeight" : 21.441, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 21.441, + "contentHeight" : 21.441, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]", + "entityName" : "Glyphbank", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 35.829, + "computedY" : 240.656, + "placementX" : 35.829, + "placementY" : 240.656, + "placementWidth" : 21.441, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 21.441, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 35.829, + "computedY" : 240.656, + "placementX" : 35.829, + "placementY" : 240.656, + "placementWidth" : 21.441, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 21.441, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]/Align[0]", + "childIndex" : 0, + "depth" : 11, + "layer" : 11, + "computedX" : 38.651, + "computedY" : 240.656, + "placementX" : 38.651, + "placementY" : 240.656, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardDisc[0]/Discbank[0]/Glyphbank[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 12, + "layer" : 12, + "computedX" : 38.651, + "computedY" : 240.656, + "placementX" : 38.651, + "placementY" : 240.656, + "placementWidth" : 15.799, + "placementHeight" : 15.799, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 15.799, + "contentHeight" : 15.799, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]/CardLabel[1]", + "entityName" : "CardLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardHeadLayer[0]/CardHeadHolder[0]/CardHead[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 66.863, + "computedY" : 243.431, + "placementX" : 66.863, + "placementY" : 243.431, + "placementWidth" : 80.189, + "placementHeight" : 10.582, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 80.189, + "contentHeight" : 10.582, + "margin" : { + "top" : 5.263, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]", + "entityName" : "CardFieldsLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 28.776, + "computedY" : 161.437, + "placementX" : 28.776, + "placementY" : 161.437, + "placementWidth" : 236.982, + "placementHeight" : 76.398, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.982, + "contentHeight" : 76.398, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]", + "entityName" : "CardFieldsHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 28.776, + "computedY" : 161.437, + "placementX" : 28.776, + "placementY" : 161.437, + "placementWidth" : 236.982, + "placementHeight" : 76.398, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.982, + "contentHeight" : 76.398, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]", + "entityName" : "CardFields", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 65.452, + "computedY" : 161.437, + "placementX" : 65.452, + "placementY" : 161.437, + "placementWidth" : 200.306, + "placementHeight" : 74.18, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 200.306, + "contentHeight" : 74.18, + "margin" : { + "top" : 2.218, + "right" : 0.0, + "bottom" : 0.0, + "left" : 36.676 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "entityName" : "CardFieldLabels", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 65.452, + "computedY" : 161.437, + "placementX" : 65.452, + "placementY" : 161.437, + "placementWidth" : 56.174, + "placementHeight" : 74.18, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 56.174, + "contentHeight" : 74.18, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel1[0]", + "entityName" : "CardFieldLabel1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 226.776, + "placementX" : 65.452, + "placementY" : 226.776, + "placementWidth" : 38.014, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 38.014, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel2[1]", + "entityName" : "CardFieldLabel2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 215.886, + "placementX" : 65.452, + "placementY" : 215.886, + "placementWidth" : 48.829, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 48.829, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel3[2]", + "entityName" : "CardFieldLabel3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 2, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 204.996, + "placementX" : 65.452, + "placementY" : 204.996, + "placementWidth" : 32.791, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 32.791, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel4[3]", + "entityName" : "CardFieldLabel4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 3, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 194.107, + "placementX" : 65.452, + "placementY" : 194.107, + "placementWidth" : 56.174, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 56.174, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel5[4]", + "entityName" : "CardFieldLabel5", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 4, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 183.217, + "placementX" : 65.452, + "placementY" : 183.217, + "placementWidth" : 17.843, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 17.843, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel6[5]", + "entityName" : "CardFieldLabel6", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 5, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 172.327, + "placementX" : 65.452, + "placementY" : 172.327, + "placementWidth" : 41.499, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 41.499, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]/CardFieldLabel7[6]", + "entityName" : "CardFieldLabel7", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldLabels[0]", + "childIndex" : 6, + "depth" : 8, + "layer" : 8, + "computedX" : 65.452, + "computedY" : 161.437, + "placementX" : 65.452, + "placementY" : 161.437, + "placementWidth" : 33.572, + "placementHeight" : 8.841, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 33.572, + "contentHeight" : 8.841, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "entityName" : "CardFieldValues", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 144.446, + "computedY" : 161.461, + "placementX" : 144.446, + "placementY" : 161.461, + "placementWidth" : 107.558, + "placementHeight" : 74.156, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 107.558, + "contentHeight" : 74.156, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue1[0]", + "entityName" : "CardFieldValue1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 226.8, + "placementX" : 144.446, + "placementY" : 226.8, + "placementWidth" : 56.362, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 56.362, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue2[1]", + "entityName" : "CardFieldValue2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 215.91, + "placementX" : 144.446, + "placementY" : 215.91, + "placementWidth" : 76.501, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 76.501, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue3[2]", + "entityName" : "CardFieldValue3", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 2, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 205.02, + "placementX" : 144.446, + "placementY" : 205.02, + "placementWidth" : 31.035, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 31.035, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue4[3]", + "entityName" : "CardFieldValue4", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 3, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 194.13, + "placementX" : 144.446, + "placementY" : 194.13, + "placementWidth" : 34.092, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 34.092, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue5[4]", + "entityName" : "CardFieldValue5", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 4, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 183.24, + "placementX" : 144.446, + "placementY" : 183.24, + "placementWidth" : 107.558, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 107.558, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue6[5]", + "entityName" : "CardFieldValue6", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 5, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 172.351, + "placementX" : 144.446, + "placementY" : 172.351, + "placementWidth" : 38.008, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 38.008, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]/CardFieldValue7[6]", + "entityName" : "CardFieldValue7", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/PaymentDetails[0]/CardFieldsLayer[1]/CardFieldsHolder[0]/CardFields[0]/CardFieldValues[1]", + "childIndex" : 6, + "depth" : 8, + "layer" : 8, + "computedX" : 144.446, + "computedY" : 161.461, + "placementX" : 144.446, + "placementY" : 161.461, + "placementWidth" : 67.721, + "placementHeight" : 8.817, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 67.721, + "contentHeight" : 8.817, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]", + "entityName" : "Settlement", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]", + "childIndex" : 1, + "depth" : 3, + "layer" : 3, + "computedX" : 297.638, + "computedY" : 153.463, + "placementX" : 297.638, + "placementY" : 153.463, + "placementWidth" : 268.297, + "placementHeight" : 108.635, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 268.297, + "contentHeight" : 108.635, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 11.003 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]", + "entityName" : "Totals", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 308.641, + "computedY" : 219.153, + "placementX" : 308.641, + "placementY" : 219.153, + "placementWidth" : 257.294, + "placementHeight" : 32.745, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 257.294, + "contentHeight" : 32.745, + "margin" : { + "top" : 10.2, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 9.028, + "bottom" : 0.0, + "left" : 10.721 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]", + "entityName" : "TotalsGridLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 319.361, + "computedY" : 219.153, + "placementX" : 319.361, + "placementY" : 219.153, + "placementWidth" : 237.546, + "placementHeight" : 32.745, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 237.546, + "contentHeight" : 32.745, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]", + "entityName" : "TotalsGridHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 319.361, + "computedY" : 219.153, + "placementX" : 319.361, + "placementY" : 219.153, + "placementWidth" : 237.546, + "placementHeight" : 32.745, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 237.546, + "contentHeight" : 32.745, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]", + "entityName" : "TotalsGrid", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 319.361, + "computedY" : 219.153, + "placementX" : 319.361, + "placementY" : 219.153, + "placementWidth" : 237.546, + "placementHeight" : 32.745, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 237.546, + "contentHeight" : 32.745, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsLabels[0]", + "entityName" : "TotalsLabels", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 319.361, + "computedY" : 219.153, + "placementX" : 319.361, + "placementY" : 219.153, + "placementWidth" : 82.968, + "placementHeight" : 32.745, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 82.968, + "contentHeight" : 32.745, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsLabels[0]/TotalsLabel1[0]", + "entityName" : "TotalsLabel1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsLabels[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 319.361, + "computedY" : 240.594, + "placementX" : 319.361, + "placementY" : 240.594, + "placementWidth" : 82.968, + "placementHeight" : 11.304, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 82.968, + "contentHeight" : 11.304, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsLabels[0]/TotalsLabel2[1]", + "entityName" : "TotalsLabel2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsLabels[0]", + "childIndex" : 1, + "depth" : 9, + "layer" : 9, + "computedX" : 319.361, + "computedY" : 219.153, + "placementX" : 319.361, + "placementY" : 219.153, + "placementWidth" : 50.263, + "placementHeight" : 11.304, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 50.263, + "contentHeight" : 11.304, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsValues[1]", + "entityName" : "TotalsValues", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 438.134, + "computedY" : 219.381, + "placementX" : 438.134, + "placementY" : 219.381, + "placementWidth" : 118.773, + "placementHeight" : 32.517, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 118.773, + "contentHeight" : 32.517, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsValues[1]/TotalsValue1[0]", + "entityName" : "TotalsValue1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsValues[1]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 438.134, + "computedY" : 240.822, + "placementX" : 438.134, + "placementY" : 240.822, + "placementWidth" : 118.773, + "placementHeight" : 11.075, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 118.773, + "contentHeight" : 11.075, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsValues[1]/TotalsValue2[1]", + "entityName" : "TotalsValue2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/Totals[0]/TotalsGridLayer[0]/TotalsGridHolder[0]/TotalsGrid[0]/TotalsValues[1]", + "childIndex" : 1, + "depth" : 9, + "layer" : 9, + "computedX" : 438.134, + "computedY" : 219.381, + "placementX" : 438.134, + "placementY" : 219.381, + "placementWidth" : 118.773, + "placementHeight" : 11.075, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 118.773, + "contentHeight" : 11.075, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalsRule[1]", + "entityName" : "TotalsRule", + "entityKind" : "LineNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 308.641, + "computedY" : 207.93, + "placementX" : 308.641, + "placementY" : 207.93, + "placementWidth" : 256.73, + "placementHeight" : 1.128, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 256.73, + "contentHeight" : 1.128, + "margin" : { + "top" : 10.094, + "right" : 0.0, + "bottom" : 9.592, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]", + "entityName" : "TotalDuePanel", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]", + "childIndex" : 2, + "depth" : 4, + "layer" : 4, + "computedX" : 308.641, + "computedY" : 153.463, + "placementX" : 308.641, + "placementY" : 153.463, + "placementWidth" : 257.294, + "placementHeight" : 44.875, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 257.294, + "contentHeight" : 44.875, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 9.458, + "right" : 10.156, + "bottom" : 9.028, + "left" : 10.721 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]", + "entityName" : "TotalDueRowLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 319.361, + "computedY" : 162.491, + "placementX" : 319.361, + "placementY" : 162.491, + "placementWidth" : 236.418, + "placementHeight" : 26.39, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.418, + "contentHeight" : 26.39, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]", + "entityName" : "TotalDueRowHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 319.361, + "computedY" : 162.491, + "placementX" : 319.361, + "placementY" : 162.491, + "placementWidth" : 236.418, + "placementHeight" : 26.39, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.418, + "contentHeight" : 26.39, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]", + "entityName" : "TotalDueRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 319.361, + "computedY" : 162.491, + "placementX" : 319.361, + "placementY" : 162.491, + "placementWidth" : 236.418, + "placementHeight" : 26.39, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 236.418, + "contentHeight" : 26.39, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueText[0]", + "entityName" : "TotalDueText", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 319.361, + "computedY" : 162.491, + "placementX" : 319.361, + "placementY" : 162.491, + "placementWidth" : 80.671, + "placementHeight" : 26.39, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 80.671, + "contentHeight" : 26.39, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueText[0]/TotalDueLabel[0]", + "entityName" : "TotalDueLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueText[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 319.361, + "computedY" : 176.669, + "placementX" : 319.361, + "placementY" : 176.669, + "placementWidth" : 56.43, + "placementHeight" : 12.212, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 56.43, + "contentHeight" : 12.212, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueText[0]/TotalDueSubLabel[1]", + "entityName" : "TotalDueSubLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueText[0]", + "childIndex" : 1, + "depth" : 9, + "layer" : 9, + "computedX" : 319.361, + "computedY" : 162.491, + "placementX" : 319.361, + "placementY" : 162.491, + "placementWidth" : 80.671, + "placementHeight" : 10.197, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 80.671, + "contentHeight" : 10.197, + "margin" : { + "top" : 3.981, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]/TotalDueValue[1]", + "entityName" : "TotalDueValue", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/SettlementRow[4]/Settlement[1]/TotalDuePanel[2]/TotalDueRowLayer[0]/TotalDueRowHolder[0]/TotalDueRow[0]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 437.57, + "computedY" : 165.3, + "placementX" : 437.57, + "placementY" : 165.3, + "placementWidth" : 118.209, + "placementHeight" : 20.772, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 118.209, + "contentHeight" : 20.772, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]", + "entityName" : "Notes", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 5, + "depth" : 2, + "layer" : 2, + "computedX" : 29.905, + "computedY" : 102.364, + "placementX" : 29.905, + "placementY" : 102.364, + "placementWidth" : 536.03, + "placementHeight" : 35.3, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 536.03, + "contentHeight" : 35.3, + "margin" : { + "top" : 15.799, + "right" : 0.0, + "bottom" : 0.0, + "left" : 1.128 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]", + "entityName" : "NotesRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 29.905, + "computedY" : 102.364, + "placementX" : 29.905, + "placementY" : 102.364, + "placementWidth" : 536.03, + "placementHeight" : 35.3, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 536.03, + "contentHeight" : 35.3, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]", + "entityName" : "NotesDisc", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 29.905, + "computedY" : 115.658, + "placementX" : 29.905, + "placementY" : 115.658, + "placementWidth" : 22.005, + "placementHeight" : 22.005, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.005, + "contentHeight" : 22.005, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]", + "entityName" : "Discdocument", + "entityKind" : "ShapeContainerNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 29.905, + "computedY" : 115.658, + "placementX" : 29.905, + "placementY" : 115.658, + "placementWidth" : 22.005, + "placementHeight" : 22.005, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.005, + "contentHeight" : 22.005, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]", + "entityName" : "Glyphdocument", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 29.905, + "computedY" : 118.386, + "placementX" : 29.905, + "placementY" : 118.386, + "placementWidth" : 22.005, + "placementHeight" : 16.551, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.005, + "contentHeight" : 16.551, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 29.905, + "computedY" : 118.386, + "placementX" : 29.905, + "placementY" : 118.386, + "placementWidth" : 22.005, + "placementHeight" : 16.551, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 22.005, + "contentHeight" : 16.551, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]/Align[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 32.632, + "computedY" : 118.386, + "placementX" : 32.632, + "placementY" : 118.386, + "placementWidth" : 16.551, + "placementHeight" : 16.551, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 16.551, + "contentHeight" : 16.551, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesDisc[0]/Discdocument[0]/Glyphdocument[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 32.632, + "computedY" : 118.386, + "placementX" : 32.632, + "placementY" : 118.386, + "placementWidth" : 16.551, + "placementHeight" : 16.551, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 16.551, + "contentHeight" : 16.551, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]", + "entityName" : "NotesText", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]", + "childIndex" : 1, + "depth" : 4, + "layer" : 4, + "computedX" : 59.81, + "computedY" : 102.364, + "placementX" : 59.81, + "placementY" : 102.364, + "placementWidth" : 328.75, + "placementHeight" : 35.3, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 328.75, + "contentHeight" : 35.3, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesLabel[0]", + "entityName" : "NotesLabel", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 59.81, + "computedY" : 127.093, + "placementX" : 59.81, + "placementY" : 127.093, + "placementWidth" : 26.525, + "placementHeight" : 9.637, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 26.525, + "contentHeight" : 9.637, + "margin" : { + "top" : 0.934, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesBody[1]", + "entityName" : "NotesBody", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]", + "childIndex" : 1, + "depth" : 5, + "layer" : 5, + "computedX" : 59.81, + "computedY" : 102.364, + "placementX" : 59.81, + "placementY" : 102.364, + "placementWidth" : 328.75, + "placementHeight" : 21.929, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 328.75, + "contentHeight" : 21.929, + "margin" : { + "top" : 2.8, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesBody[1]/NotesLine1[0]", + "entityName" : "NotesLine1", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesBody[1]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 59.81, + "computedY" : 114.777, + "placementX" : 59.81, + "placementY" : 114.777, + "placementWidth" : 328.75, + "placementHeight" : 9.516, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 328.75, + "contentHeight" : 9.516, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesBody[1]/NotesLine2[1]", + "entityName" : "NotesLine2", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/Notes[5]/NotesRow[0]/NotesText[1]/NotesBody[1]", + "childIndex" : 1, + "depth" : 6, + "layer" : 6, + "computedX" : 59.81, + "computedY" : 102.364, + "placementX" : 59.81, + "placementY" : 102.364, + "placementWidth" : 186.262, + "placementHeight" : 9.516, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 186.262, + "contentHeight" : 9.516, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/FooterRule[6]", + "entityName" : "FooterRule", + "entityKind" : "LineNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 6, + "depth" : 2, + "layer" : 2, + "computedX" : 28.212, + "computedY" : 83.759, + "placementX" : 28.212, + "placementY" : 83.759, + "placementWidth" : 538.851, + "placementHeight" : 1.0, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 538.851, + "contentHeight" : 1.0, + "margin" : { + "top" : 17.604, + "right" : -1.128, + "bottom" : 12.3, + "left" : -0.564 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]", + "entityName" : "DocumentFooter", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]", + "childIndex" : 7, + "depth" : 2, + "layer" : 2, + "computedX" : 28.776, + "computedY" : 34.229, + "placementX" : 28.776, + "placementY" : 34.229, + "placementWidth" : 537.159, + "placementHeight" : 37.23, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 537.159, + "contentHeight" : 37.23, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]", + "entityName" : "FooterDue", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]", + "childIndex" : 0, + "depth" : 3, + "layer" : 3, + "computedX" : 28.776, + "computedY" : 43.153, + "placementX" : 28.776, + "placementY" : 43.153, + "placementWidth" : 276.479, + "placementHeight" : 28.306, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 276.479, + "contentHeight" : 28.306, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 2.257 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]", + "entityName" : "FooterDueRowLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 31.033, + "computedY" : 43.153, + "placementX" : 31.033, + "placementY" : 43.153, + "placementWidth" : 274.222, + "placementHeight" : 28.306, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 274.222, + "contentHeight" : 28.306, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]", + "entityName" : "FooterDueRowHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 31.033, + "computedY" : 43.153, + "placementX" : 31.033, + "placementY" : 43.153, + "placementWidth" : 274.222, + "placementHeight" : 28.306, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 274.222, + "contentHeight" : 28.306, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]", + "entityName" : "FooterDueRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 31.033, + "computedY" : 43.153, + "placementX" : 31.033, + "placementY" : 43.153, + "placementWidth" : 274.222, + "placementHeight" : 24.356, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 274.222, + "contentHeight" : 24.356, + "margin" : { + "top" : 3.95, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]", + "entityName" : "FooterDueIcon", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 39.121, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 39.121, + "contentHeight" : 27.836, + "margin" : { + "top" : -3.479, + "right" : 0.0, + "bottom" : 0.0, + "left" : -3.479 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]", + "entityName" : "Glyphcalendar", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 35.641, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 35.641, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 35.641, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 35.641, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 27.836, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 27.836, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 11, + "layer" : 11, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 27.836, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 27.836, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]/SvgLayer1[1]", + "entityName" : "SvgLayer1", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]", + "childIndex" : 1, + "depth" : 11, + "layer" : 11, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 27.836, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 27.836, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]/SvgLayer2[2]", + "entityName" : "SvgLayer2", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueIcon[0]/Glyphcalendar[0]/Align[0]/SvgIcon[0]", + "childIndex" : 2, + "depth" : 11, + "layer" : 11, + "computedX" : 27.554, + "computedY" : 43.153, + "placementX" : 27.554, + "placementY" : 43.153, + "placementWidth" : 27.836, + "placementHeight" : 27.836, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 27.836, + "contentHeight" : 27.836, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueText[1]", + "entityName" : "FooterDueText", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 63.195, + "computedY" : 46.33, + "placementX" : 63.195, + "placementY" : 46.33, + "placementWidth" : 197.629, + "placementHeight" : 21.179, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 197.629, + "contentHeight" : 21.179, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueText[1]/FooterDueTitle[0]", + "entityName" : "FooterDueTitle", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueText[1]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 63.195, + "computedY" : 57.6, + "placementX" : 63.195, + "placementY" : 57.6, + "placementWidth" : 122.528, + "placementHeight" : 9.515, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 122.528, + "contentHeight" : 9.515, + "margin" : { + "top" : 0.394, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueText[1]/FooterDueSubtitle[1]", + "entityName" : "FooterDueSubtitle", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterDue[0]/FooterDueRowLayer[0]/FooterDueRowHolder[0]/FooterDueRow[0]/FooterDueText[1]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 63.195, + "computedY" : 46.33, + "placementX" : 63.195, + "placementY" : 46.33, + "placementWidth" : 197.629, + "placementHeight" : 9.497, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 197.629, + "contentHeight" : 9.497, + "margin" : { + "top" : 1.773, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]", + "entityName" : "FooterSupport", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]", + "childIndex" : 1, + "depth" : 3, + "layer" : 3, + "computedX" : 305.255, + "computedY" : 34.229, + "placementX" : 305.255, + "placementY" : 34.229, + "placementWidth" : 260.68, + "placementHeight" : 37.23, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 260.68, + "contentHeight" : 37.23, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 29.905 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]", + "entityName" : "FooterSupportRowLayer", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]", + "childIndex" : 0, + "depth" : 4, + "layer" : 4, + "computedX" : 335.16, + "computedY" : 34.229, + "placementX" : 335.16, + "placementY" : 34.229, + "placementWidth" : 230.775, + "placementHeight" : 37.23, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 230.775, + "contentHeight" : 37.23, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]", + "entityName" : "FooterSupportRowHolder", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]", + "childIndex" : 0, + "depth" : 5, + "layer" : 5, + "computedX" : 335.16, + "computedY" : 34.229, + "placementX" : 335.16, + "placementY" : 34.229, + "placementWidth" : 230.775, + "placementHeight" : 37.23, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 230.775, + "contentHeight" : 37.23, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]", + "entityName" : "FooterSupportRow", + "entityKind" : "RowNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]", + "childIndex" : 0, + "depth" : 6, + "layer" : 6, + "computedX" : 335.16, + "computedY" : 34.229, + "placementX" : 335.16, + "placementY" : 34.229, + "placementWidth" : 230.775, + "placementHeight" : 32.716, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 230.775, + "contentHeight" : 32.716, + "margin" : { + "top" : 4.514, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]", + "entityName" : "FooterSupportIcon", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]", + "childIndex" : 0, + "depth" : 7, + "layer" : 7, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 44.011, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 44.011, + "contentHeight" : 29.341, + "margin" : { + "top" : -3.668, + "right" : 0.0, + "bottom" : 0.0, + "left" : -3.668 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]", + "entityName" : "Glyphsupport", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 40.343, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 40.343, + "contentHeight" : 29.341, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]", + "entityName" : null, + "entityKind" : "Align", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]", + "childIndex" : 0, + "depth" : 9, + "layer" : 9, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 40.343, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 40.343, + "contentHeight" : 29.341, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]/SvgIcon[0]", + "entityName" : "SvgIcon", + "entityKind" : "LayerStackNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]", + "childIndex" : 0, + "depth" : 10, + "layer" : 10, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 29.341, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 29.341, + "contentHeight" : 29.341, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]/SvgIcon[0]/SvgLayer0[0]", + "entityName" : "SvgLayer0", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]/SvgIcon[0]", + "childIndex" : 0, + "depth" : 11, + "layer" : 11, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 29.341, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 29.341, + "contentHeight" : 29.341, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]/SvgIcon[0]/SvgLayer1[1]", + "entityName" : "SvgLayer1", + "entityKind" : "Path", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportIcon[0]/Glyphsupport[0]/Align[0]/SvgIcon[0]", + "childIndex" : 1, + "depth" : 11, + "layer" : 11, + "computedX" : 331.492, + "computedY" : 41.272, + "placementX" : 331.492, + "placementY" : 41.272, + "placementWidth" : 29.341, + "placementHeight" : 29.341, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 29.341, + "contentHeight" : 29.341, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportText[1]", + "entityName" : "FooterSupportText", + "entityKind" : "SectionNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]", + "childIndex" : 1, + "depth" : 7, + "layer" : 7, + "computedX" : 371.836, + "computedY" : 34.229, + "placementX" : 371.836, + "placementY" : 34.229, + "placementWidth" : 182.481, + "placementHeight" : 32.716, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 182.481, + "contentHeight" : 32.716, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportText[1]/FooterSupportTitle[0]", + "entityName" : "FooterSupportTitle", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportText[1]", + "childIndex" : 0, + "depth" : 8, + "layer" : 8, + "computedX" : 371.836, + "computedY" : 56.531, + "placementX" : 371.836, + "placementY" : 56.531, + "placementWidth" : 119.69, + "placementHeight" : 10.414, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 119.69, + "contentHeight" : 10.414, + "margin" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + }, { + "path" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportText[1]/FooterSupportContacts[1]", + "entityName" : "FooterSupportContacts", + "entityKind" : "ParagraphNode", + "parentPath" : "PaymentsInvoice[0]/DocumentFooter[7]/FooterSupport[1]/FooterSupportRowLayer[0]/FooterSupportRowHolder[0]/FooterSupportRow[0]/FooterSupportText[1]", + "childIndex" : 1, + "depth" : 8, + "layer" : 8, + "computedX" : 371.836, + "computedY" : 34.229, + "placementX" : 371.836, + "placementY" : 34.229, + "placementWidth" : 182.481, + "placementHeight" : 18.994, + "startPage" : 0, + "endPage" : 0, + "contentWidth" : 182.481, + "contentHeight" : 18.994, + "margin" : { + "top" : 3.307, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + }, + "padding" : { + "top" : 0.0, + "right" : 0.0, + "bottom" : 0.0, + "left" : 0.0 + } + } ] +} diff --git a/qa/src/test/resources/visual-baselines/invoice-v2-layered/payments_invoice-page-0.png b/qa/src/test/resources/visual-baselines/invoice-v2-layered/payments_invoice-page-0.png new file mode 100644 index 0000000000000000000000000000000000000000..ee7f1c12b59d88ea60420a7f7fee0e2edaaf5937 GIT binary patch literal 100748 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%0AsaqXfd0%V*aQBMP7t2AWHfCm& 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 h=}4hA?puvja_>$3M3&|6 zmm7QZBabR=Ld^SEk)buklX&|p$c7-ys^_=MTaj=WLXY*m&&`vghu*MDM|6euR(1)hegl}>2aN4`9 zIeD;N;3?&wG{?+J?0=TshKgP|%r7iGBBy5rDtD?ULj%CSUD@|;3WD7uV)xqtco!yu zIvuBNk;COng>6vXD&D&tvblym&6o(4{)LP=D;w8k(~+7ep9myEFfcUy1qc4Y%Ywvo zLxkw>5S!D1$X#8+18G?wKSg+-vH~ZW2AssQoV?mveH&BtDF7o#zW{s(neLYIHnIm} zus3?zQJ)oN>gt&!Ur_uMWva|fNC^iM2fUTXj&~ojheug;rmJMe`}`T+cswRC4d&y9 z7pS_dY}6Oczx@?ojmjx&zMsctSVs#f5=7nSEfsKqspzp$%#)0XZlJn;X) zp}U9aCZYusn|s>jOF8Mk(5_tOq+U1eAUrQ(s8i6csKg(=JP#Wx?IV-jQ+7>S;7Dcj zws6W=CTk9$c2=}!d{dG0!+#gnK7s;8CeUInP~23Ju?)_=916A7{XX_KG;k}N&UJrP zq3b7o$h=_8$59JQv`iu{-D?U2Mv|7`xcA+VM6&O$+HhA6U zktrtVp*M?*IbW^XR@GGWxmKqpD6*L`wZ;?ueoyG?G2sa`RsCDq*SCp^B+2V|6W<|< zaB6x8zn+GH?0=vAE%@C)&y;A&e>Hv(=eC9){gu>V07E>TH)Cs}%S>*LUS%;6lOEoe zTKA2^tjP4%>9cvQsWsJJ*r^=K6K@5(RN*Dm$eQC!a%{P+#YI2Z_{jJ;hkx?IA-3-q zk+!vLxg1Tao_NAt0B@{)`*W<1X|T{8t!SShv4)5!1*3v%&LLw>mJ+wgV!!YFjG5xC zb=FzP%*5#aiq~}kF8zSYuw59FH))R|{>}Z5NQ4 zzRr%0KpS$u-JP8^Blyr*R;E%{7cAOjU7Ro9&$6JTmrv!9p-yzPv(Fxjtf&7aM1d6^ z+f`VBi>(ld-~O^|n5-#hqI>K5(}&wV_KySy3R=Nj{Z>8}JYl|C%9$v4WPcuEE?n2Uvb9DYCnHJaczN1M^K}2kB+F0fp+BV{6RUq@oSXGy8^dafLS$ z9!}|lte%<}XsUr@DO2SJhoL_xe$s3NGi5C8BKwOel1B6hg!! zN)cFk=5ZP!UNAK?nUjzbP4Qaax1$I4ZKcWrfb}I`-4`kM#S1yc0l6DfMFM?jqay1dJA&`8v~i(MGq*$d0gO@uyuP=2)V;^ZO<`gF4fx^zE$Dd z-YD!^pPSwtk{W(qqlx+pFvU%Ul?vmr+6g-S7syd%G9fKxWGdIbjS8bZAq+4)+r?8Y z_q86u`NHUt#FJSj7%Z8@Vbs{*p50~>GlNV?6V5U)^K6VdBnU&sY-nf~UuzggClN6W zo45cOIX|oJ3H*0-=>#?WZxND%X@>v;`0^Av3HS0-RhmdRyQS!5q_nfaaQF;_FeGXm z&xwt;y%p6PNnedc+tJQ{Y=ZH6f!-XJ==S&EJ2X;$@7U!RJ||>QuHRBtwphv)WU+uB zk>rU^>(p&<`E;Y3B}E)S=N~3#?GvM;%IHVr;-D&gkWy2{UPy$pgem;j)0TwlKSofw`&B#!Q;ok(!f^EOkHh3T-juVRLE8>iH6 zk}Y)0$@SNrJ?b2>H_y(W;hs`+)HLsho1pH{lv6X%q7Vmy{muzNC>q?LUHww#%**8- zipw#(IH9T%)2Yt^5roT?&rS{Y!uGko?3WaSHPQUW_bFlVz=bCe;8igf)qOS}(Hwz^ z*W-?Q$uu4yU45zhh#248phQm5#d~x?VLQC54mIeq4x$b$=TDoge$w}RLZxrUecU9v z|5VWRSKm3}ZM_DVuNjKZtq!s#-BNTW%`F(cDV7IsejH&UtStJKU8$w&9-7YO1TG;mQhfvlPOYn) z+G7=oHN>KIf(oD%R2m%aA!}9v9xBp5oXmH};*StbI>EcwgIT&h{~$b}T=j{ihXVYxUtq zul%CNJ2CHC{SuP#2*fb`Nc_KEQqfj4F@a={sGdKX)IOwsl}KPx2Q71VM(*Qrzj5+E z@M?dGUMUPmm+SQGBC06BTuMLLCZ+u@_7UOHvHF}OXO1?^h|g8d-BuD<(1K1KB)Pr* z2uPj~KR(LfuOle?yi*EfPS-p)o&=zd^}jt!+%&pz+%Hlj(c6pGvJ6vW^6?!pVw35! zQ23oDq&1}++RHm&z~6K;5?@?k{rIq>tVll$Rk>T#d3i4bJ6Za>y( z$$aLbhmVnNQ*jJDtQ3NgM+BLR*EpcE?mWNCK47Wjy4ZSJ?08ZzDJQ@$JZh(HC`owpcJT^% z=rA6=L1y^0@RMHYK89M4h|^fffUohqE@rjz-WS&%IF6T9I&(1bST5r@hB$%V2x#>J zjK}YIvs1EXh|bo`{6@6 z0H~0}eP~abR+l0%))+BN><$8UH^n0nZ|U_B^_|eoJxK^E`0k8*PM-Jexg@kb-*yU* zEf?y;45r7cX*8U+hm}p7mHE8F4a9T8crLHAyp_kQs}ItTkw%-#rMpvbq$2#|73$Fe zV_4NtF?h+1T~_F%dm9^Z^Ky`$sx10WV-Nx4(LZ9;WAG;j33K|}MK)}1`JgRn`YUZ3k9npM@7 z!Y&1_m6O2W5yZRw&8Gc3N=yhsL7#^5QWgWB?>R)hf632SyT3ORZ#MQkABES?W;2-i z$;K@|?qiUf_ru(!NBnoo{Z)DipCjcy*Khbd&D4HC!zvu%W9e@}eGbabaPE6w!%W`( zA2lU>EP38EC>4YR5<@}d$dpfiT`~$3=!cv)av$gA5)@HwJ0Te3c;TNNk95X^37>BN zyt>&1h(ScnNV^-7kDXqwX5vJv(PiXn3{5U56QqZ+b$21uCuN*CI!*o>FBm({;)|xD ztC<-$E0z7R{^7Bw;By(2D81#kr{ikMXRiMc|L$*ZDf0^Kdwbb0JKX(*P4XrHybccj zd#$>XzhKU-X0uNZ_Ex@yca5ahNfs8A?izo2d-^bn26aXW<|xw<5341%@DU3~7n5SU`6pW*OXdhV(O^otRZ| zB!=nXi^0)AiT0iub-bvl9^Z!Zfl5$@2|Jj52u&umfg$<&{GnA%Zsvs1eg$$uV*ti3 zbArdrrPuMnNznCJ=~+?YE|JrMf`}Kt#p-@`y{fFpE_!dFi9_}COERb?#fnPJ|LoC| z?!?V=EZ8T=Roeezo}1+JX5e*PX6E_U^5I2F#NoGZre0ICP6_U7%3)@q2Ljos;-6j&=Vq&@;okAVotCh70Q<`w(kDi z0Ywj!j`4fnPH^b2d@3B7EVE3VfWVXKOWw=Z*C+^%2E8v|-9J9O*MDdLY!7dEW^N8i z!0&h*ADW*2xNdq;ckmHt8oL)k>jlM%&qzyvtogw}=GVS_dY`j0I#FD{ zeOFX9z~&2-1;1y6f?FEFxDL=Sp(0I*|1EFCOxw^%2^9@`uz0w*ola{Bo+2G@5d9lA zzkkWfpiAZ~6npI4iBmlYEOP-#9V>SqtzGwHuNR}bgTOlAw#$wH2Gy3$QO z^XDbU2;oPts=zVpRZyPb`5x8%q%;SX9ACHwZvMqLZ5F$10(;Q6Q^LHgnDSEjGeetj#0hvDa!w%2mq&daz6EXJmqq@x$gd4g~;sKLo$4AIW`{B0Aha zmvevrZR?V+fH6@jfe}V|Kdlu%HZKn}yVtj{jL)&m1#fmQ0#1?Yg}t5><*ceI1F=|i zU5#6Oi(p$bfaQdAjW+l`d%btG(q_pc&PdVME?UU#0~be&qH0(Tyl{Sfb>Kz<`sXC0 z)f*sy2V#kSicWR346{N){IF63X#H!ruoAQC%QVl0A477e$S38P5gryJ5YQo~wV1_@ zo6;K<cGPlDD1_0{W!YEk2W7-OKNO1O{;N^p zJv|?gYTS>7>WZ@X%xN?8=ut;Rt0415%r(=C_AKE|s^I;f+}v9?UYz&PO9Bt@SuU@G z%uF_ll2KlA>?#i$4t(HPkwc0A^hiXT{Tl(#5BJr?tE-kltHUMUzs`2u zaL66;+Ur~ArxEYPrOpuPwscy@d+Qbla={9>+p}v>>gy308sLDrV*xWfBVUV`{;u;- z`h$a;k))lSXOWTm2|eLtHF)F$B`MDnSfsk(Sqt{ri*T)aJLz-Mk!Lzz)>e1EUKZit zaAm!a6Ds9B)LFUgX-n}0_D#tBI^L-u<}*zalmGJqu%wbERcX)vE>n&VTC;dqI!Iju z8P$!&U!8{&3YOLFVeoRr&g%L%)B3&s4$obtfcC8sd3D>RcsE?$k zf^gd;!6-?c*+oCU#K+ezD^;v3*sKoW;AeoR-}^I3c`XGQCNfD>pU^-@X>*1FCWcn1 z)9${PKHg!si~M9jo7=S=q22f;K3(0&@Hj}AnT1EeZY~avtoheqypT;Ry`u^cyL`M^ zC~`E%>*+t{%?#K<(eG+_XA*w%Vw$bYTJ((+_U%~^rjzrm464QcY!%O=h;*Wif#8&6 zZa;@0ib|1@NMzcr##MEi&8E{w$1882lD2FL{E4e!q(NJ#Nr7KvQZXgn*&sz)^aL;{3h1DLhQ) zw>I7Paxkto&23FJ-&$hV04(Zi6Xd3^0o*C<{y5>hS-*9!W?|*t1#vTRe-|?>x$Mau z2j}ho(PS-`BFs4L?ZQ4DHhdF-%A-AH@NzS03DRUl^!lr6yk2X;VeEV8enBcUp!s)? z&Oh6HH2Cgs9|{V?-*-gwd~W3ntjx?C8?VU(j-$#QPZAiD`G}U4JRbaZCfXk+e?Kkdoh7!>$Sz+Z*-(@r6si89ktoQpxWB@%kVg*X^WzktU zt3*Jf-aH)vt@NliCrj0t{}WK2gIP|BpTYD~0ccR<6Q;F<-^8M23xN5vvRVtTy-Cmn z)@p%Q2(HZn=<`7PWTP#l5Jw0`8MEVEEqn^q(%>K&Pss_`9&Hu$`5m+(FeGh^qWQ(f z0akYf&I>0>Rw5nc%A3CPwszBv5AAh=i-0?OkGu2|VCEt+09w8ZpU%xw0o(r_`G&d7M^xiHzN)ou*FKMK+A z&%4^f6Qt!}NI6QU{oPcasObuH0-{;v*`Y0JHji4WHL>6$l*lhl({7nPPT#yX{~)E1 z*|@yy!#C1lyy?hMGkhQSs8Rq5pZI?_@1b1HzjUFuaNmaNr%?g5|qKS&*@7528Eb|j>1cOZG#q5kdLR`|nn_;-&$YIVee3SkT1XFd(F zRLLPzlB4J<3mUgD6w_IminKA;17oq!lQ|&MGoxc@DR0alm>oj71vZt+FE9|ks~@xT zcYwwlZO3Dr>*oP5hpJ%fX&QMg6gL4O}rGS4S$I9%EzdOEE zD0~U8{qm!bMcMs!!Mir=adu`z1_s>tqRBa4dm6DJxZ&y=N0Ao*58`%cAFn|6)`?Td zTKTa2T+G!E-}j_!jO}dxJZMly-oYKzUhFzMd&e9S)l%Ae2_VhU>Z=1g^^g`jHPG?V zj}#{Hmsi9KWB#+wUyfk}&0#PN`hiBYFJt|_B6@Vu;hshf9Hc7O$Fq<0K$uaSH!$bF zhw4Y**Sm{nR%YLvo$k!a;=aM7_w7g43`JavGMDOxn8kEMfHtQnpW{&n;~I~lYmnJM z2dc?YSZo1RPG6+vPA!S;+Wj?pY-F;I)DRq>Xa!B*mBG8r`|jMuoqE}e#hv_jWTHFe zc{MQ>KAWI@#dm=7~8{Bv40qf_-R5hBsoH(*DNnT+;=0tMW!*xRA>|| zWA}@D1ziUC7qlm9>g-Rb`;fO!lv=3L4T{+DQ% z3a;(lXN-_NgY~L$K~q5=;TKkSu)SgnU=PZ*6?cK(imcbPjhiX~X3cRawHd#l2w6ix z35Xi2AQ?n4n3eGORb5Th_R}~?C%}KFKO3HP6;MeMl;`5Vx1gat$Ohc+@)gF?Z^otA z*ybS3YZ&(^2nwec->t28#WSI$Nn}A=Y#n0%=K!S;zRUTOyt%eV*l))>AP$yGTM*5P zoa#W2s1T%LMB>0ZB~|Q>I)NJEV(nDJT-gk512tpJa6*jQt8gLvRue6mYI(FO#wQohv_YPo!h15cCLp2O-_s<;l7JwWXH{5PhGWq>Ga%EyG`(2%Ld6^M z;f-cs{)Q2k65X zM|})N1(G=FYeh_%C=+QOjjjTiwJ2&v101MJ^r`3vS9$1AL&Nm}oQcTX@@S6Dkgbdjoo>4a)NzY`>6_NxP)L?XyO(OM|(gaU~Z9hrpPw-8A z;+=CXdC$w0=3T^G;l}u9#Pg8E(pvSFyt1qh+?}n0@y|btAY>~vA_96OGK|UJ-0u#f z{8w$vzJ5|D|IN{CVYbJp%^S6HT~xBSFA%BjDnEZE>asb}u4ESHjvvI`dm8-OEI)ZYtk@~<0x3*VqBwt~ zZr)c;8~SJBQFrjZTDbQg^mp0lKwxQlsg_0JS(Tkv|Jsy=F4Rs5m`G zZ0K;{{pbJ6gD1`e8vAby;k`xx4(<6``Bo^Y0 z(|ykODo6_A+F&58vZG$ByUuvO%UzGa!=S`-*_PEV5LBwF$|b@Bx9Nz%r}L>6VA&_D zg0uX?4et81)+@NOz= znW5<;IEs5NLwG3ou`b7ha;IL>`*Os`PA6&J=`nsGXxWb9cn%DgB`%^ww`H1r zANXB+lxCL<=+Ddrfm+G3r86}M-MP$QvKFQmXf`aD0Cj)$6~LS2@EQ_jBkvaf0#?+M zSF>g4vRt{Yv-|3Il2X1a~vO@w& zz70aw^(VK^XUxR$gliGmR3;*#@MoFv9+K5qswGOZixVM;@SV)>fO>+`#M*Wzk5kYfwW@w^ooYKh1KVl$tk#$}3 zND#`_sP88*4#31bR&2n%Z;#l?59lM@CLxLtP>WcS1Nl}IM)kZh{pdEhDTZG>%d#p^ zVsHh(q6oKc1hGVhm9?ckLxWYh)!43#G-}GcK~}o@KP7iQuX)Vy zG{o;=@;zsSo}j<8(1Y7rP8sUDmy@E7+63e)a&?e;VT3O1V_z_muDeaa_^^BUtU?tF z@#7>@OO4fGZ`jQ>TtGg5 z%BYdSeK+6Uhy%)2|G*)0)W4_e2!!0BV}K=K?X_~oDDi@aFhg58 zAZ&-eWOp8*Z=aT|lbHIcTvm_;Ry7Q0C%E13bc|)c?DObR=T|pdC!}iVK4pdma&U^M zcOh0C5ZsU3?{2D*dHNvW?tB>B0}uxAmxcMJte>VjOa7;kAHSZ5&sS^HlF~A<pX7FK;qF@U@<(sZCmGgxLu-9N2U*$pz=NC0b0o+p=hForLXxO=O9d1KX z+ap9H@_zCaIl`mKW~|1%o6u*=_x4MxjNQF*l}b%{3CXnrrh?NJbwE$l_sE413$=LF z_1FG3KsCBR8=(7Y!1h>!X&#S%WOQavR5UT6ms6K05{LZc`7Z&WO0g{6+TTqbfxHO~ zA9z!{u=n8STgqo74XEDYcn4>B z_JfJGQf(}slSgx$`M+1fbxWIO&#^N0f`ix?Z~XT%3ML65&yTQ7Nw=#(13f+Xt3On0 zf$gi}M%e~zHi`Aj2GXewMya~}%YrabU?n>_UW2Sc5Nh~)dHh>2`WKM2h_y~Wapggm zxS^p*m)RntHrziz_w}Hf=p|p4qQiZ-V8{tUsvmlaM4xdFr4i1XPoU*5|Jjo=JKNm( zzBub+R_-lWy6Ceg5hoaLmmMR@%TEJd;+;0+wv}qAX-{f>*6PCF%4jmEwQqaXMT844 z&ON&{`4q9O&ScO5TyfwDsaW~&e^zRNVe5>O{P~OhtMBP2{p^gxkD(D~p?@pwt|(Tz z68DYW7g3ocjU3!;Rx&@Xbp?kG?CcUgT`$|9l?*@t-|B4#1d<&#f=ujo( zG77fCJY0g18-S#l?OOw9=-ni-mENPsMt;k} zDv@z@f1h~hSD7ADLo0qbvW*LN1Rth~`t)a|ITCHU4pmi|-RvOfE}o^QQ~N}9m+I>8 zx^LOY>x%gs3KGD;;@8JOiY8x3p{aK?>v9$LOG$0z4{2H4;!x%+88CNwrvnc0MoBUVKe?^qgC72niDCcsX z)_Bq}!+rS4BM=yywpma@78w8i+qYzkdUf_qgou~DVN>U`7A(g+-z!k6b2kNoHXdLG zn;UWZ*KE9ulf&dMeKrVqO8#qWEbxhtBlO0%!KU8`w&|K)^(3 z+VmlHbFWRPwT$0UaxCHX2|z0FBfg!(=W5>$dbP zgvFmSR5u)&e(_{#%dD&^LCScM{1zA2&I#o`H7VN!aixyY2~XzeECdqxnU0+wHlRa) zU>1>s0Y9-Uvk-Bqw=dXiw0j6RX;>Lr&~+^=1@~6jM0Uav&Au&vQUD~u|6h^-YMk0X zK0~Q#tWmkmX-QoiVD!I zm1>&FYGJdl9^oa$Mn|ZtbqASA8B;o52@;J!;NK~vae3>NlNXgl^pazt#Gz>fD{4oxYfVekYuGQw^ODf4CHv|k6~I8-;V$;@7P zp%G0Itwo&O<{00aAikJU*0wQ24Pk4cu)EVy2c%yX$qlnT8<8KhDEm{jpj9U9f zpzrPNA9qqkx%Yk^{NHZu`@Kmf+2$~(PMp=8S2#{D;ZKN%B;AOJlCU!pp|_(F6;vl1 zvnom&^AQ$;BicKGoPp zDuJE2lS%?Yhl&*4tCaN7dkx*+c1x^z$Bju#Yyn_v;R%Qcsq}R-Sr%h3qWqsQn_WL4 zMbsQ-%m}9sNfDN?*d4z8T5W5yD?&iS=!0Hc@q^HoG`@#S$`k4okjvUD&soG`q%AR{ z-r!O7Z2ybY)M-;DZBWIt5%c5)F=EC2&V=219G5R#>JdQB5ElQ)YuXALlTsFrmkbn{ z;%d7O0RUBqB>o4(80I%l87EIEG7zL)*1UPXGsp)A2HqjTfA9u|t5)Enc6n*S>mJoI zV^?|W=60taw%BYJ{s`{)=fmS43h~s>?jTusTuzPlyhDseQkKeC&|eO0lE7H?d6ygr zVkFHK)zs8hey6Engap3NH?Z}O-k~!UtVYH&l%ZrwYAAGJL!vS{0;5#nb)dywgSvQ3RN@l?o!&XzP8d1pM2r5b zzd=L32-%~{qvYbLVTXsUYJ6#y`u%(Q@*R$Dhk`A_9PUL_keU?f0Ewut5a6WfuZtY7 zFY25xB2SY)wvVB)afG3CGawDva@9LHUyCGdV7$tGskJ~VxEW@=#yRB6pht2OUHqLs zcrf@-QIMTIyfvgda=+l+&$k#dH8sxmESP^d=|@U@@85e=D(xUQvUB%$k%e~~8tXYo zENWT`YV>|;*EiC{J>C2=ZkvQIlw{P6mL`J08!-ws-&HE6{6Wx_nOqQCwln`Gwj5rw zqzY$xEC@LMCg87LM5~;GGWcY`Fs1?Px%bYWq(m7pG?5sgA7pZc_Z#h8SB0U)-3Gz? zyq>!H`9Dms;>Yp7l`#?YmFhlu^}a>>+1qFOv#?2QYKA=dF%9`2(m{~;Ogdht{3G~@ zrTu?(jQwxZm(tM8@-q0RfC&^tKt^;fg|>XwQvUzhJQgwx1VDZd2RR`4M%+s7z)bW`_bOqSNq4q(Bnu;UAn=w%xtk zsZ9n{>SVB94zfqHmwzTScJX3x@i9No-4gOyeVv@JFf(%!_{Tf9_zd_&esAp`CTF%3 zMYBNXjDbVQWw*+{lqeA;jTcGV9$-Oedw+q$33!fd?jQE>kB_%dgj}+$jAXZdAW^+` z%=5VgZXJ+l)u9Z!h$?QiFkj}cGQ6nK8myPIVv}_!1l&C{pQa~=P7KygDH;^aIqYgDcv@mlVi5Rrl7{UItg(FebXH)ySH~lz!EF!I^>%8VJkv* zcxHl`blz`S=c!KXqf1FHY7}T!55M_Cs)_Om}s}#Gqgu(~;Nd(N!z?Sz-Y| zi_7idO2c(-lbiS>uO(%iX}^XlqQH^;a%ITC~nq{e#dk z6}zT?e2yE>x=vsNgSQcFH`T-SowcsK;=a{q-1|z&z!u=aOl&|^e+V>O&%%M1=OFeq zFp-J;=NnGnQpHM-3|?QhM4Qnp3nN?b&bg*FgF4@?B3oDG1c9$9uV-P4$S zgKG{_KC?=KMhTjg_!y)^L7&lM+$0#=ELDY@>#xf>sj`&0Uuy*1Dt^z&CbmeWmezc)tY-5Iv(1CNh-q1BPO2-=NL(Q# zK*^v_(6o&u_W|A9a;e1azE~f4)M!a(d0`A*d{nL@?Rc@3jrt`}B3JrTO5nfU!C^-< zf={t*CteC=T$~6BGS(Rf{1mZ;ZC4^>v)j}2-egu{3ZSzd2Qy~jg%ZC960WVz?Rd;Bk#x!(2eg|4YwN-@ECt% zl`RGxL+QnR$>uJ3wqb}p8b%Y3^-Z5?H!27$2WYI=q)3sgy&>HMU z;s#%XidjQVNlI*PKF%#HmEK%py`@1b2t5E6+SXQ)p@3WTZP(jg+nIj7>BKM_WS*lv z;@H`-SqT$TnC@cGjTRIbWX%PnuZ#L`Xyt7vJF!9ix~a|An49=US8-wJZiobzHt=Xg z0b9SIrvx!8kggba3q@+%eKCqEPE{s+IAwzcc{1y!E?e0cN#d_a$p@H7zj6*(t`xjf zc-HtJF9HoqSI)#o_Bo5WsnR)s7A^L9q!{ac$Jy*U3VYzZNa+cW zENL}=k^d94hVi(Pp*c$XEUcB_Iwn<7{Co+7X7V3spG6>rey_Q)WNd#X{`a1bb_@Gn z7%;uKWLI5w_Y9HqZuzaTtFJq@`@~-UV!?4#1fTgNPueXuK_ck;U-fSsbVS?&6-|Q} z%<2h(2i!J#2wiMk?*|TDBZuB)vA1Ae$~1?Z7O5#9z~MZOR&$Q3+ku8x59_Ik6nGil z+~O`2Uh2E?310LNX)1MF#uUGx_mtB&)K}MNgt5eE7Qi!TdGG)f@ZrOYneBi-09GAH zX&tNaL)dcR`iIxw3`6ildmVjNZ-+t%XCUa0IEGJKU3va&gKRri?b1>{d-i;(BE2Bb zs?#N44Td6-LDF0S&Nwj>bDg#-pvN0f_^*P=EhI4_5zPxIx4M0_1!xt%+jJOt+f*14 zTL0KJ6ht(Z{`_OB3&b-7jXn4tgK2!;FQmmqKE}V>7=nu-eQnSk#9nv!iIv?^PL5dU z52zlv>E}9lf;aRB$AUj&orCqv=I^}7(;%gX&1F_cJo|0G%3=EE4l#Ia~2#A!di%M zHx30esoqq{$XoGfVf!x=3AyK#WeBi9f!*c+Bg4Xb8xiqc6atFE=~dXb&;co_K?eF# zP|`ZNIGR@RzVYrRh@^n8Vaw$k+cO?)5P{-}OsWf6w5<(FM?$WSnv zd3vkaV6ehYyDN$uVWOt$@DVSh?Wi~k&z;0U;$K;$V~tRKEgNkq-Y5H(6vr7_u`?s0 zkX!Z|h%fXY<2!EhW2Wy5i8rivy|yEmJ(>kB~B0&lo?kQfGW6DTIgBi@i>8&ByC&|1va;-rW zKx-r@g%ZV$yM0wT1sQwlfT-u_Inf>YC zo?B%~s|yxapu1+&JyX$ke|5ZHr{xMX+_McGJJ*kIi-qbNNcYOfc z?%d6t>b;|rA)4Di&#k>tyP?#7yDa<{?GT_)0^mTTR9_^&(kM2C(rfT9Fhah+)lD~k z>Ws=IAkA?I!&I8Aw8c60e|Zm2J(9`*5~e+U?3;Yw@p7v4_6e8g<>X8r!9H6H7IzQ! zWB|l`jWDh}8P-p6-7Epm%1&mb=iQ^<`<%W-Kw?NED>!U3& zEER^gXjFR(=-NSPzE|~YF?=DOlBN=xHn$Z&5?puz^c(c@opNuojqS+a&>4;JEU4-zMVM4zeSWX0iSsv5q8wr4 z>nC7K|KxLM(2c{Vr#>X=by88kjMPUK9O3Q`m#QrW(z^N|ctMd=>HSZRLjKmew7*A; z%BL?l{y}drG(4_+yPmaEQ|!J&$tyNv7Q2jfxs} z7l^%y9R>>EW>&a@%>Eq*_TXM7+GPEBAhC)6CettdVL-C#gqOfi0*tw|#$5@ZEjfgY zqY~(T(s5Re6Chw=XD=?}RHM@k_#X zlkAap5(TB6W)O#^>7Pf!d4QLg*wA$f{YTYwJ6<2|Wd>F)i0MSgpnGFxaolHx0SYmC zcr=xPdk_bb7-D)yp`!2f1Z<58-@V94=hv&Bql41ke?{J8KFI0Oh?}A(MV5e6p>|^Q zXO_0c(Lm{l9QYzrVGIjLjv*^MI_5;ty0_G9jLZ8=2ESyPndEyLNbcLPPJrCe4oA~w zyosRyb!-2?;FwVSmm(6fh(>Ag7j939jEyx7Rk>a0xbn)@C^mA`sWGbybf33WanmJW zKvhKA1m!P-JOEvov1P@+JCS8^bUSUNQ&{3;OVgfb)h&kVad4fE>)kAG#PiMjH;lvY z>9xSC>bIurToDJQy@2te_!PKZ-t^);i!Iz`za0LL_63y4Mo1Nx)b;Bg4C?2PfMl}J zC>^L8GFx1~+{z{G(FFv*$xBH@G!P8*cqMWb$bf?}NmHaj!tS#S^!lP)J5Wk*UtLE< zjU%baF7Uabzpw@2aKN^h^OB4Kz#^DO5d`?2)x-fnqW32nJyWWYGqQ3^N`5wHx8_tO zu<2@va`Jc&T&eUB=wr$r9AS`}3px;C+n65~7k`O`tY_xl7IlwEP{7$tPuDFnH->#> z=4ko)_Piq#eq8E$Rmr~}L=$t9~1u_0ObZp|?Jvp+JKR8n*u$I-3X^yu%PZzoKsz z@wZ6)S?OQ!$K`qktnTka?8$vxjw8!!c0a(k64aYFea#E|Cm@5J^TTh-j@Lp{zH4vBBdu4>ObErThT_8 z`rC7;N9M`-6UC=#HAMF&@$970BL)<(Npf?;s?Ysx|2lDQ0@n~~r0z4kW^MWWiBXzz z(z&w74?+AZl=90oL1L6IY|6gB)wk?Y&hfDqE!zKhy_`+Tq8lo^|H&RgH2#47f3u_g zKL-`5zX9n>Xtj0MlmB?s#3#wA3&rOdk-D=J|AVQFk^WFzI`u@kt7J>60{f}#N=6_O<)&uB=s9&>)lFG3^ti?$6dnVz8)^4e{IVC-- zm%=OreZ1Eqf+YgYv&}bim0G3h(T`;r`}g7)!IiV>V+?a~(g_%iiBE<~&;CrI1}{FS zT=5y?<1xFIyL{d|#=3GqsKfh#+3WT9I}OTs|1XCGCc-KHk@!gL9fJz9Xmrs zMa+-DB;agyT=qaXK1VZjG({3G(mt&3RpnXhdUmNA0XVE{E6 zTi+(GJCeQ#uO==A$;Vb2-ukfdnb&#U{LH$pt$Jp{jU35l8fO#_(-}zre0ZcPAYCQ` z&c0{P*ZvHdj9*G#Qq?GzjWms?bA-1#<uvOFT+IN^UT3j`v~pV`KcuBtSV zC9~X0C6*O^W^ND}h)t$%EbSmk+GFd1T@O&-wbYlvOc@=1y~JwJf5}Q2KxXKX|060* zQ{z4p!^MULn+(NSW8KRPBtplJ8LR8rpZkWIfsPL=!=WH+IqMt#S{?d^!mdT4c^9JzmsIW*uWs|LrHlt#+y z9G{tV&qt=aIvI0rs3d;Stq4|uwItvK%Lyw3Z z;7|4MLt~}znvoB#NZ&YQ@J~>XQIps^PCD|Y9xBKgDXptWZ&40RL|~-t$I|8=h@3^r zdc6^aPOjY8kBm}@B~NTj(h&Z}iIM$PmvmA@A^fIPf;`&^HVd)(j~qfnQyzUoeQxrW z)96a&@hkyZg&FAcsNa$3w?DKz%QLG4{K{Vszq+l8QAtL#Eovsf#HZcc_bBI0j^~v2 zy4>#cO)RS^(bVo+3#~LZ_~3KFAIJhGXGSxoA(2Iyfnpb!3AF}5&_nD6SqL3lWV$*T zh(Y<7mG$H9smht?NQq##@d=IlI@SH!Qs=mIM&GK;ez|5whnk>WFC~=?9$j4&4Du01 zfK`;B$xO8$Q5WUePPLE6MaXTixu#Cef`frZB$>X0jPg%Ut4>dIa9r+}6*M;H7VFGb zw-F`B^Jsgi*dHg}SR(Q@N$zUfVbPQEp2w7-US6Og;w70V#l)xpVGETSKV8w=3fidf zCU?mcb(eTG_F&~+%B_!|xRmODHjU1YtZXHFIgc(qYAMY{My9^A6qOrJGl|#v&X`4> z!&Si}=!q17pVXi_Et|kLnk;mNf)=WuPjma~j!3jM2QJs?ld>Gv4_L3CV>4oI!^ud6 z8L_^Uu|r#k+bvjIw)&Y;t{HDe@G7T1*?JE(bntwCoemjv=b38I-RAUZ8LIyAGk!wG zZKA$kl2TUzr*Ad?)py9p3(ev% zTTyW~5iO7&1;n1`-;%G)7UG(OM%!#%4haihVov08AC;029(8w^FVh?*n`HTCX0sDg zok`!MWEaHp2;5Y=A0;QuhOy^CZ?K zjGM?{aG~sgx7W5w3HWl6Y_FmXnsvEPt)%! zB8*#t)Gky4mUuhExx}m=eB7}~s%|Q*)_Q-yPy$pf?TRbdfmg328F6`uc^oMpBnCVN z;Ql`DDZJ}$^wiSIK7MvEV?vg_4P4E2-zW+!D{d|?gHw5tp+qmLu z9ziI8dq;+GLd{sncR0t4By2@MnAf5L`$%++*AA0#>@kjup-dcNVjkP~x1N-K zjc!@HD8KcAaHuYZM^{9-_rqOd5Cn8MlAp<$&fTG(nWt^B2EMWjz&sId{fRx9r^I12 zV46vef|dj(arP6c#Y0RaCh=m{8{}ZVCU-nKNAz1l{r4UwM=d;Q8!cI^)a2r7d(GnI za%!51hvqoNkoBpyz;p($Cij*|d z%e7VcI8}D<*sryy8O(RCIr+hmB2&wDPFk+zG=cmts6{PjBfs;vMyeXGzVepw1bAM@ zAXc_}ELP|;v6C&$GoG|=_$@yoOra0#q9gJokoG`KW>}f!nq2bR+Ry*TZX>yaX z+{x|9Gw*y4E2ohn7bNCEeK^#!VNsa8`>DV`qY-bz*_lnyjgI{Ch{|ak(mxOK!`{p- z3}?yIMg}(0df6~~E1(A#H`vnAyA%}}@XDEwf0XTZ;HK24W4W?+`uwTaK|(j8sY=2} zEUUWLjWNI3zX>m_eYHJyUG?Z#?8Dpy_vRmxk{?@-w_PRO zG%Xzq-8sG_?-E2pCUv{lr1^eBEcfAZEF=U>d=5J1IvjfiCI?={w@1EliL~)(-sket z2H`1C&L?0yV&In_JR>=S3N2K2(7Li`D)X5M#`VU0<6q}IO^VCix2yO;{VdCxJ5&*V z(h|WlQCJX?@@8&{t^7E$^?pgp2jXB@^|Pt0B?s;V%wJwAafo`vLPb&Fs7h>QvO0c) zyz;%%wAyO@wcYCNxXIsd1_C+zZ_*Wp-`)Og>1`-Dj_o*crQefz!)b0W*o90mKB8VotXx%{?- zjxc7jx!97UsycapZ?V7f=z^2lQ^A5z|M|0)SQC+W>!Xjpi%SNBnxIE-puywirU;mL zMGJ*xmg}N^230uwUO#^hi)3cO+4)LQ;kbQS%LB#SCrs6W1%=FH18 zAFo+39k<0`Q?5yPvWj<+i<^h10qoEHJF`GgI;MbbXnjatA94P}m6Eu))Ynf}dgM?$ zrT(efq;|h{GPjtvWmspv{eYI;c1BHHLB93AldgR|NcW>p>bHea@>dy8w@3Z)OO0Q5 zgCS)tb%(i))4ICal26+Y=SX=Vs1XHTzP9nLw|3vh;f~H5aqG84dJS$Z5{jSc2Kk-G zZM&|{&o=y+Zhqyn!2`un%jp`b(bEl5-qvqxz3CAanC0yZoxgc4IoGj)({~w1J>zTP zuWz|W9$bxeM5dSK&!6@>_;NdK8CUa|8D6IENM_i}7hUL_-QG}-C9w{dDo-Fjo-dJd z8yNw)!_VJ8j%EvFQh@3ln^O=R2&8uZU_g<*bQ!nh8WWH&O3`I@nBe&Oak{#j3R0hT z=g6e()Mx7K>?P$wcSV-a%Y%UiVDpm3cTOX~rPFURE{=2&=3_cxi;v~LFNR)Z%4qqaGOC6+p3$nwYQj+K6 zd-GAd$J)FVHQg2Tq!6{|aT2E7Zo0{!4n-W9P<4awjAQ&&OwfQmGa{g zMZ3Z*>c1B&>{fha{*9?l514rYPD2KvJ1*sT8NH^af=6=;24yapSF z1{yRhXDo(SH_vZ2I12pftnPmB3+pNM`|rpk1gY`^Cdf!v_AZlusr@L{D8S43Ow*P? zPeZZpoAuK&yh*LOLG?v|^AQ&Tp=-azO2%t8&huPhHwkr!Xe-3`>IzB*-|O}U?_g_o z1GJSL88jbctO*bO&Jg;+9NkTF*d{&h$>sOv|MTv`{2^@~o{nB^6jYqYE4uFttE!86 zcxqsBTpbti~2g#>gHxjj*>S%7ei*_?>vT(tA$)>b^=cLH%on)BgzWF}`bZ;OD;G%T z<@Cbm=Eu!yA&F)d7dNzeHp+fBHh$Mht)RJDRb>diq6|B5RDXjtqe5CRMSmI+ZCgJc zrTKB7=YM@AVL=cLUU~f5FAK8)Q&SEEyq>Uvi+R76dH*uL`&~$^TCwQZ9^7A$WgOu$ z2z!?HyW0K1kMIS4)Uki^<$LnFGEZ($dOi&DX^!fC^}JlN0&}I{0cG_(eXw1yAe~*9 z6rj@$a;=i%8@Yw0=y1456>d#kEXo{XS1hQ>J3g_+bT1g|>}+IcswU5_M5Vz;xsZ`h ztquM@3{@>m?;F!(YAIoYXJC2g2PK3sTCU6aB~zAx(0z=Bsf~)6LRGb^sG&ja)*tVC zw(SV2zZf<%n)xfZz9^&_%oJyH=yq;J-4$F!I2GIadVff}LhDx8=<_KP+;=PtvDj$0 zWI6Wjwbw#RT+AdDl_-CWW3X4@&U{o~;6p?XJkE2pNeFl#piFQ=)rS%>pGE5Qfplcy z^?fXPJR9VVw3+6W%e~$Ixqli0gP}BM1F6S^J(@Lrk)hm*dT!Dbcd`1dW0BvWJ@@Dc z!)66WRc^nyICQ;eOX>y8-s!a?ljaQt71ke2{V^6+D$RIEY$Ec;LcU!3(&1W~*IYAX^hjEK8{MWcmT}Ny2ri=;I=gVkYtw=iL z7S@r5AR}vytAAac26O4qAMW=YhmrZZ7x_dR_xlImN}d zvp?SbU&Os-RF!SlHB5Im(k0zUmvnb1A&qn@-Cfdx(j6ip9nxJ=(p}Oay~+3By6^E` z&-0D<|F?fJ1jpF>+{dxjTyxH~Rz6Jw*2`>F2F=FBuZeo!ZP$E`gJ4Oe(rsVw5f>)2 zFue>Pm>nNSUznJN9dO_Mf(*0fAS<+^7UU0gG`DL{n^Xze;Qk+PT|yMr3{xB_^;aY(*kH%FnXtpUfwdFDvhoFARHGYZ;;G?#_?N{-8vm-B@-c( z#8ve!jwmX6r#r@fC?PDGKo(l?K7~Te-op2lhsjPC99*$R&d;AsRVAW)l`q(I%|8$r z!xB(~y_h3n9K>)is6Qg%koxbP7}}JE03PuNZ0*oVBkxY=fRA< z7h_4Xf4ir?H)d#fc>jxZLAaI^l37bNTko;m%HQ-Us~Xc^D| zRn2abdggeN-{2|-X<)m+MAHOCvZ_aS@F^D}&g6jG><>nP-YcU6$CJHp4TdJmvQ$_(3~ zh*J-dHcmA+D@?9?rdCT{p2-jUI5+vXWYRj*JgrZADqauqNw#yH`7(%chFnb>fy(wG z;hA^r9exW=FHCYXqQg}Bwb@T}ns@hbgGURJf0ldKs%HNX^cwo$;sX7yt@Hn;1Mob- z&cL5w_<;h1c~|V`jjI#?wU@1jcl+b{(6(3>Ps3ka99Tnt-;bG9j3sTkt(E?_3-?o% zn5gU{NiM;9J#F1G8sr`ne)aywPH?@TO{9C!`(V>BtIc`M=(T!XeO6Mq>fy%*xiy^* zj;RebPw8$(bX3NZxd~e`*?xy0R|VNm;-cb;vmFT<74rpbNvbH{pyTn5kBO_Qw%H;b zmYZ9>TA5(l?X+l|(%yQ3KJtOBbozhO+wR~X;*kc|oOeWUQj7cHu%knsZqqxi^EWNh z!|WWO;qeNIaeI)SIQwSz`~e`?L-xw=%5p>8JRhI3#eALyb;C23^Uaf9_oa&HR%k0K z{qjHFeuW47qygEo7%qb*X~>pM$r(=ukqnh*B|UEMt8U*X9DtsyIRTyqV`kQnP%1Ov zQGv;=_QO#K4`}_PS24oog@5(Rot)ovZe^n8I-b0@;5`8#Z`$~#eLy-UuIcA{zMeG_ zZNFnSjGngpJ3A9j{4^$Bt;t|{7=opX%VG?BMdqaMjAe8f3zO-ylb;Txhn90)Gz4ve zIw*|p-_GpN;D7$zc6y6&zcM=%Lk|d?4-o>lhnpAhEK#S$=iyErIczzWOwST_TiRvX1WR!uVW; zPtbv*nuA{`3)hbFzu+Pb|LnEX;V;7vAuTfg^_|}OSLxfJkc8A-*FT)NGGmf*7MY)I zk&q-ApPW&sw%t{V2wl0(uAOZ$GnPxLJ4ZHYIK+Ruzs%NEQCgDl*n#%#h?}%qDYW$$ z!P|wuT67yb>M(!O@BOs;8?Oo}Xqr^#hImMiPKE2^haTQommO40 zAfchj>3mmDRsBg>uP8Mzpb{aXmS0du~^$Mgui! z-|esk3A1CXI`#DTrkTFu7#J|y>T@qGnVNNsjZ*wRdGI*VcYNb3$3I`Hv}jowbo=d8 zRGogUmFrzwbhxTgoDgtUZec5&$ci>g3kVC>@8nP=U?NwvNKgJGVmuk6`m@G~%Llym zRlgS-=vVKpien!yOXj|VV1X+h!IPp3>vsNYwcm)L&i&%CQH883SpaFOhV|}%N~OYt zN4KW<+98fE+tJv`<6(w-8y_9?o!T~7#l*SlO3SK#r4CC3^Mb(*hx*v^nN6@c#BwKv zif&`N?z=DS2I&3dJ08cG6Uf%1-LgF)x?fwp6T6MmP*kMgU0guOST;pLX)@vCY#JEm z`_X>#62VlBRp4{FKSj1$K=S3K;oQh@+30Bb>)V-`$NQk>2CK_Xu%XDN8ipt{bJN?$h@O?EcPnIIc=<8m9G~@A=BbT%DJ}>59d@GS zQ(EcX70MHei%ITgzuuwrth^>qS5i6LMEum>l!TK5DZw!e#7fhzoLE?mz8n-tONhFb zL4kz*pm=<5=82m_=~HJLyKcPl?PFR6`47Ho=JuP%#!rR=&E-2knw(o4G!&ezZazH> zz4S_5nzfthqIV0GwQRkgNeRf|VItU)95kjPLO#3v5SKO83i!ch{XwK{cB4WUo&LRL z|Dz@w3Y1+KOnxc3H-A9l8k%(?P&OQ%xvAEbmW~eBwNtWV8$hJoGjd^OwTHp({5A!M zDgpHJvVhTqBuhwWUBC9|;0`Ry159FKBI@XfFHEoo+Nb4C4gf)!h_@us#y~PM-{vT$l0agJQ{4LkrX=;$%qI zQ(@dWc%+q2KJGCapH9i4B41adCeLJ&35ViU zPp%Yeh-FZawD4+{6}O0I5h(mZ@H>p6)cIE|xnJr)ysFFl1Y4)%86Oi-3S8VNVJpsf zOedKAZ)J-nrww_VXJG55u9H<*l45fAh9WJjeP@Gj}2Kf7HAHEwflxi35d23s@B3!{)UG16G$O65kpC1 zgLKq9!my0%bAySPD+Pu2;@)?Z29p^}Or)s_2#_en7trcjm@4Ebf#)b5?^hVa-1br0 zB7*V+Cm6-*{w;=Ui3U>B^^=lxCD(ucTsT~^Y4iofCgZ)4*NUHfYWcm8V7Q+CUFDnG zJ49D^E)WGrSRO!ux$7^A*5iZ{EWuSZJk1@uB=yF}l*&c^hL{bMFhr%wBffcNF8O(` zP7we>Gw>$*4`Po-4~~4};kc4hX8v5c#q#2TQ-+sU@N1?f-MTIwY+wKnR_Mx`li zyj~<~A3nyhv3v_p|D5oaSI`AD{j^V@LXOPMNpWO++zfF7f>Oi^)X z0XN;(*X#oxTotky4xZGHQz>=go0b40b?1lE@sM;`C2479xx+m&dKNd7u8EeHP>NU+ z0Fht9LDbMQ;B79^T6bRm%P4Th$IS~9jnh#K{!24N{)<)qsevt7f{@61Pm6{@v&WyN<P2(vKd~jG~ZEs z2nf2gF)U~xbtsIaN)vOGlk{EZA{h|+oK?e)E`aI9nQAt;x-D?BcJt>(uM zl3g4eHFHVHhKk3_+6x>?f4dK7jo+H$a~ca0vN%&ulX&+&9__I4*Phw7b9#UH_bKY3 zZFN^+P#pL2@$T)m)Via!J^VeMYrNks(*mbZ^foT>cHXvhuduSMg_VP!tPNw*aqipE zF+RKbs`mg93s2qYa=E$r4pzNuHnc{N&mQr%SjF_fuky$JaNILQLk1F(R&@W026wbA z*hxUxs|y=+{Hmbh_p~pEP1`w<(db~OWaJSx%P|UqTVAFCby=#C$l7@)HV@a|jzZW; z1NX?0fuHXmtSm8KJtH1Wy47-h{vKLxOU0Q}T&yQ1OZn(PAM?@CR^zO2_pULLF;mTx z#5)US|9B9<3DZyfn^oV)-G2G@IW{Xg{%`l#6(8>vrO+fpHqZ5id_ha*jBaqC>bTZy zhxVfrszt)YTM*m+%=nSiTNf669zSCa4&ICy87)Hq_`s`(213`56`=TjXJGkvC}9Mg zbnn!OYCy2J!sz4z8%KMUPFK0_zOIJg1CdaT>_1E|CY_P%!y6e1%>Vs{Js}^B`{6jEubva_0o&WG?5#}@z|t_jA~}lwW%K^9 zL&EM`$>M^LG*kw|etDeR=ag6e_f3f)a0dPezkf}*wChk@pQQT?5O0rO9o>dfn>QwvXU=S4`1pLc@P(7hDsQ~+pe8{kq(bQSHUFR@rN#T{ z4p1wAicr5#GoPM5`sKjcrHGKlR90b~ddkiO(;Y(BKVVLysF*&);pNk}XnGDr(p6C$Fj>6N`9Lp2g*AIfqLrDFhBoEdTw6|3lgIO19zK{!Xpb zNQl$@{mV)SW!>KULdDiaHT3#=+2e)$0Lh z3mW&aH^|o?WJmY7d7E!%!F~ZjAq3UZw|WZ*yGAbEY>FgL!vvxO(#8%p`;aql3-Q*H z#>d8Q5NSz5!fPuphVfAv8GTCuB1`W7#km?;SS#wpCV1n>+5 zFOY)hr|p@T^iZQ;sFb`-|8j?huKZ>m;q&KLJKNKO261R8gN=WP{BA-#Ep-YTj3!qf ze{}XacyX%6pM=ixQ6~<}&dr%wZ7{A=Bsp5|O-;B96nigE(f`d$NRQ1z&7hATyNQa6 zYPQ#3gz`~435r!nEYFQvX)7s9b0uEt zP6;d(*)e2{)p5#eHAEjNRzpO9(|T;J4CyG;A&ra~dS=|mhXG2EZqAm~b2 znXEQTH%-kN7fi;`R4o)01*I*wV+NHYb6Q!GkPz@%r;$oACed{vead^Xk0%at12p7SgT8ug|uipdBkB&= zK-Q&rk_wFAKqYBk`e|b_1%Q+Q=;8S$u-4#wCxBV`24DFA`cdA08`pB;M^g?>7v*aH zed(YQ7dz12f5NfU24Oz1a}OllVvaRL%)@iXxGq#J zAu~e!Ojwkz0~kMEyQ#pR(2Eq^+qm;3F4F+ox&zC7!Z*83g3S`B&!HFtiJ$rK*T&3s9*A4 zpE@VKek>#yA-8#sP~@RLBCWxIVV3l>GVZgRNC$+~%{7NNNW!ooYh~(0v<&QEHgJ4L zAt;Wel(e<=`#zx{KPe!>?Y6=JqE=G_3~CQw>+4i3bKE6=k=B@C$hf|`rU}Z;LVSW( zAKX8wJ?D=u_6uz_AS8(+M-2Wd50i}il9D1?P+H+YID;d(&QEQ?W4^clQ)v4P86Cff zxESZr$J&`I{^VG~0%D*&Je(f-H3KLt0!`W%Vid%zetngu;jt~qz<2I3GpJfr)r-!?fEm=6rk(3C) zo&A%t|BcaJ43NCd>g|3Q@ax!T+466tY0AGbJ}*3RY?%F>9}9R|dvidk#(vKD|NeIn z;`{6@@1_*nBmD7eKv~+>vz7N_V(@Tj|0W~|-1U5#DQ+Pf8$pE=P}mKY0n`L)`!CJ*PAn^ba1t;|B zp{^RBoDl!;yR=a~@Clj!9KI;cvpzaXchc!^tFPazF05>-11myn&zv>EswY>M>lhKQ zGp?KULjntL)`7W^q#4&h_|PJFK(pTjRAY;RGV}sfPJ)f19WGgBOqx{CQo~?!_aGaO z{39$s*bGzg-434#s@kt5%61(vTlOOKii-iZD!BnD82jsF#otUq4fplx---TZkQILk zYC|>tH9Vq38{hFenrLpES%w_la2&MoR#n?{`ZJy6EJL0MB@@$ zl1e%R*Kd&Cs$L^m$p%2{?Y_DWsOY||BJtrmMdJv5|8kw8kexBpuMf6SL5ZngM^&8V zOf8UZA=+kB3JWQE1YomNI*LqekL)aUx3k*N5dBOaq>onidsD)Wsp-1P(!KOshzNy9 zsN;A9)0?|UP=yZUoL10VFyCG)4A56|bA2CN^)CESe?LJLbGI|i- zpVn$c5Su#5wiL%0p8D?=VS^^K4A1cKXAel46mGPO*Y`UgU^qCw2Sa;>83?1X{Q@uq z1e>+}y?rA@%QdqJws^3j(~#f1iemN~H3BJoS;s(H8b-WhH!tf=gg3^Ej&NAW6*CE$ zr~|b=G)E;6ETL#v{16;5jq_Vlop`3W73h|fhmW}zWr2-#LSQM4P0X-T|%lLec?i!E6?VnBkxNfE8hcUuSGEYb=%C0-;EFZ z&$hqwbVlIvhB+cX(d)>)X$JJ{+Bq~75QEmjt1#+9o=7m`X)5K;pt3Qgp&fIg*UkZY zNHe&i&Ss}%=$-7#uI?Dks}u1z$afiK#3Rb@U%@2f4pdD^>l0bPgvlk%LED-fq=Uj_LQH7G_ zAmAOK#pUAi#zpxB^}EXjl`ZZ))ZQGnaQ|>J7N4Bq9iN+{VY!{2oTN7z;5NVT)6>g{`Qzqx&W5d` z_Jw|aQHWQV=k?#9!LcK}mohMhlEF(CijB5-G$TjJr^5wTg*?#VG-Zi9-|Bkw13Wl6Li3<+)m^-!al> zXNn>Q_17~+lqK{0-SQA_!CGU<#8h3MI6A%_*}r@NU})RZ?NLMB$8wwZ_SnCM7~9SN z{5VV)EcWWNv{S0KlQ{#k8-iom$kp@m0J9`z2C&4T^*>d+>+80s>wXFuSx1|U8r-Xj z<-E|=uCiG3!E3<8&uOb^WhUy(O)gB&telJa-#lUuB4z=Fj9Sfb5#}k5x?Rti)U#8} zt--Y(ZFQj2>?L@BH?gPq1HV{<>=$xBsRS9W`29Vo7rh_*P55p#K*B&IKa`oO8mMwj z#{`isU<8IcGx2@)sxNcP_3A2V+aJ8BR+9u`SrxyM>C4)-&|0T)et=#PqG#9!X2& z5cJoOR$yPFr$5=-+2uad^fyU&-viQIqVihjtU zzBr0=!2{u^ijZ!K@8__)Cw_qd1kIwY*wDq(WhQwmY7`6M3k$PXw1t1 ziceetUt8S2bKJ5dQLO@e+Qdk_+Po7~#mqrVM=h8%Ae)w!hI19}Cz5qr4hppNtj5?9D2wTyFUtQS8($B1Ql`nwhFXjkis*7;JI1;(=A-ut_sL2+y) z`D$r0iAV7YWXA#GGO+fE3Y|^a{K>QTI@Hng@Xt+sE1~+Yl;x=l>f%#S-{he#w}~L@ zVtVVAYf_MtcfXr=kPJJZ`ik zmZ%wxk?LEst@Ocw>;};V3-kRt{Xquivi)byor_5jk?Zp?i1hS`FL?OT`)_%x9Qx<+b z&nLR%d0+cEs+lz^v2x5{(eKe34*AI=IL_bHMd3$mmZp;3u>)OeC-fjlK**8sfv*{B z15ib3u>gcT!HWt2-tam@N*p4hmi*<|vNTOo{Ey5|$H3FVSlT-hh5u9 zrsni~gA2{&dZg=pv`;^|XCn_m#&P+Yrn*`g)=U3K;p7xQl?7>YLw+ur!!%w|>oINg zJ$80{GJVh587gOEiiF1r6-@}(WE3Klak0@F*5{@!K>g2?<*Q=lWy{W*^*d@kIvv3v zZ@J&pLl+9?2tPo!TfbdAj zzk*ol-}zR1GmE}-XMSrCw9v;Y*VWW#k_9hm0^sW1?YDFvW(VTU=s?*QE&kPa~g z7M5$Y*sjm!Ti$s81kU0uvw9>JVJ6(=wY-Gr`wENu>99jfMcdR1zm++ztW@6zNy=5< z>!>05Q3e?SP~uvjW3oT8cst_KcCRceAe?QlaVfsRgtjy}h)ebhlpntF55=x;BA`8# z{!tQlVbah;3?Vo53uFW=%H@QA@~v0DO6h#SI|@HPsC)e%GQLw7%kfo8Z_iq9k9mof zZ*dba4-J}R4Bz~P+wun9Eum`?zq9T2t~>fu~+w zkwidD{uCt9wAe(My@&6pjb2uUVL%5C|8lcFy-2YBlmL%#cQ><67yE=Mpx#b^-e@Ww zi_`7mQpTq5M9x98`X71)1Wj%d6PcCH#0GF)#fNfpC&b!rYVKEhwtNo3q!(t^N=LhW zq)&2Bc1_hj)fV?hqsWg}MW>F`#8Jyt4`A;ok<;g74NAqvyM@Zf+Pu=QE!j=>C(?FB z7A`#66SXPIQ`5`rpTBnErxYPZo)2vS}BV8B$B)(&8;F{sTr0RU|A!tgG z?pxXg%S`#8%B&bk=X?`jpGtvU<2Imu)NlSnShJ?BH>QG>{ejF)k+}i69}$V>WOUW+ z0-IXx0YIlE@mH}cz`v6$7Bv6}sd%De8f9EorqbR&xtm4R)-PTxVmDbdRQR}c5EsvAFXd#_-t_%53Oe{rtYeGMa&CUzJ z-2|GSq5>W@t7R?VfE^>`+aDygjj*tau~dqlIK&ko>7WiEO7gR}%d}yP{3Evmh~gdp za2n0TKu4YJD4utp1oe!vKlo2hbL+K{5_u&gXOAI^*%6CDM;XY+YxBZP|P_?|58@iHV<6=e1bb5QQ8^IVuK2G3Wzwe3}#Id@HaWAy8z)mLBux=g7}$ zGMZIk;!#wKzC-N)R;@K(k8<6G0$aC!!!SOPcKK%W1WY8MrMoYGEC-o@ZQD?s3c(XO zeveN<3UfVDX*M7ody}H)!Q0&kREyzoVB=?XTn}7m5hd6wZx|7XD3K)h1WfM`3Aq1( zZ$PzZ$xFT36dilkk}_z_PD||@hPb(L)0CF(W`)Xm(2$vQ#?5N2*+DMMJ&$Od^4C?! zY@;T0)~jRpZ{$sn!Mu48_Em?L$u?XyDC)4X6W`JHjJvXTcblC(7JmO1=K=e#CHLGD zWVr!fTe-neb&@8L8ulttga0rv7RVZrDP&kn-^bcTTn0xrLEd6(k<8p}wDa;JBj&DA zD0F`ufxQy;-K_eWZWMVTA&~s#v0`|zEGLp17{mF z$HSN3tuBG9t141q@@1^z4*xmYO|LnyV~SESst$QeUwARTy#od$lrqE!0+}Ye?dZb} zqAqgLC07rpO{+&mTYYy0J*v?XDXI%zOs^|(CS4UZt06AGI&LpYU*K@_3=fkjyuYhr zs7$gANoGe`7ePd4%r7BbKou%8i&G8|Zm;@Q6U|)Hw4L>S|HSqmUhLEJwFahffW+gN zZR256uL7x-tS;5=PHP@!Gss=aA5I)GiVFxQPGzqyqc*4OSXV2W-@gMe{IedMGx=NwEQpV3JL)(i>-^3kH2GTMcjDp~ths>1epQm+Kbhzuc8zcyFf^ zbS7;ZzcNb%k_ti}dDzRW$4=|&bKXIiph*Lf#_&0UPjtn2o7}9vUR)}Gvh?(H)lf)? zhca1Dkm8Y3v(f_wj&e|}>uhYMiXUWXYt=S-_f4jo0kRL+LyWsfOzG}hj(_@Wa62Yz z3MA*$*2>FKt{Zth6EW)-F{8akCxc}jK zEkk{(X`+G45>zZ38@CpIc6sh&ez&h0ma6Iub52b^#Iv(-bGq7$jZDx%VK|*il&0(gbo#*S!lvtA8>k7{Myr#XiFp5Lk+>=oD=#T?Ooym9 zz3+N{csG0RT+vqBbd8Q;GVOdcHQD`kE^1fvIK94^9KBRFmg!<0m=B2N2ONHk(y{Z$ z09g+!Ot;=i%mOqdh1Y3wjRvmF$A(A1knY_qtM%$T@Nr;}Ht`7aI4{$I`RV5}I-!S! z-N1gsu+%XpB9dQQP&;uE#RpUEm;f&X2$Ko!51&tkdD{-P-)Q+C{=S&FWN)(G6O_A2 zEvBJCFjYO_N8C9*Eg^A6hFJb_*NyRZ`=|fodlKePXbIq=jNs(Sg_;Y9y9BOQcrna& zBt1L=JnxE{D=bBbvPT0545;V*>En|># z=Sn^uJC?0?KwEOmOIM}*eKHFydM@4fX6-~36Xu)n@x;B%LxhmTF#CZ`_RGD*JkA%9 zfi+>GTH|A*1+WS`!7F1n*=E$hLab7wny1&+ZkkXr zQtF{27dP4yP6hs}ZBo+_8gHq*Mp4sZxkLH(hk z8?QEN&$1hYf$$!Uv$0l&W2S!ABqvK{J@95Edj);8HP~R2DaZ?554Z%a)o~SkaZ@Uq zs+~1bnGB0`%G75vZu4Az1YsbWfUruhpKb5WKGdd}I*)d>;JrwG5#L>7@l2Y; zp8(&}vp-*D1@tTc+PjWjaFg)eo8JK*v^Ri>$e4D%_1t`WP}T{m(UyW*M!Gtx_N~EEegfem z1*_T2qEOiAN|ripM9i8eUm_ExaPUogIhAtRLqDIt`Nb!jP zte-Kj$=Tcgx^zWvvoR4odg%VZkQe<~fx^7e(w>TeW3&zh&R1fjp0U7cO0Z`VS@rmP zg$PxDM^AZ9iQdJ^t3aQi!CN2T1VxEafbJXwUCQu5LDA2xfY64Zci?kKB|;mDEnR-1 zN(DC5itRngqPmDj_%o5!0~Px@TyNDgl0hf}z@IOvWDS%p9vWX%t{?IxZ%bhNF5 z;}_6B^733S*qgeo%PJfyOZTt_uCE&!{%lX{Xw_bQhzs(`H0-wCvoNaUk2H6>IYT{Y zyNgu30w`~gk?tAnoA5J$mJ20TpM;`!mL{q2e1SeVkA@P!X@Lz9Pt~+Z0mOcF4Lb4Bk$0emvCtrXX|XnGAvySD&Y; z);Z=zX9kpy0s0V-`e*E?sfWllUp;L`i#=UVe+=Nfdb~^Dn}?Jj<6}(ySv5Te{l&&q zD1pT=$td2=8bo(!%F91et%mI6iNTXSd{DhcN0X~|`Ib_tVQq8#VBP)o)8a>VqUMy; z2D{a=I5?2rj7c`m&jbdblOlxu7Hqn8>KLuUJ5?;Z9G65{*xUDG zwwF+icCo3ma+zj1HE{5=WZv`MxazxEH`HAYzZ5Mq^S^0Ct_H?McQ$D++D^+^rixaVKDHC8NyG)G3({&h05skps>gn;nPXJsDBKZomMLvlA{GoHv z7pF9#aJ4~tZYua+6gZQ~5#bpv4j?iA@Oy8mR=*Q1F{Ty&ika60cNg@F{ew$(_o$x1 zSMmRbh|l8I|7G(25&uT6ViFvq65{43|M5BhN8K1}{V8)__JwW~9a03$V61*5sUxia z5BZRXek-`IzqcC>=;I>}%HVIn{5`_{^8xTKvXD_t#+v^``5ab?T1KxFWg+=s(o(5Fhz~DZDYN+ga`@*kijA0{a-otHHzE^weP*Z zh>TJ}3V!bJbvk%+=^MC3d-oPKmWhP{&QjwsYv;=M`X@c`-}l-B=yL>`68^HA=)7v! z!VO6XBCdJAY^j@RkK_D17%WuT-X=WxgWnx9zfljSFAUy<+#qr+rqP4;rstOk-LsPg zy!7<`fB7NJ@k}{J5%I3rtEEVAv8Z{WspE9*ce(zCxzax`*MjHq0=rt?!{(aH59oNL zx@#ht|M^v1DTH$McXDlut3sCB8SgmX;z_IJ^G7jl)^$~B8;m5jx# ztel1+8!A7n&?s)v^m|gvri2;&EGaflG5V~j%9wT3y&Icqa^0jfDf73K(F+nfO*UNc zn!*{+NUALJU07shPpfScws7!?gZEnQCp=jf9HtO}ucy@!{UUyE0WpWv^SJ>jnyWDN)$WJz};B6^%<=jZw`>aid(Vm*7=Imn%SP zq_`;}njsAN#{4qcrTC}=qqMSLWDAzRmu_WZ7wP&vIkE$3lb69g!_LT{jYmX&esb3L z-L(4k^*tbRT+{w@X!KChn9l-vs)<0=Z?2r>b2Q5RFx~(BF?%jNz^{~5qNwQOPpa3K z_cA$lY)MbI24`nLJbC^Do;&aduSYMh>9d1JMdB_Xo-5ft+^Q$$|C~lIVemN@(oaAa zNt!UktC{>p449Ok50{xO2Cxi!KQ(1uKnaZu9Xh~xo_)gL{?FAMZTl1Nvzh2EEF9>g zo~udamr+Q!vdm0v%!+f}fN5ZLu z1h0S_`^z5z5;!o+0~?DzQPWki_^1xb`8##9`5%Nc<m^A8S5*U{3QeNCen;Tw}V`e zJk)un_!Vnlym!(_!NrJa_yHB*95=|g_K%O_qDG~}Wyhci^*5HI7#QiE+Gcs;%VYs_ z6U?6yN7%cz^JklcISQ}9b47==_dvaw2X_j_#$nLicHt9+=nPn`>1AdcAD^Jf@g^E#8A%?-Z=Z_t z4FfynmjZTiU8hCkg{>80n0-lv{4>b9K77!%y&WI9M$FiX=r@id=Zz}nKQ&7LdwJ391T6Rd;QI>E(4Y?6ncb1 z9D&S>4AEvfu8kHMF){!3G;z^f?0CPE*CG^8{CGk265&!m=A;@TRfjtHHrC0&?4l>E zHkgpV%tBs6$tVdfIioeTm!rQJCErLd!(6^5qus>ibBxV5yvBUIwcmp`(uilU595_+9UWlXJiyUhbOOhr=x$so9#C?(RZ=9;B)oSIN}IAV%@ zMB^m7J4J;%=UCX7jb0VlC_lRYJKV#e&;*4HYxW+lmVIHf*iU5^qnkj+d<`xi$FFeG zo85YkiwAr^ zY`_s~T+-zM$3cTWng2Q@4K>B1A9F7ke|n8kJwO_W;42D4h1ex$BK=|L-hn|0ryQ; zYG_3eJ1SX#j0r25&{pq9RRf8uujlm)It;|n25oCn<1EH8d-#}Ad1g7Nx!QlpppRf6 zPEuo}sfHt)cKwj=Io02#L{T@9%Zdjp*# z;6Ss-m=ZzDl9B?U@?PS&9lZmp1Z(*yFe&hFG6G?Y17757O({`zHYVckhS0h=7RbO3 zED;nvHANwuG)I-`_kL+U1WFMeB4qG5$v9w7|cl#69Y@lFNeb zkF143Te_+4kY+TJ915-JU>pxXqDNM?8H;PzSXmC#j7aKD{kTYhVx^=}pJ7Epps}aQfmP2+!X}Ez>&wwEcwuFYP&B*P+wcM7#&9`KNbI>FS zzfmBL=VO7??cYm?&iBHwBFVkJzY4_o z2(K}}Fp^{6X1_a)?r1s`Dj4fMC&OorvC&lRds$)ZB)Hqm&odV@44=C<4k;ylSp=Ez ziN{PMN_DG`6riupswiEI6ZYMDz11BM@fYSko}NO+-k=5*mLbGw?Y2CPsEhwaW=*Fm zwwOoE8PQ#yDc8DwM^ETfe(QB#l_eX#S% zt={VHjV}?Iuu>QbvqHRp*213^-xX%SU2OwY8TwA_)$eI{Ddd|zb?sVk5kh46OWoi{ zgEVEf%{HpVMeR125PdOq^>&SytW#$47NCR|upYjmycVv=aFP$H#7U2kmARi8rz}AL zIVvPr0U{u}=$0+(wa)Y(&FoW4h+>w!7HD<_TeWpf~g> zkiN(#uQpD8O^Xo)Q;JbS{;(R%iE73vV{>fjD8*D2-o^RBG^BTLGe%02%~=L7rzx|9 z9*jI=?!ty1G%wy#r`yBz=8Ttz>;-jg3n)kmK|M)u)waj^lcJYe+5c7+PpBfKr`~3# zj3>+|KaxNlk0I$GqA^yJ zZxPn03Y#)vyXC?xL!yzhF%czD&2UY4xD<*slg>P3GS!Jmv3-M!`f?H`&WsTj5R2JI zj-=df3C3e?T-H-2{JRHYC7f*d;kD4j^B$q764Ow#`F(E%o!*JG-Vf7y=E7H@UKTfH zE)nYWJWwbdF|I{DzUqk_e@6;~D1km<%1@StCXF6}vytR7ZhE0Fo~hnur$5LGBOXc~ zowYgm6tQbQA>fSnhy_`qx<$a2dEfnZ_)*-66Yd0klx}g5=UF#Gz&Qa_+aQz$zn za&K?8D?aYIApOszo#*1Fw)VeO&j0I&3#CLbkxl#28HQ0z-pg&r=GS+61I;;hj@MsS z%HthYNC`!-8Md>BJYxC-PZncny*h$R@Y>H)<)U-411_tJOdcdR+#J7pLy;ktV$@yg` za&+gOLM(PZ2nb=XMU!b*=EA&mW_j{SbK$f~zcnL!@BOvWf->P@6cPDDf|Z@76QG&D z?_Bo%lf0Tf0MB|$IG=NOuHsQ&Nv(^tE}4GO;(B#?QL$iYx1krFB_OH%;gW0@PW^YV zj?Hrso5%)pW8Iv;gtN z{EYpT`}jICg7yt{VBinbuw}`9HfXB-_vK5%G+=a=nU=EBFIN|2RCHA^A}mIAr1SIz zc4n^UF9cyBkKafpP^v>_Xz2#;SZ#IV5V^*7P^Yzc-(Io{Y<>tp zKPdC7RpDEJrXOal$TW=7M2b`B4@8MBW3~6iO>}X_%UFKwMnF>gN-1I!tCQEiAD6|2 z|3ZL)7V`Z{yU~|&^;NO4WBVIYRH8Pk-4F%P&487m=Fdvjvh~|1U}>I}R2LzKUj=S7 zFV_P0DxXmem+~IXUxVM52j&-<5e2Y}N}>DSZysg_IoIVD*hN$#8xf}&4zb?-nLm(kYa1HM6?gSWIf;$sjLU3n*0KwheHNk?rgrLLVPH-6<0)u4GGw=JI zwa$<8>#lY0y8Wwr*6!KeyLMMS&#u~4T9>%(3Wu~qa$>0Q%&D;zFZWx&<<%!&mWa!P zKA`6l38Tg$vQ7t^H|28H@JAwo!kj;jgrA4Za2orVzbV(u)WiMd!%;1Y^c@NL%~Z(9 zx5F@!VND+dKjAHAHX3@lBcLnGDl5573Laqj`n7Dz3>W@ID4GcuZl`2zREqu;!7qo4 zys0+VSF~&1@UPb&Em~9+B6tB9$Udt^{o?JQ$Rry2fm>G4=Wexn8(Qu=k0G)!CopMe___m%4o>;*j%$ zjz+x4k!5;4h2VMlpw-{L+#cvE@=4M?;X^kpPoC&klvLEgM0j6OONyPQ=T>PF5r(HH zwJD@>Np;}OEfZB3h-4c#3fwo$+kRrErOz@2~KqVQRjGa%~CDDZZT|%5!UhVz% z+QEmz?p@?LS38=x!s=YDCP4+srv~IRXGF!%27O&2wB63eIS1UNgo$?t#e^*`o-Z$_ z8zyji*g3;{QxGsg;ZsC$zzh93)I`~wS#Zi9;;K*O#3a91q_)`35HC+umalZV#Y;8y z681OaYuHcAKA(tS5=U9_q1A_eWy}qz-g>|P5)TouAa|9z47{7YoH zn4~10Pk~vMK4c{PJRwXKP(*n@6JGbmo}-M!)R?4qjC&heY!_QueoS5`R?)v@p2je0XdRY>7)b&J6A9-XWgZnmr01fFw zV@UsZ*h9#4&(nn+Gyj`+NW|pKL1D*MG`{Mcthz6EC@@3gxM{2JDwza|tF0 zKn&hEk%LMIbzEo#0t&17B?KoX{bR!r*6Eywe)Tj}U(Vxow~<#Z1G~+5X=0maE!;CP z3o-IG0F^M%=g(`{9T)SfGa}g19iGR6s|v2{vvi7?i@*L^+G8_f{m%lq1uep{@b9`M z$N#63$LE`guQkyps(sHNZ+w#>^jYjF`KrlEOj%ZpqgLsvyoVk$YxR~!v;MzZYEEZP zSI)M3Xx>CKvqna?6;emjMpst0QHMlgG_Z)FM>a%-2%LXA*IMskmbqf}L)3nXs5twk zU7=3sIpN>)y~C3bph>VHGhV?QUHq5Gj0gDC9$s2QD0*0$qAq%Pm548M;Q^7|A%w9+ z7c(o@0sgz8gCyd%!PXD|{@fFmt)WQ(xZs!rAsR(H7eTcN0Gc2Sfda(Uws9pKarHla z{O?=+i027~BvJ?fzNLt^W!|ogjq7|$nyCul9X_D%w`Q9%xW7h+*>~oiUzUQvPgQAY z_JhMlxaN9^z3?${mQprwW3>19;?hS3C%(^7_S<%!HglkLpsP&r^aj11l4m7GfG@g_ zBebf9=ksX^Qu(20zM?IQFTvjOuNdejyB|ZCw~p#-1qQ9}_bUEUCj10>pBY4;qxJvngQ)P?|+%JWPw|gE2Bkk zfAaYas;ODHWZo**2V!fC59Q!+yDa<2XS@80BP-D-qKL%<{=&+({mw3E$v(*2&D%%?h@DZj7Bu4;} zBOKcFGi4N$06OylT$NGx3O6ImP10MA69EZeaGi^^gF{{GdItv!A`3b|x%ABO9FLIl}(zMFre^0je z>he5LSm;_BS{0Q0&@=v$%Lj9QzNTSoSU5nVX;?`Ai~Rg&d{Gg;(A)E?MMi(T%z)7~Lwd&40f5k^#)29zNZv|Ji#ib%-iO(H5|XEBSOE zgl#h@`N$-K{Bp1gF}_j1O&BrIPV`6=DBZxU)xWjva39xic1|b+S*HT*<|!ufxu9~^ zjtXMQdaD#8qfw7iy-&h6?$M>CCsIn$kh*wPOd}#TSQCN$4=jE!KeXG_2|2mbs~r5T ztQ83oInmI~3Dx`_R#wJkzWMObKivgg=ULyyQ4%IW62&>k7Ck|C>p2iBo4v=e-tJ*l znQfX0H&MUC?fU+yq+pV5rssRyEv$T5ZdWu^!-0*ufX?2`a|~e6JPST7;G(_9{c+Kd z0&27mdRIKz3&96K0m!FV7Dc zT*>_pw?U$R+V?jKRo}7fnCk5IaE{NGlzG^=j@XF4ot!)4@qe#l<&kXbfa>vbOmE1) ze8r^Q@3gMxukobL9*xh@`0c#&wd@N^MovpRCG`HKMlNLCuPgf>j%$8P-A%qnu~mrA z+d^ckVd9i2maQ<|!o1B)Sej@US6ECy_BxkXr+^^^uhs5a-trd=fZAPb_tmf1{zrAj-=^RqyA=N-7`*0I|oI zUjHOGq#7gW1`c$u<<$vz8bgSJE%bK_`I5^*OM>**49wwj3Cggdhp1Z}f0g+kt6o*aTMo#k3R}PnV{(MhoR6vP5 z?Y_-~j%k$KFKN-!4hDO`=N;ssPJVLq=RK8@gAfDd<3RU5RXwSE*LWf@ZG~^L42Cs_ zL$a4}4(ZKaiN?!ZGMvl=haU-CH>4`g(v#E*;k6JRs=buBt@|cJC^d5suNnWw_N(%5 ztLI7SwM@R7*7e8yJzSaR?!ZS1+sPS1V}yQYXA!_6<9FP0zK^dkSIlod_I76+6&HO^ z?~{c2RqVGHIUbDW`xt|+n>!W^H*s1qlF?oTo1cn_Q-suJ#*QIusPCKoGSm`371Vg0 zUL6J>kw?$zV@Ou)+%BnF#Toz+JnaSDA@5jw9qn@k(gxz$`Oi5dZ-7NGO6bEb1Wxf` zMdmAlvW`aanF%vX2hDe#*kdzeE(Qbc2O?rj1*BMGKV_G%=*VZ_NXL1Q^zL5Di>hsg zE-OhHAzv5AQ-?{wT5$9073^wHDT9XuAf_j_>(d|T+^gVY35bGN*#)KI*d5|SoW&}T ze?7sC3&Vv?qi|F4Ss`keTKxs=Yt!u59&@V6{XMbf zG)81z@RVXR4(w#M`_(_lbM?acZEoDJcVszIw`uxzugF?YWFg6WjC)o8sl8zKY^jnQrv*S)Rx~YB_SUEc z4&{ipfp$JWQNFa971oN!l*q|UfNL)k1HPUmuro^x#z1qp!Jht`8u`pcpK`16USbt) z?6arhJPbssKNVWn z$1?1VQmlx4P8RHo{}AjP_{`xIZO)rh^3FnX%&Bh<2vPXMD#pBq^fn)ft3+qnnzvB& zCN*@FcBma;FQNeL`_Wkk1WS+S4+o}#`({dmDn6qi!>n2x&x?@#;+p_DM|&E({m)|I$J6a?=$ z$9lkcJ%XC)qWWUfG&Scjlh=cJS}%WAT1tAw**pmW{l4AbN~TTtOoI|=plo&3G?Z?V zGofSls7*Z6XeCV9DfGqsa@)I;5b#cEU8h%QAdqngSnqnD_mhqdjArz~Kz?f?8V9E< z>7glD;Mhw^arjMqxeTp*s(V2AX9C8RFVz5R`Y`c{UnwNO~T;d(@s}@j_{#|$hNqaIO05tR9D*ZB_;EqZ&KGZZ-%Dq<_!lV z^>h|KT#jgD_|1K|pfuwJt}@P+hhuNcU7O5N7{qw81iN)8nQOuqd)BDpwgg{;Ft6?C zv~6qUUyxa7N6rX;BcbEv`C_?bq-7M=M?&#*lJU#n5e7UCHL5lJlvtI=)x~SGQtiSE zx;B2aYdnLNu(+8k@y_ox;&Y}&=_?w3!o#yhbzSBMbk$|5|c6yHu18{p2YSiyl!-tpxI@XHFA ziy=Y@z5jUd@^Tg;!ix|p7#nL%=2?0U5slEt-T#Q@Qg)9J&RUngw+5w+DZuypMKYZB zBnL$GmK&&#ebeg2Xdq-FTX#RR>bPz-^deO^bJxONPQ&S17x>NcqmZkS0YVW(I=|T@ z@gEJP97(7*LYP1{x|aL#sKUBoTOaGYRRP)r3Z+B4(2>`CxL9UY&L3Hh@mlK%H0vYh z4H0=i`xUw}Jy&8skxmaeYrrbe%5Yi0;tr|Dw0-i^^gBit@0H9=+DdlNce7Syj)vZ} z_3X@SPvhHKn|2L`yD-UWT`Gv14cSwr1+ z)Zx^|eZ~9HdU1)x-D<`?JKKl|CA$+Fk9N#_D|6FyUp;z;4ncipI{zfYLmo^s*z)YJ z5E&prc)R0yXYJ_PiN|-=lZBy-tL+=w_sT*^ReAZ}lqWS|EXwEoDo~83b4if+lAJTM zTK+t_z*SEYP(5A6bC#*yLULixax?VoJu@N^CxUo&W7K6&UJzN3U9~7J`xewWDTL*e zSt_h{a~)`g6pMHNOP(%#AgD0g?9{SgZ|zmImb!ROUhF@e2PTLHW#VfHx?}f_&s<5` z1#%@)RcBHY6R8Y=bUeo)iZqIYdTf))e#vLqcAt&@nMTT25)1=a3mH4F^{m~DF5P=@ z2%<&VM|EQPm#;_s895#1oA4`_L^&LGTW~&!Yc=D{(2@L8)I4i@Sut*;s~fPf_+Fw+ zToC4|?pgtxnP7>&Ouh8TsjEF38qpZXAF`b!rjZ&3{X=NHKyXYtQCOMv{7gYhb8}j% zUZ)h%pu$+!LTNCsp($QgT_ry-8yBYJr=s#nyU};N$q@iqTwg!a{PlL+mvwJM)aSK!_lRV&Q(|LnEEb#c^7X@uZ$8>^bFK1T#a&k|EbJ7X4JG>6~q@#-W*v6jLdw*m5!|CpVPun(p z&`~+idrH+09yKeo(@Iq+edus#b>Axy_OYq7^eAm{2;jUb;aDoQCc0%h620_e{-QJ4 zG(qirHGtlJa+tA0w+TLgzugXQo>Fq4laJ` zu)B>LcVxL%$fq3cc(r_X_TSF_Vet&`JiFg z6tGX@l`9ht>UzOff4%f~E-G+r(v;bZ#BN>bXHu`r#ijANM#cB)PM^cq7R{j%>U;TY z*&;%@gm7Ey{at)7=cZ2~aUnh zVl#@nR2M@pq@D|}!@|nc)j{y}h(=+LhXnOp@tm~0VOl}Ckv4l3bOn2*18CDPZz_qP zZG@4|t24W~a;OmB;st{i&kjp!7aZLD_ea}Jj&C@sj!6Af8`?)ZcKzC}|*O>Wg8esZ0&Sy-~@p0qZBL0))44|9%&dDY&#t669jFtikXKNgPf}Br$-0e$%Dz6XwfEVZCn1t8lsFnUypTJFfyVdti1Xws3fG z;6S2%={@(CTE5-`tI6qg-b4WDT;Q)FL z6X7YKhVD#_F}&~dmE#ceqOgf|Uf!q*2pY-dv&9I>`0TcTw>lmXjh7N1o7XmQc(*p5 z(RE7#&Echs#mY`Wjw)sdN$9j*Mxa1#Bq|p-;YGr*31}n4`J3Y~?bV@Uh?^pf4}&N! zOtTQPZRzfVSg#lYjB=tQMXJ9EAcwg^X~ZWStNUUHGUVa_8DQ(|T!qvPteZVh5ZxCnC|NSyq0;eryRZtm47!=!%<;l6sFY4CIj7*l+9jft@B>9RHZ z`npX>`>v@?&Cu(rrUCG1OUvhabXX1B{K9z7P`1B!PGn2jpie49Wckt=FnMxWzpY^;l^;xuDrVXyQ5@b}usrh};Cl z#{JIlZ%M>OeMYcPGOW@(qef01dPj_Bz^;N0L5JI?#K-fZI(lTD2zOg7bKxMvq`$H8 z`IQ)DxB|+e03IWA+5wuR_~uOY-0)yb##x?F%ne!v~=C^AABx1A9*M6j)q>K zGbpyqg=RU%_o+?SPaqW8|5qs z2G?o0QGNj@ELn1Wuo46X1sjR@=(VV5xxej_i(#>`v+|)1pAM4>6QHP)5WslMENL6r z`$4gS!t9znN{)UHsn+CP1^x{p;wxc?7wT63H znie%|Zr|?QhoLnCvIx&Plz3#k-}D~eI15S%urKs%925@4G7bFAey}Y z#SmO6+>!rC5aa)ncu5A_fQKJTW3ga#y%?)rT2diP%@ozP-zT}#0=3arg762Gv*5$c ziBUedji$=0U*WfdJM?TFy*U@7qZ*>otBkkv^|k8eAD_7O5y5UX(7;ayDJ3Ct=iOCpm#>&z*~( zw*grmlnXRW!b@FGaBptps|=G~<mneS~1rQyYR%L|nSY&uC=h{@E?b;|?h-l~BmaI2-8BFdQG zF5@imP$=<1#hf;@h+!hwCn#KQSqTOX-o-5FWc4C~=wl(VL#6pTnWjVWBbn=Hb<`ZZ z3JTfCiuF1Pr1S_V32yfrWY%VtramBO;M}f-|9Aph+hl}=ejD;?K);`m#Cq=2!3@@v zd`5)X!UdP!rxHXuky8E8gfk_-hbS}+hcj0k7vP>DCb2f!^aHU1A4yG3XME+5szE>Z z6#}Sz-the!rY~uJ@-+0KH(?m1m}g9I@yvOZ^pG8Eh&8Ot|O(7fW5^I4PXD12vmw!_GM z;LKJM>m}0J(HFEpae?f7n z!>c11p6D{&YrSTqFexR2HiA<~v-X|V9rGk@1+pO{;#?VF`2_0%RF>(fR+EXfV)&mt z#Z8KtdjMSgRFBnNwSN7~?jp50yHFCT(KNEFl&;xTw@*&I3nHMYmEOfBS4b<%%0b0y z;2b6yE?qelFW3suZa7Gk;+0uTo-`n5I2guRwYQ%IU^*Rpn>xu#xHlxE7`Sw1% z^rS-(x7>J6dHLU+&828!SHME2iIO^6eiNymuH+GBBMwQcITh{Si4Tj zkJ9+6b{vQMjA9`u0lw8IpAE3rbNt46VArZ?FLHaWg`^mayW? zbk2mm5||bZz?b?zJ@Y}0$-4QtdQte^k~P1`}FT>gO3fwcA3j@wR`{IQrGo*kxV|`7_>i;m)DsvBKzlYJ->_H@zdF|%-ECq z(!DHH&Uy9pY2Icbua#LDB4qAhXRZ5IWwb?#L)&chtF|V!QCcfz?MCKm)q3yuE1UoH zkPh*Fl&6zS5gIjTe;%Cv2h(4Lcl0lwwfSAIMDiek9zGtdhV=8ol)EMahsSt;x}K-S znBs?@$F(Z)I5toIE(#=Cu8A%Qo7nEd^_3QlD$pB z!kjx3y+<21#J!*T8QO7J&mDR@dvf6H_t*L*L#RmzC!|S_Zk~Vbh?L#q!xv__Uh~EY zqAsSNZYn3j39Wp-oy7xONjlLOdL1Y#A{U6gdjc=M&`uwvOr9iD1 zHxWUM_?4x|#1Wg`FfKJMKxc7bA)H{Zf}F-~nennQvNEYSbBhkob3r$?_CNC_i>ILY z%IMz_sjT%$cJ|aF080PAaD@M#_|Sc=QqzEj#3=;bG~X)QR^68aMj#!VSyqO=#9S3r zV@ZguhT$Ro4U?Su1ban@Ap+Cw_zW#;FZ-UJp2iT>IU^F&g6QwBvOqH$`@6OUJqDVF z+Su>=&7h2&ykwL!^%qMOgrnD?E>7uJWL72%-9JC zSyGZ_I-75HjChJI%Abp;7)!rtqyA`W7N{g+@vdJ*Y5Wh693eLsUAd4(aCW6!mc5-F zdcvximJwkii-;A#QP#4tG(+D+7x9QC|AZGLU`D~MC`}QhKChSg$i>fV;ZS_Lz58BW z_0m{9m$>)wOJlU9BxWm{$m2wwm=CVEC@DfTmm>&SA>MH{Y&!)#Ty|(t+q?{R?@_$d-e}ih02L&XSgVtXl4kduPT&>KThe footer is body content rather than page chrome: it carries glyphs and + * a reachable address, and a header/footer zone takes only strings. Page + * identity on a continuation page is carried by the page number instead.

+ */ +final class PaymentsClosing { + + /** + * A trunk prefix in a printed number is for a domestic dialler and is not + * part of the international one, so it is dropped from the dialled form. + */ + private static final Pattern TRUNK_PREFIX = Pattern.compile("\\(0+\\)"); + + private PaymentsClosing() { + } + + /** + * Draws the closing blocks. + * + * @param page the page flow + * @param notes the note block and the contacts the footer offers + * @param payment the due notice and the closing line + */ + static void render(PageFlowBuilder page, InvoiceNotesBlock notes, + InvoicePaymentBlock payment) { + if (!notes.paragraphs().isEmpty()) { + renderNotes(page, notes); + } + renderFooterRule(page); + renderFooter(page, notes, payment); + } + + /** + * Glyph column and text column as two cells, so the second body line + * returns to the text axis rather than to the glyph's. The notes introduce + * the footer, and a page that ends on one and opens on the other reads as + * two fragments — so they are kept together. + */ + private static void renderNotes(PageFlowBuilder page, InvoiceNotesBlock notes) { + page.addSection("Notes", block -> { + block.spacing(0) + .padding(DocumentInsets.zero()) + .margin(new DocumentInsets(px(1280 - 1252), 0, 0, NOTES_DISC_INSET)) + .keepWithNext(); + block.addRow("NotesRow", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .columns(DocumentRowColumn.fixed(NOTES_TEXT_INDENT), + DocumentRowColumn.weight(1)); + row.addSection("NotesDisc", disc -> disc + .spacing(0) + .add(PaymentsWidgets.disc(PaymentsIcons.DOCUMENT, NOTES_SURFACE, + NOTES_DISC_D, NOTES_GLYPH))); + row.addSection("NotesText", text -> { + text.spacing(0); + text.addParagraph(p -> p + .name("NotesLabel") + .text(notes.heading()) + .textStyle(style(NOTES_LABEL_SIZE, ACCENT, + DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets( + capOffset(1285 - 1280, NOTES_LABEL_SIZE), 0, 0, 0))); + text.addSection("NotesBody", lines -> { + lines.spacing(gap(NOTES_PITCH, PaymentsStyles.NOTES_BODY_SIZE)) + .margin(new DocumentInsets( + px(1307 - 1285) - LINE_BOX * NOTES_LABEL_SIZE + + TEXT_TOP_BEARING * (NOTES_LABEL_SIZE + - PaymentsStyles.NOTES_BODY_SIZE), 0, 0, 0)); + PaymentsWidgets.textLines(lines, "NotesLine", notes.paragraphs(), + PaymentsStyles.NOTES_BODY_SIZE, MUTED); + }); + }); + }); + }); + } + + private static void renderFooterRule(PageFlowBuilder page) { + page.addLine(line -> line + .name("FooterRule") + .horizontal(FOOTER_RULE_W) + .thickness(RULE_THIN) + .color(RULE_STRONG) + // One design px past the content box on the left, two on the + // right — measured, and small enough to look like a rounding + // error until the renderer refuses a line wider than its box. + .margin(new DocumentInsets( + FOOTER_RULE_GAP_ABOVE, + -FOOTER_RULE_OVERHANG_R, + FOOTER_RULE_GAP_BELOW, + -FOOTER_RULE_OVERHANG_L))); + } + + private static void renderFooter(PageFlowBuilder page, InvoiceNotesBlock notes, + InvoicePaymentBlock payment) { + page.addRow("DocumentFooter", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .columns(DocumentRowColumn.fixed(FOOTER_SPLIT_X), + DocumentRowColumn.weight(1)); + row.addSection("FooterDue", cell -> renderDue(cell, payment)); + row.addSection("FooterSupport", cell -> { + cell.spacing(0) + .borders(DocumentBorders.left(DocumentStroke.of(DIVIDER, RULE_THIN))) + .padding(new DocumentInsets(0, 0, 0, FOOTER_SUPPORT_CELL_INSET)); + renderSupport(cell, notes, payment); + }); + }); + } + + /** When the money is wanted, and what to quote when sending it. */ + private static void renderDue(SectionBuilder cell, InvoicePaymentBlock payment) { + cell.spacing(0).padding(new DocumentInsets(0, 0, 0, FOOTER_DUE_ICON_INSET)); + PaymentsWidgets.layeredRow(cell, "FooterDueRow", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .margin(new DocumentInsets(px(1404 - 1397), 0, 0, 0)) + .columns(DocumentRowColumn.fixed(FOOTER_DUE_ICON_COL), + DocumentRowColumn.weight(1)); + row.addSection("FooterDueIcon", glyph -> glyph + .spacing(0) + // A disc centres its glyph, so the icon box's own padding + // cancels there. A bare glyph leading a text row does not: + // the padding sits between the column's edge and the ink and + // has to be taken back off. + .margin(new DocumentInsets(-glyphPad(37), 0, 0, -glyphPad(37))) + .add(PaymentsWidgets.glyphNode(PaymentsIcons.CALENDAR, FOOTER_DUE_ICON, + HorizontalAlign.LEFT))); + row.addSection("FooterDueText", text -> { + text.spacing(0); + text.addParagraph(p -> p + .name("FooterDueTitle") + .text(dueTitle(payment)) + .textStyle(style(FOOTER_DUE_TITLE_SIZE, INK, + DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets( + capOffset(1408 - 1404, FOOTER_DUE_TITLE_SIZE), 0, 0, 0))); + if (!payment.instruction().isBlank()) { + text.addParagraph(p -> p + .name("FooterDueSubtitle") + .text(payment.instruction()) + .textStyle(style(FOOTER_SUB_SIZE, BODY, + DocumentTextDecoration.DEFAULT)) + .margin(new DocumentInsets( + px(1428 - 1408) - LINE_BOX * FOOTER_DUE_TITLE_SIZE + + TEXT_TOP_BEARING + * (FOOTER_DUE_TITLE_SIZE - FOOTER_SUB_SIZE), + 0, 0, 0))); + } + }); + }); + } + + /** + * The design sets this line in capitals, so the preset uppercases whichever + * of the two due strings the document filled — the emphasis when it has one, + * the notice itself otherwise. + */ + private static String dueTitle(InvoicePaymentBlock payment) { + String text = payment.dueNoticeEmphasis().isBlank() + ? payment.dueNotice() + : payment.dueNoticeEmphasis(); + return text.toUpperCase(Locale.ROOT); + } + + /** Who to ask, and how to reach them. */ + private static void renderSupport(SectionBuilder cell, InvoiceNotesBlock notes, + InvoicePaymentBlock payment) { + PaymentsWidgets.layeredRow(cell, "FooterSupportRow", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .margin(new DocumentInsets(px(1405 - 1397), 0, 0, 0)) + .columns(DocumentRowColumn.fixed(FOOTER_SUPPORT_ICON_COL), + DocumentRowColumn.weight(1)); + row.addSection("FooterSupportIcon", glyph -> glyph + .spacing(0) + .margin(new DocumentInsets(-glyphPad(39), 0, 0, -glyphPad(39))) + .add(PaymentsWidgets.glyphNode(PaymentsIcons.SUPPORT, FOOTER_SUPPORT_ICON, + HorizontalAlign.LEFT))); + row.addSection("FooterSupportText", text -> { + text.spacing(0); + if (!payment.signOff().isBlank()) { + text.addParagraph(p -> p + .name("FooterSupportTitle") + .text(payment.signOff()) + .textStyle(style(FOOTER_SUPPORT_TITLE_SIZE, INK, + DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets( + capOffset(1408 - 1405, FOOTER_SUPPORT_TITLE_SIZE), 0, 0, 0))); + } + // Separate runs, so each address reaches the PDF as a real + // annotation rather than as coloured text. + text.addParagraph(p -> { + p.name("FooterSupportContacts"); + boolean hasEmail = !notes.contactEmail().isBlank(); + if (hasEmail) { + p.inlineText(notes.contactEmail(), + style(FOOTER_SUB_SIZE, ACCENT, DocumentTextDecoration.DEFAULT), + new DocumentLinkOptions("mailto:" + notes.contactEmail())); + } + if (!notes.contactPhone().isBlank()) { + if (hasEmail) { + p.inlineText(" | ", style(FOOTER_SUB_SIZE, MUTED, + DocumentTextDecoration.DEFAULT)); + } + String dialled = telUri(notes.contactPhone()); + if (dialled == null) { + p.inlineText(notes.contactPhone(), style(FOOTER_SUB_SIZE, BODY, + DocumentTextDecoration.DEFAULT)); + } else { + p.inlineText(notes.contactPhone(), style(FOOTER_SUB_SIZE, BODY, + DocumentTextDecoration.DEFAULT), + new DocumentLinkOptions(dialled)); + } + } + p.margin(new DocumentInsets( + px(1432 - 1408) - LINE_BOX * FOOTER_SUPPORT_TITLE_SIZE + + TEXT_TOP_BEARING + * (FOOTER_SUPPORT_TITLE_SIZE - FOOTER_SUB_SIZE), 0, 0, 0)); + }); + }); + }); + } + + /** A printed number as something a reader can dial, or {@code null}. */ + private static String telUri(String phone) { + String dialled = TRUNK_PREFIX.matcher(phone).replaceAll(""); + String digits = dialled.replaceAll("[^0-9]", ""); + return digits.isEmpty() ? null + : "tel:" + (phone.trim().startsWith("+") ? "+" : "") + digits; + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsIcons.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsIcons.java new file mode 100644 index 000000000..3d59df9ee --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsIcons.java @@ -0,0 +1,94 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.svg.SvgIcon; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Classpath loader for the Payments invoice marks: the two party glyphs, the + * six a service line may take, and the four the preset places itself — the + * bank on the payment card, the document on the notes, the calendar on the due + * block and the headset on the support block. + * + *

They ship inside the templates artifact under + * {@code templates/invoice/payments/icons/} as SVG, so they scale with the box + * they are drawn into rather than being resampled. Parsed icons are cached per + * token, so a sheet that repeats a mark reads each file once per JVM.

+ * + *

The set is coloured, not tinted

+ * + *

Each glyph carries its colour in its own markup, in one of the design's + * two tints: ink for the marks that sit inside a lavender disc, accent for the + * ones that stand on the page. A token therefore names a glyph and the + * tint it is drawn in, which is why {@link #HEADSET} and {@link #SUPPORT} are + * the same drawing under two names — one opens a service line inside a disc, + * the other closes the sheet on the page.

+ * + *

{@link #LINE_TOKENS} is the vocabulary a document names through + * {@code InvoiceServiceLines.Line.icon()}. It is scoped to this preset — + * another preset packages its own set.

+ */ +final class PaymentsIcons { + + static final String BILL_TO = "bill-to"; + static final String SHIP_TO = "ship-to"; + static final String BANK = "bank"; + static final String DOCUMENT = "document"; + static final String CALENDAR = "calendar"; + static final String SUPPORT = "support"; + static final String HEADSET = "headset"; + + private static final String ICON_ROOT = "/templates/invoice/payments/icons/"; + + /** Every mark this preset packages. */ + private static final Set TOKENS = Set.of( + BILL_TO, SHIP_TO, BANK, DOCUMENT, CALENDAR, SUPPORT, + "card", "card-settings", "shield", "globe", "mobile", HEADSET); + + /** The marks a document may name on a service line. */ + static final Set LINE_TOKENS = Set.of( + "card", "card-settings", "shield", "globe", "mobile", HEADSET); + + private static final Map CACHE = new ConcurrentHashMap<>(); + + private PaymentsIcons() { + } + + /** + * Reads one mark. + * + * @param token one of the packaged tokens + * @return the parsed icon + * @throws IllegalArgumentException when the token names no packaged mark, + * listing the ones a document may choose — an icon token is data, + * so a wrong one is a data error + */ + static SvgIcon icon(String token) { + if (!TOKENS.contains(token)) { + throw new IllegalArgumentException( + "Unknown payments invoice icon token '" + token + + "'. This preset packages " + LINE_TOKENS.stream().sorted().toList() + + " for a service line's mark."); + } + return CACHE.computeIfAbsent(token, PaymentsIcons::read); + } + + private static SvgIcon read(String token) { + String resourcePath = ICON_ROOT + token + ".svg"; + try (InputStream input = PaymentsIcons.class.getResourceAsStream(resourcePath)) { + if (input == null) { + throw new IllegalStateException("Missing payments invoice icon: " + resourcePath); + } + return SvgIcon.parse(new String(input.readAllBytes(), StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new UncheckedIOException( + "Failed to read payments invoice icon: " + resourcePath, e); + } + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoice.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoice.java new file mode 100644 index 000000000..a51312a8b --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsInvoice.java @@ -0,0 +1,167 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.api.PageMarginRule; +import com.demcha.compose.document.output.DocumentHeaderFooter; +import com.demcha.compose.document.output.DocumentHeaderFooterZone; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.templates.api.DocumentTemplate; +import com.demcha.compose.document.templates.data.invoice.StructuredInvoiceData; + +import java.util.List; +import java.util.Objects; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CONTINUATION_MARGIN; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.MUTED; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PAGE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PAGE_MARGIN; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PAGE_NUMBER_BAND; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PAGE_NUMBER_SIZE; + +/** + * Payments — a lavender-and-navy invoice: a masthead crossed by a diagonal + * band, a half-split issuer and metadata header, two addressed parties, a + * marked line-item table, a settlement row pairing bank details against the + * totals, a note block and a two-cell document footer. + * + *

It flows

+ * + *

Unlike most presets in this package the sheet is not drawn for one page. + * The design shows six service lines and a real month of usage brings dozens, + * so the table is the region that grows: its header repeats on every page it + * reaches, a continuation page reserves a deeper bottom margin than page one, + * and every page carries its number. Pagination here is load-bearing rather + * than incidental — a financial record that runs over has to make a missing + * page detectable.

+ * + *

The lockup is the caller's

+ * + *

The design's mark occupies a measured 136 × 55.3 design px box beside the + * title. What fills it comes from {@code InvoiceBrand}: a document that brings + * a logo has it drawn to that height, so a wider or narrower mark keeps the + * design's optical weight; a document that brings only a name has the name set + * as a wordmark. The templates artifact carries no mark of its own.

+ * + *

One column, not five

+ * + *

The table has an outer box and a rule between every row and no interior + * verticals, which is exactly what a single-column table draws — a cell strokes + * all four of its own edges, and a one-column table has no interior vertical + * edge. The five columns are a row inside each cell, on shares of the table's + * width. Building it the other way round, with the box from a stroked section + * wrapped round the table, is wrong on a document that paginates: a section's + * box fills its page fragment rather than hugging its rows, so every + * continuation page would end with an empty bordered strip.

+ * + *

Every horizontal pair inside a cell is a wrapped row

+ * + *

A row nested directly in a row cell is refused by the layout compiler, so + * each such pair — a party's mark and its label, a line's mark and its text, + * the card's fields, the totals grid — is a row wrapped in a single layer of a + * stack.

+ * + *

What the document says, and what the preset chooses

+ * + *

A service line names its own mark through + * {@code InvoiceServiceLines.Line.icon()}, from this preset's own vocabulary, + * and an unknown token is reported as a data error naming the set. A line with + * no token is drawn without a mark. The other four marks are the preset's: + * which glyph opens the bill-to block, the payment card, the notes and the two + * footer cells is a property of the design rather than of the document.

+ * + *

Figures are written with the locale stated rather than inherited, so the + * same data renders the same sheet on any machine. The currency is named once + * in the amount column's header and its symbol carried on each figure.

+ * + *

Fonts

+ * + *

The sheet is set in Lato throughout. The templates artifact carries no + * fonts — register the family on the session, or the engine substitutes and the + * measured geometry no longer matches the type sitting in it.

+ * + *

Usage:

+ *
{@code
+ * DocumentTemplate template = PaymentsInvoice.create();
+ * template.compose(session, invoice);
+ * }
+ * + * @since 2.2.3 + */ +public final class PaymentsInvoice { + + /** Stable identifier of this preset. */ + public static final String ID = "payments-invoice"; + + /** Human-readable name of this preset. */ + public static final String DISPLAY_NAME = "Payments Invoice"; + + private PaymentsInvoice() { + } + + /** + * Creates the template. + * + * @return a template composing a {@link StructuredInvoiceData} + */ + public static DocumentTemplate create() { + return new Template(); + } + + private record Template() implements DocumentTemplate { + + @Override + public String id() { + return ID; + } + + @Override + public String displayName() { + return DISPLAY_NAME; + } + + @Override + public void compose(DocumentSession document, StructuredInvoiceData data) { + Objects.requireNonNull(document, "document"); + Objects.requireNonNull(data, "data"); + + // Every length on the sheet is a share of the design's own grid, so + // the preset sets the page and its margins rather than following + // what the caller configured. + document.pageSize(PAGE); + document.margin(PAGE_MARGIN); + document.pageMargins(List.of(PageMarginRule.from(2, CONTINUATION_MARGIN))); + renderPageNumber(document); + + String currency = data.currencyCode(); + document.pageFlow(page -> { + page.name("PaymentsInvoice").padding(DocumentInsets.zero()).spacing(0); + PaymentsMasthead.render(page, data.brand(), data.supplier(), data.masthead()); + PaymentsParties.render(page, data.billTo(), data.shipTo()); + PaymentsLines.render(page, data.serviceLines(), currency); + PaymentsSettlement.render(page, data.payment(), data.totals(), currency); + PaymentsClosing.render(page, data.notes(), data.payment()); + }); + } + + /** + * The only chrome the sheet has, and an addition rather than a + * reproduction: the design is one page and carries no number. + * + *

The height is stated because a default band would take more than + * the bottom margin leaves and push the footer onto a second page. + * Sized to the margin, the band sits inside it rather than taking + * content space, and the type is sized to the band rather than the + * other way round.

+ */ + private static void renderPageNumber(DocumentSession document) { + document.footer(DocumentHeaderFooter.builder() + .zone(DocumentHeaderFooterZone.FOOTER) + .centerText("Page {page} of {pages}") + .height((float) PAGE_NUMBER_BAND) + .fontSize((float) PAGE_NUMBER_SIZE) + .textColor(MUTED) + .showSeparator(false) + .build()); + } + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsLines.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsLines.java new file mode 100644 index 000000000..62186a101 --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsLines.java @@ -0,0 +1,237 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.dsl.PageFlowBuilder; +import com.demcha.compose.document.dsl.RowBuilder; +import com.demcha.compose.document.dsl.TableBuilder; +import com.demcha.compose.document.node.DocumentNode; +import com.demcha.compose.document.node.RowVerticalAlign; +import com.demcha.compose.document.node.TextAlign; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentRowColumn; +import com.demcha.compose.document.style.DocumentTextDecoration; +import com.demcha.compose.document.table.DocumentTableCell; +import com.demcha.compose.document.table.DocumentTableColumn; +import com.demcha.compose.document.templates.data.invoice.InvoiceServiceLines; + +import java.util.List; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT_SURFACE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.AMOUNT_PAD_R; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CELL_AMOUNT_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CELL_PAD_R; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CELL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.COLUMN_SHARES; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CONTENT_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DESC_PAD_L; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DISC_D; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.HEADER_CELL_STYLE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.INK; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_CELL_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_CELL_STYLE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_DISC_GAP; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_SUB_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_SUB_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_TEXT_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ITEM_TITLE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.LINE_BOX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.MUTED; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TABLE_HEAD_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TABLE_HEAD_SMALL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TEXT_TOP_BEARING; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.gap; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.px; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.style; + +/** + * The service lines. + * + *

One column, not five

+ * + *

The design's table has an outer box and a rule between every row and + * no interior verticals — which is exactly the rule topology a + * single-column table draws, because a cell strokes all four of its own edges + * and a one-column table has no interior vertical edge to draw. The five + * columns are a row inside each cell, laid out on shares of the table's width, + * so they stay aligned down the page without the engine drawing a line between + * them.

+ * + *

The alternative — unstroked cells, separators as line rows, and the outer + * box from a stroked section wrapped round the table — is wrong on a document + * that paginates: a section's box fills its page fragment rather than hugging + * its rows, so every continuation page would end with an empty bordered strip + * below its last line. Cell borders have no such problem, because the engine + * redraws each page's cell edges from the same styles and every fragment closes + * on its own last row.

+ */ +final class PaymentsLines { + + private PaymentsLines() { + } + + /** + * Draws the table. + * + * @param page the page flow + * @param serviceLines the columns and the lines + * @param currencyCode the ISO code the figures are stated in + */ + static void render(PageFlowBuilder page, InvoiceServiceLines serviceLines, + String currencyCode) { + page.addSection("LineItemsBox", box -> { + box.spacing(0) + .padding(DocumentInsets.zero()) + .margin(new DocumentInsets(px(596 - 567), 0, px(1060 - 1042), 0)); + box.addTable(table -> { + table.name("LineItems") + .width(CONTENT_W) + .columns(DocumentTableColumn.fixed(CONTENT_W)); + renderHeader(table, serviceLines.columns(), currencyCode); + List lines = serviceLines.lines(); + for (int i = 0; i < lines.size(); i++) { + table.rowCells(DocumentTableCell + .node(renderLine(lines.get(i), i, currencyCode)) + .withStyle(ITEM_CELL_STYLE)); + } + }); + }); + } + + /** + * The header repeats on every page its table reaches. It is one cell like + * every other row, so its own stroke draws the table's top edge and the rule + * under the band, and its fill is the tint. + */ + private static void renderHeader(TableBuilder table, InvoiceServiceLines.Columns columns, + String currencyCode) { + RowBuilder row = new RowBuilder(); + row.name("LineItemsHeader").spacing(0).columns(columnWidths()); + row.addParagraph(p -> p + .name("HeadDescription") + .text(columns.description()) + .textStyle(style(TABLE_HEAD_SIZE, INK, DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets(0, 0, 0, DESC_PAD_L))); + headCell(row, "HeadQuantity", columns.quantity(), TextAlign.CENTER, 0); + headCell(row, "HeadUnitPrice", columns.unitPrice(), TextAlign.RIGHT, CELL_PAD_R); + headCell(row, "HeadVat", columns.vat(), TextAlign.CENTER, 0); + // Two runs: the currency qualifier is set smaller than the label it + // follows, which one paragraph of one style cannot express. The design + // names the currency once, here, rather than on every amount. + row.addParagraph(p -> { + p.name("HeadAmount"); + p.inlineText(columns.amount(), style(TABLE_HEAD_SIZE, INK, DocumentTextDecoration.BOLD)); + if (!currencyCode.isBlank()) { + p.inlineText(" (" + currencyCode + ")", + style(TABLE_HEAD_SMALL_SIZE, INK, DocumentTextDecoration.BOLD)); + } + p.align(TextAlign.RIGHT); + p.padding(new DocumentInsets(0, AMOUNT_PAD_R, 0, 0)); + }); + table.headerCells(DocumentTableCell.node(row.build()).withStyle(HEADER_CELL_STYLE)) + .repeatHeader(); + } + + private static void headCell(RowBuilder row, String name, String label, TextAlign align, + double padRight) { + row.addParagraph(p -> p + .name(name) + .text(label) + .textStyle(style(TABLE_HEAD_SIZE, INK, DocumentTextDecoration.BOLD)) + .align(align) + .padding(new DocumentInsets(0, padRight, 0, 0))); + } + + /** + * The five columns as a row inside the row's single cell. Alignment differs + * per column and is part of the design rather than an accident: description + * left, quantity centred, unit price right, tax centred, amount right. + */ + private static DocumentNode renderLine(InvoiceServiceLines.Line line, int index, + String currencyCode) { + int n = index + 1; + RowBuilder row = new RowBuilder(); + row.name("Item" + n) + .spacing(0) + .verticalAlign(RowVerticalAlign.CENTER) + .columns(columnWidths()); + row.addSection("ItemDescription" + n, cell -> { + cell.spacing(0).padding(new DocumentInsets(0, 0, 0, ITEM_CELL_INSET)); + // Mark and text are a horizontal pair inside a row cell, which the + // layout compiler refuses as a bare row. + PaymentsWidgets.layeredRow(cell, "ItemBody" + n, body -> { + body.spacing(ITEM_DISC_GAP) + .verticalAlign(RowVerticalAlign.CENTER) + .columns(DocumentRowColumn.fixed(DISC_D), + DocumentRowColumn.fixed(ITEM_TEXT_W)); + body.addSection("ItemDisc" + n, disc -> { + disc.spacing(0); + if (!line.icon().isBlank()) { + disc.add(PaymentsWidgets.disc(line.icon(), ACCENT_SURFACE)); + } + }); + body.addSection("ItemText" + n, text -> { + text.spacing(0); + text.addParagraph(p -> p + .name("ItemTitle" + n) + .text(line.title()) + .textStyle(style(ITEM_TITLE_SIZE, INK, DocumentTextDecoration.BOLD))); + if (!line.description().isBlank()) { + text.addParagraph(p -> p + .name("ItemSubtitle" + n) + .text(line.description()) + .textStyle(style(ITEM_SUB_SIZE, MUTED, + DocumentTextDecoration.DEFAULT)) + .lineSpacing(gap(ITEM_SUB_PITCH, ITEM_SUB_SIZE)) + .margin(new DocumentInsets( + px(668 - 648) - LINE_BOX * ITEM_TITLE_SIZE + + TEXT_TOP_BEARING + * (ITEM_TITLE_SIZE - ITEM_SUB_SIZE), + 0, 0, 0))); + } + }); + }); + }); + valueCell(row, "ItemQuantity" + n, PaymentsText.quantity(line.quantity()), + CELL_SIZE, BODY, DocumentTextDecoration.DEFAULT, TextAlign.CENTER, 0); + valueCell(row, "ItemUnitPrice" + n, PaymentsText.amount(currencyCode, line.unitPrice()), + CELL_SIZE, BODY, DocumentTextDecoration.DEFAULT, TextAlign.RIGHT, CELL_PAD_R); + valueCell(row, "ItemVat" + n, line.vatRate(), + CELL_SIZE, BODY, DocumentTextDecoration.DEFAULT, TextAlign.CENTER, 0); + valueCell(row, "ItemAmount" + n, PaymentsText.amount(currencyCode, line.amount()), + CELL_AMOUNT_SIZE, INK, DocumentTextDecoration.BOLD, TextAlign.RIGHT, AMOUNT_PAD_R); + return row.build(); + } + + private static void valueCell(RowBuilder row, String name, String value, double size, + DocumentColor color, DocumentTextDecoration decoration, + TextAlign align, double padRight) { + row.addParagraph(p -> p + .name(name) + .text(value) + .textStyle(style(size, color, decoration)) + .align(align) + // padding, not margin: a paragraph's right margin inside a row + // column is taken twice — once off the box's width and again as + // an offset — so a 22 px inset would land the text 44 px in. + .padding(new DocumentInsets(0, padRight, 0, 0))); + } + + /** + * The five column widths as shares of the table's own width. The last takes + * whatever the others leave: five independently rounded shares sum to the + * width plus a half-thousandth of a point, and the engine refuses a row + * narrower than its columns. + */ + private static DocumentRowColumn[] columnWidths() { + DocumentRowColumn[] columns = new DocumentRowColumn[COLUMN_SHARES.length]; + double assigned = 0; + for (int i = 0; i < COLUMN_SHARES.length - 1; i++) { + double width = CONTENT_W * COLUMN_SHARES[i]; + assigned += width; + columns[i] = DocumentRowColumn.fixed(width); + } + columns[COLUMN_SHARES.length - 1] = DocumentRowColumn.fixed(CONTENT_W - assigned); + return columns; + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsMasthead.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsMasthead.java new file mode 100644 index 000000000..c603a47f8 --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsMasthead.java @@ -0,0 +1,319 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.dsl.ImageBuilder; +import com.demcha.compose.document.dsl.PageFlowBuilder; +import com.demcha.compose.document.dsl.PathBuilder; +import com.demcha.compose.document.dsl.RowBuilder; +import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.node.DocumentNode; +import com.demcha.compose.document.node.LayerAlign; +import com.demcha.compose.document.node.RowVerticalAlign; +import com.demcha.compose.document.style.DocumentBorders; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentRowColumn; +import com.demcha.compose.document.style.DocumentStroke; +import com.demcha.compose.document.style.DocumentTextDecoration; +import com.demcha.compose.document.templates.data.invoice.InvoiceBrand; +import com.demcha.compose.document.templates.data.invoice.InvoiceContactBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceMasthead; + +import java.util.ArrayList; +import java.util.List; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT_BAR_H; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT_BAR_OFFSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT_BAR_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_BOTTOM_PX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_H; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_LAVENDER; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_LAVENDER_QUAD; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_LEFT_PX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_NAVY_QUAD; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_RIGHT_PX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BAND_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BRAND_LOCKUP_H; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BRAND_LOCKUP_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DIVIDER; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.HEADER_RULE_OVERHANG_L; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.HEADER_RULE_OVERHANG_R; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.HEADER_RULE_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.HEADER_STACK_BOTTOM_PX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.INK; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ISSUER_NAME_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.LINE_BOX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.MARGIN_T; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_COL_X; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_LABEL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_LABEL_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_VALUE_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.META_VALUE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.RULE_MED; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.RULE_SOFT; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TEXT_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TEXT_TOP_BEARING; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TITLE_DROP; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TITLE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.WORDMARK_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.gap; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.px; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.style; + +/** + * The header: the diagonal band, the lockup beside the title, the issuer block + * against the metadata grid, and the rule that closes them. + * + *

One stack, because two of its three parts are page furniture

+ * + *

The band bleeds past the top margin to the paper's edge and the accent bar + * stands left of the content box, so neither belongs to the flow. Both are + * positioned by offset from the stack's top-left; only the header content is a + * layer.

+ * + *

The lockup box is the design's, whatever fills it

+ * + *

The design's mark measures 136 × 55.3 design px. A document that brings a + * logo has it drawn to that height, so a wider or narrower mark keeps the + * design's optical weight; a document that brings only a name has the name set + * as a wordmark instead. Either way the title beside it does not move, because + * the title is a left-anchored member of the metadata column rather than a + * right-anchored member of the page.

+ */ +final class PaymentsMasthead { + + private PaymentsMasthead() { + } + + /** + * Draws the header and its closing rule. + * + * @param page the page flow + * @param brand the lockup + * @param supplier who is invoicing + * @param masthead the title and the metadata rows + */ + static void render(PageFlowBuilder page, InvoiceBrand brand, InvoiceContactBlock supplier, + InvoiceMasthead masthead) { + page.addLayerStack(stack -> stack + .name("MastheadStack") + .padding(DocumentInsets.zero()) + .position(band(), px(BAND_LEFT_PX - 51), -MARGIN_T, LayerAlign.TOP_LEFT, 0) + .position(accentBar(), ACCENT_BAR_OFFSET, 0, LayerAlign.TOP_LEFT, 0) + .layer(headerContent(brand, supplier, masthead), LayerAlign.TOP_LEFT, 1)); + renderHeaderRule(page); + } + + /** The lavender quadrilateral, then the navy one over it. */ + private static DocumentNode band() { + SectionBuilder band = new SectionBuilder(); + band.name("HeaderBand").spacing(0).padding(DocumentInsets.zero()); + band.addLayerStack(stack -> stack + .name("HeaderBandLayers") + .layer(quad("BandLavender", BAND_LAVENDER, BAND_LAVENDER_QUAD), + LayerAlign.TOP_LEFT, 0) + .layer(quad("BandNavy", INK, BAND_NAVY_QUAD), LayerAlign.TOP_LEFT, 1)); + return band.build(); + } + + /** + * One quadrilateral of the band. The corners arrive in page design pixels + * and are normalised here — {@link #nx} and {@link #ny} are the only place + * the bottom-left origin of a path's coordinate space is dealt with. + */ + private static DocumentNode quad(String name, DocumentColor fill, double[][] corners) { + PathBuilder path = new PathBuilder(); + path.name(name).size(BAND_W, BAND_H).fillColor(fill); + path.moveTo(nx(corners[0][0]), ny(corners[0][1])); + for (int i = 1; i < corners.length; i++) { + path.lineTo(nx(corners[i][0]), ny(corners[i][1])); + } + return path.closePath().build(); + } + + private static double nx(double pagePx) { + return (pagePx - BAND_LEFT_PX) / (BAND_RIGHT_PX - BAND_LEFT_PX); + } + + /** Page y runs down; a path's y runs up from its own bottom edge. */ + private static double ny(double pagePx) { + return 1.0 - pagePx / BAND_BOTTOM_PX; + } + + private static DocumentNode accentBar() { + SectionBuilder holder = new SectionBuilder(); + holder.name("AccentBarHolder").spacing(0).padding(DocumentInsets.zero()); + holder.addLine(line -> line + .name("HeaderAccentBar") + .vertical(ACCENT_BAR_H) + .thickness(ACCENT_BAR_W) + .color(ACCENT)); + return holder.build(); + } + + private static DocumentNode headerContent(InvoiceBrand brand, InvoiceContactBlock supplier, + InvoiceMasthead masthead) { + SectionBuilder content = new SectionBuilder(); + content.name("HeaderContent").spacing(0).padding(DocumentInsets.zero()); + content.addRow("Masthead", row -> renderLockupRow(row, brand, masthead)); + content.addRow("HeaderSplit", row -> { + // The two cells of the split do not share a top edge: the metadata + // block starts 11 px below the issuer name's box. + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + // 12 px by the design's own ink gap, less the 2.5 the title's + // line box gives back. + .margin(new DocumentInsets(px(12 - 2.5), 0, 0, 0)) + .columns(DocumentRowColumn.fixed(META_COL_X), DocumentRowColumn.weight(1)); + row.addSection("IssuerBlock", cell -> renderIssuer(cell, supplier)); + row.addSection("InvoiceMeta", cell -> { + cell.spacing(0).padding(new DocumentInsets(px(11), 0, 0, 0)); + renderMeta(cell, masthead.entries()); + }); + }); + return content.build(); + } + + /** + * TOP, not CENTER: the title's line box is much taller than the lockup, so + * centring would push the lockup down the row it is supposed to set the top + * edge of. + */ + private static void renderLockupRow(RowBuilder row, InvoiceBrand brand, + InvoiceMasthead masthead) { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .margin(new DocumentInsets(px(46 - 28), 0, 0, 0)) + .columns(DocumentRowColumn.fixed(META_COL_X), DocumentRowColumn.weight(1)); + row.addSection("BrandLockup", cell -> { + cell.spacing(0).padding(new DocumentInsets(0, 0, 0, BRAND_LOCKUP_INSET)); + if (brand.logo() != null) { + cell.add(new ImageBuilder() + .name("BrandLogo") + .source(brand.logo()) + .height(BRAND_LOCKUP_H) + .build()); + } else if (!brand.name().isBlank()) { + cell.addParagraph(p -> p + .name("BrandWordmark") + .text(brand.name()) + .textStyle(style(WORDMARK_SIZE, ACCENT, DocumentTextDecoration.BOLD))); + } + }); + row.addParagraph(p -> p + .name("InvoiceTitle") + .text(masthead.title()) + .textStyle(style(TITLE_SIZE, INK, DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets(TITLE_DROP, 0, 0, 0))); + } + + /** + * The issuer's name, its address, and its registrations — the last set off + * by exactly two line pitches. That gap is authored, not drift. + */ + private static void renderIssuer(SectionBuilder cell, InvoiceContactBlock supplier) { + cell.spacing(0).padding(new DocumentInsets(0, 0, 0, TEXT_INSET)); + cell.addParagraph(p -> p + .name("IssuerName") + .text(supplier.legalName()) + .textStyle(style(ISSUER_NAME_SIZE, INK, DocumentTextDecoration.BOLD))); + cell.addSection("IssuerAddress", lines -> { + lines.spacing(gap(21.33, BODY_SIZE)) + .margin(new DocumentInsets(px(172 - 140) - LINE_BOX * ISSUER_NAME_SIZE + + TEXT_TOP_BEARING * (ISSUER_NAME_SIZE - BODY_SIZE), 0, 0, 0)); + PaymentsWidgets.textLines(lines, "IssuerAddressLine", supplier.addressLines(), + BODY_SIZE, BODY); + }); + List registrations = registrationLines(supplier); + if (!registrations.isEmpty()) { + cell.addSection("IssuerRegistration", lines -> { + lines.spacing(gap(21.0, BODY_SIZE)) + .margin(new DocumentInsets(gap(2 * 21.33, BODY_SIZE), 0, 0, 0)); + PaymentsWidgets.textLines(lines, "IssuerRegistrationLine", registrations, + BODY_SIZE, BODY); + }); + } + } + + /** The two labelled registrations a supplier may carry, as printed lines. */ + private static List registrationLines(InvoiceContactBlock supplier) { + List lines = new ArrayList<>(); + addRegistration(lines, supplier.registrationLabel(), supplier.registrationNumber()); + addRegistration(lines, supplier.taxRegistrationLabel(), supplier.taxRegistrationNumber()); + return lines; + } + + private static void addRegistration(List lines, String label, String number) { + if (number == null || number.isBlank()) { + return; + } + lines.add(label == null || label.isBlank() ? number : label + " " + number); + } + + /** + * Two stacks side by side rather than a row per entry, so the divider + * between them is one continuous border. It is the value column's left + * border, not a node: that is why it begins with the first row and ends with + * the last rather than running the block's full box. + * + *

The two stacks carry different spacings because their type sizes differ + * — a bold label and a regular value have different line boxes — and the + * shared pitch is what makes their rows line up.

+ */ + private static void renderMeta(SectionBuilder cell, List entries) { + PaymentsWidgets.layeredRow(cell, "MetaGrid", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + .columns(DocumentRowColumn.fixed(META_LABEL_W), DocumentRowColumn.weight(1)); + row.addSection("MetaLabels", labels -> { + labels.spacing(gap(META_PITCH, META_LABEL_SIZE)); + int index = 0; + for (InvoiceMasthead.Entry entry : entries) { + String name = "MetaLabel" + (++index); + labels.addParagraph(p -> p + .name(name) + .text(entry.label()) + .textStyle(style(META_LABEL_SIZE, INK, DocumentTextDecoration.BOLD))); + } + }); + row.addSection("MetaValues", values -> { + values.spacing(gap(META_PITCH, META_VALUE_SIZE)) + .borders(DocumentBorders.left(DocumentStroke.of(DIVIDER, RULE_MED))) + .padding(new DocumentInsets(0, 0, 0, META_VALUE_INSET)); + int index = 0; + for (InvoiceMasthead.Entry entry : entries) { + String name = "MetaValue" + (++index); + values.addParagraph(p -> p + .name(name) + .text(entry.value()) + .textStyle(entry.emphasized() + ? style(META_LABEL_SIZE, ACCENT, DocumentTextDecoration.BOLD) + : style(META_VALUE_SIZE, BODY, + DocumentTextDecoration.DEFAULT))); + } + }); + }); + } + + /** + * Wider than the content box on both sides — it is furniture for the header + * block rather than a divider between two pieces of content, which is why it + * overhangs. Its top margin is negative because the band, not the content, + * is the tallest layer of the stack above it. + */ + private static void renderHeaderRule(PageFlowBuilder page) { + page.addLine(line -> line + .name("HeaderRule") + .horizontal(HEADER_RULE_W) + .thickness(RULE_MED) + .color(RULE_SOFT) + .margin(new DocumentInsets( + px(359 - HEADER_STACK_BOTTOM_PX), + -HEADER_RULE_OVERHANG_R, + px(378 - 361), + -HEADER_RULE_OVERHANG_L))); + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsParties.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsParties.java new file mode 100644 index 000000000..8ed94a8ed --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsParties.java @@ -0,0 +1,127 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.dsl.PageFlowBuilder; +import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.node.RowVerticalAlign; +import com.demcha.compose.document.style.DocumentBorders; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentRowColumn; +import com.demcha.compose.document.style.DocumentStroke; +import com.demcha.compose.document.style.DocumentTextDecoration; +import com.demcha.compose.document.templates.data.invoice.InvoiceRecipient; + +import java.util.ArrayList; +import java.util.List; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT_SURFACE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DISC_D; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DIVIDER; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.INK; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.LINE_BOX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_ADDRESS_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_CELL_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_DISC_GAP; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_DISC_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_LABEL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_NAME_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.PARTY_TEXT_INDENT; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.RULE_THIN; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TEXT_TOP_BEARING; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.capOffset; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.gap; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.px; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.style; + +/** + * The addressed parties: who is billed, and where the work went. + * + *

One method draws both — they are the same component with different data, + * down to the registration line only one of them usually has. The divider + * belongs to the split, so it is the second cell's own left edge rather than a + * rule drawn between the two.

+ */ +final class PaymentsParties { + + private PaymentsParties() { + } + + /** + * Draws the row. + * + * @param page the page flow + * @param billTo who is billed + * @param shipTo where the work went, or a party with no name when absent + */ + static void render(PageFlowBuilder page, InvoiceRecipient billTo, InvoiceRecipient shipTo) { + List parties = new ArrayList<>(); + parties.add(new Party(PaymentsIcons.BILL_TO, billTo)); + if (!shipTo.name().isBlank()) { + parties.add(new Party(PaymentsIcons.SHIP_TO, shipTo)); + } + + page.addRow("PartiesRow", row -> { + row.spacing(0).verticalAlign(RowVerticalAlign.TOP).evenWeights(); + for (int i = 0; i < parties.size(); i++) { + Party party = parties.get(i); + boolean first = i == 0; + row.addSection("Party" + (i + 1), cell -> { + cell.spacing(0); + if (first) { + cell.padding(new DocumentInsets(0, 0, 0, PARTY_DISC_INSET)); + } else { + cell.borders(DocumentBorders.left(DocumentStroke.of(DIVIDER, RULE_THIN))) + .padding(new DocumentInsets(0, 0, 0, PARTY_CELL_INSET)); + } + renderParty(cell, party); + }); + } + }); + } + + private static void renderParty(SectionBuilder cell, Party party) { + InvoiceRecipient who = party.recipient(); + PaymentsWidgets.layeredRow(cell, "PartyHead", row -> { + row.spacing(PARTY_DISC_GAP) + .verticalAlign(RowVerticalAlign.TOP) + .columns(DocumentRowColumn.fixed(DISC_D), DocumentRowColumn.weight(1)); + row.addSection("PartyDisc", disc -> disc + .spacing(0) + .add(PaymentsWidgets.disc(party.token(), ACCENT_SURFACE))); + row.addParagraph(p -> p + .name("PartyLabel") + .text(who.heading()) + .textStyle(style(PARTY_LABEL_SIZE, INK, DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets(capOffset(391 - 378, PARTY_LABEL_SIZE), 0, 0, 0))); + }); + cell.addSection("PartyBody", block -> { + block.spacing(0).padding(new DocumentInsets(0, 0, 0, PARTY_TEXT_INDENT)); + block.addParagraph(p -> p + .name("PartyName") + .text(who.name()) + .textStyle(style(PARTY_NAME_SIZE, INK, DocumentTextDecoration.BOLD))); + block.addSection("PartyAddress", lines -> { + lines.spacing(gap(PARTY_ADDRESS_PITCH, BODY_SIZE)) + .margin(new DocumentInsets(px(451 - 423) - LINE_BOX * PARTY_NAME_SIZE + + TEXT_TOP_BEARING * (PARTY_NAME_SIZE - BODY_SIZE), 0, 0, 0)); + PaymentsWidgets.textLines(lines, "PartyAddressLine", who.addressLines(), + BODY_SIZE, BODY); + }); + // The subline is drawn UNDER the address, set off by the design's own + // gap: this sheet uses it for the registration a billed party prints + // below where it is, not for a second line of its name. + if (!who.subline().isBlank()) { + block.addParagraph(p -> p + .name("PartySubline") + .text(who.subline()) + .textStyle(style(BODY_SIZE, BODY, DocumentTextDecoration.DEFAULT)) + .margin(new DocumentInsets(gap(552 - 513, BODY_SIZE), 0, 0, 0))); + } + }); + } + + /** A party and the mark the preset gives it. */ + private record Party(String token, InvoiceRecipient recipient) { + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsSettlement.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsSettlement.java new file mode 100644 index 000000000..b3ea7847c --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsSettlement.java @@ -0,0 +1,273 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.dsl.PageFlowBuilder; +import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.node.RowVerticalAlign; +import com.demcha.compose.document.node.TextAlign; +import com.demcha.compose.document.style.DocumentBorders; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentRowColumn; +import com.demcha.compose.document.style.DocumentStroke; +import com.demcha.compose.document.style.DocumentTextDecoration; +import com.demcha.compose.document.templates.data.invoice.InvoicePaymentBlock; +import com.demcha.compose.document.templates.data.invoice.InvoiceTotalsBlock; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.ACCENT; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.BODY; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_DISC_D; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_DISC_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_DISC_SURFACE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_FIELD_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_GLYPH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_HEAD_BOTTOM_PX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_HEAD_GAP; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_HEAD_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_LABEL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_LABEL_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_PAD; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_RADIUS; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_SURFACE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_TEXT_INDENT; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_VALUE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.CARD_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DIVIDER; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DUE_PAD; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DUE_RADIUS; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DUE_SUB_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.INK; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.LINE_BOX; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.RULE_MED; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.RULE_THIN; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.SETTLEMENT_GUTTER; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.SETTLEMENT_RIGHT_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.SURFACE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TEXT_TOP_BEARING; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_LABEL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_PAD_R; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_PITCH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_RULE_W; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_TEXT_INSET; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTALS_VALUE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTAL_DUE_LABEL_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTAL_DUE_SUB_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.TOTAL_DUE_VALUE_SIZE; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.capOffset; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.gap; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.px; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.style; + +/** + * The settlement row: the payment card against the totals and the panel that + * closes them. + * + *

The split is not the even one the two rows above it use — the card is + * narrower than the totals cell, and the divider sits inside the + * gutter rather than on either cell's edge. That asymmetry is in the design.

+ */ +final class PaymentsSettlement { + + private PaymentsSettlement() { + } + + /** + * Draws the row. + * + * @param page the page flow + * @param payment the bank details and the due notice + * @param totals the summed rows and the amount due + * @param currencyCode the ISO code the figures are stated in + */ + static void render(PageFlowBuilder page, InvoicePaymentBlock payment, + InvoiceTotalsBlock totals, String currencyCode) { + page.addRow("SettlementRow", row -> { + row.spacing(SETTLEMENT_GUTTER) + .verticalAlign(RowVerticalAlign.TOP) + .columns(DocumentRowColumn.fixed(CARD_W), DocumentRowColumn.weight(1)); + row.addSection("PaymentDetails", cell -> renderCard(cell, payment)); + row.addSection("Settlement", cell -> { + // The divider sits inside the gutter rather than on either cell's + // edge, so it is this cell's left border and the cell then pads + // itself back out to where the panel's edge actually is. + cell.spacing(0) + .borders(DocumentBorders.left(DocumentStroke.of(DIVIDER, RULE_THIN))) + .padding(new DocumentInsets(0, 0, 0, SETTLEMENT_RIGHT_INSET)); + renderTotals(cell, totals, currencyCode); + renderDuePanel(cell, payment, totals, currencyCode); + }); + }); + } + + /** + * A tinted rounded card with no border — the fill alone separates it from + * the page. Built from a fill, a radius and a padding rather than a panel + * helper, which takes one padding value where this card's insets are + * asymmetric. + */ + private static void renderCard(SectionBuilder cell, InvoicePaymentBlock payment) { + cell.spacing(0) + .fillColor(CARD_SURFACE) + .cornerRadius(CARD_RADIUS) + .padding(CARD_PAD) + .keepTogether(); + + PaymentsWidgets.layeredRow(cell, "CardHead", row -> { + row.spacing(CARD_HEAD_GAP) + .verticalAlign(RowVerticalAlign.TOP) + // The disc's own inset lives inside this column, so the column + // has to be wide enough for both — otherwise the heading + // starts on the disc's left edge plus the gap rather than on + // its right edge plus the gap. + .columns(DocumentRowColumn.fixed(CARD_DISC_INSET + CARD_DISC_D), + DocumentRowColumn.weight(1)); + row.addSection("CardDisc", disc -> disc + .spacing(0) + .padding(new DocumentInsets(0, 0, 0, CARD_DISC_INSET)) + .add(PaymentsWidgets.disc(PaymentsIcons.BANK, CARD_DISC_SURFACE, + CARD_DISC_D, CARD_GLYPH))); + row.addParagraph(p -> p + .name("CardLabel") + .text(payment.heading()) + .textStyle(style(CARD_HEAD_SIZE, ACCENT, DocumentTextDecoration.BOLD)) + .margin(new DocumentInsets( + capOffset(1078 - 1065, CARD_HEAD_SIZE), 0, 0, 0))); + }); + + // Two stacks, as in the metadata grid: the rows line up on a shared + // pitch rather than on a two-column row each. + PaymentsWidgets.layeredRow(cell, "CardFields", row -> { + row.spacing(0) + .verticalAlign(RowVerticalAlign.TOP) + // Measured from the head ROW's bottom edge, which the disc + // sets — not from the heading's own line box, which is + // shorter than the disc and therefore not what the fields + // follow. + .margin(new DocumentInsets(px(1110 - CARD_HEAD_BOTTOM_PX) + - TEXT_TOP_BEARING * CARD_LABEL_SIZE, 0, 0, CARD_TEXT_INDENT)) + .columns(DocumentRowColumn.fixed(CARD_LABEL_W), DocumentRowColumn.weight(1)); + row.addSection("CardFieldLabels", labels -> { + labels.spacing(gap(CARD_FIELD_PITCH, CARD_LABEL_SIZE)); + int index = 0; + for (InvoicePaymentBlock.Field field : payment.fields()) { + String name = "CardFieldLabel" + (++index); + labels.addParagraph(p -> p + .name(name) + .text(field.label()) + .textStyle(style(CARD_LABEL_SIZE, INK, DocumentTextDecoration.BOLD))); + } + }); + row.addSection("CardFieldValues", values -> { + values.spacing(gap(CARD_FIELD_PITCH, CARD_VALUE_SIZE)); + int index = 0; + for (InvoicePaymentBlock.Field field : payment.fields()) { + String name = "CardFieldValue" + (++index); + values.addParagraph(p -> p + .name(name) + .text(field.value()) + .textStyle(style(CARD_VALUE_SIZE, BODY, + DocumentTextDecoration.DEFAULT))); + } + }); + }); + } + + private static void renderTotals(SectionBuilder cell, InvoiceTotalsBlock totals, + String currencyCode) { + cell.addSection("Totals", block -> { + block.spacing(0) + .padding(new DocumentInsets(0, TOTALS_PAD_R, 0, TOTALS_TEXT_INSET)) + .margin(new DocumentInsets( + capOffset(1082 - 1060, TOTALS_LABEL_SIZE), 0, 0, 0)) + .keepTogether(); + PaymentsWidgets.layeredRow(block, "TotalsGrid", row -> { + row.spacing(0).verticalAlign(RowVerticalAlign.TOP).evenWeights(); + row.addSection("TotalsLabels", labels -> { + labels.spacing(gap(TOTALS_PITCH, TOTALS_LABEL_SIZE)); + int index = 0; + for (InvoiceTotalsBlock.Row entry : totals.rows()) { + String name = "TotalsLabel" + (++index); + labels.addParagraph(p -> p + .name(name) + .text(entry.label()) + .textStyle(style(TOTALS_LABEL_SIZE, INK, + DocumentTextDecoration.BOLD))); + } + }); + row.addSection("TotalsValues", values -> { + values.spacing(gap(TOTALS_PITCH, TOTALS_VALUE_SIZE)); + int index = 0; + for (InvoiceTotalsBlock.Row entry : totals.rows()) { + String name = "TotalsValue" + (++index); + values.addParagraph(p -> p + .name(name) + .text(PaymentsText.amount(currencyCode, entry.amount())) + .textStyle(style(TOTALS_VALUE_SIZE, BODY, + DocumentTextDecoration.DEFAULT)) + .align(TextAlign.RIGHT)); + } + }); + }); + }); + + cell.addLine(line -> line + .name("TotalsRule") + .horizontal(TOTALS_RULE_W) + .thickness(RULE_MED) + .color(DIVIDER) + // Measured cap-to-rule, less what the last label's box hangs + // below its own cap: the line box minus the top bearing, not the + // whole line box. + .margin(new DocumentInsets( + px(1154 - 1120) - (LINE_BOX - TEXT_TOP_BEARING) * TOTALS_LABEL_SIZE, + 0, + px(1173 - 1156), + 0))); + } + + /** + * Navy fill owning white type. CENTER, not TOP: the amount is centred + * against the label block rather than aligned to its first line. + * + *

The line under the label is the payment block's due notice — the sheet + * says when the money is wanted twice, once here beside the amount and once + * in the footer, and both come from the same field.

+ */ + private static void renderDuePanel(SectionBuilder cell, InvoicePaymentBlock payment, + InvoiceTotalsBlock totals, String currencyCode) { + cell.addSection("TotalDuePanel", panel -> { + panel.spacing(0) + .fillColor(INK) + .cornerRadius(DUE_RADIUS) + .padding(DUE_PAD) + .keepTogether(); + PaymentsWidgets.layeredRow(panel, "TotalDueRow", row -> { + row.spacing(0).verticalAlign(RowVerticalAlign.CENTER).evenWeights(); + row.addSection("TotalDueText", text -> { + text.spacing(0); + text.addParagraph(p -> p + .name("TotalDueLabel") + .text(totals.totalLabel()) + .textStyle(style(TOTAL_DUE_LABEL_SIZE, SURFACE, + DocumentTextDecoration.BOLD))); + if (!payment.dueNotice().isBlank()) { + text.addParagraph(p -> p + .name("TotalDueSubLabel") + .text(payment.dueNotice()) + .textStyle(style(TOTAL_DUE_SUB_SIZE, SURFACE, + DocumentTextDecoration.DEFAULT)) + .margin(new DocumentInsets( + px(DUE_SUB_PITCH) - LINE_BOX * TOTAL_DUE_LABEL_SIZE + + TEXT_TOP_BEARING + * (TOTAL_DUE_LABEL_SIZE - TOTAL_DUE_SUB_SIZE), + 0, 0, 0))); + } + }); + row.addParagraph(p -> p + .name("TotalDueValue") + .text(PaymentsText.amount(currencyCode, totals.totalAmount())) + .textStyle(style(TOTAL_DUE_VALUE_SIZE, SURFACE, + DocumentTextDecoration.BOLD)) + .align(TextAlign.RIGHT)); + }); + }); + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsStyles.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsStyles.java new file mode 100644 index 000000000..8c76cc924 --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsStyles.java @@ -0,0 +1,456 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.api.DocumentPageSize; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentStroke; +import com.demcha.compose.document.style.DocumentTextDecoration; +import com.demcha.compose.document.style.DocumentTextStyle; +import com.demcha.compose.document.table.DocumentTableStyle; +import com.demcha.compose.document.table.DocumentTableTextAnchor; +import com.demcha.compose.font.FontName; + +/** + * Design tokens for {@link PaymentsInvoice} — the palette, the type scale and + * the geometry every part of the sheet measures against. + * + *

One scale, and one content box

+ * + *

The design was drawn at 1055 px across an A4 page, so {@link #PX} converts + * every length below from that raster to points. The content box is the + * table's box, not the text's: body copy sits a further + * {@link #TEXT_INSET} inside it, while the table, the payment card and the + * total-due panel sit on it exactly, which is what makes it the page's real + * edge.

+ * + *

Ink measurements against box measurements

+ * + *

Every vertical distance read off the design is between two pieces of ink; + * every one the engine accepts is between two boxes. Text sits about + * {@link #TEXT_TOP_BEARING} of its size below its own box top — the half-leading + * of a 1.2× line box plus the run from the ascender down to the cap — so a gap + * read ink-to-ink loses that before it can be a margin. {@link #gap} and + * {@link #capOffset} are the two places that conversion happens.

+ * + *

Sizes come from widths, not heights

+ * + *

Each size below is a measured ink width divided by the face's own + * advance for the same string at unit cap. The two disagree for all-caps runs, + * where the body face sets about 6% wider than the design's at the same cap + * height, and width is the one to match: it keeps every glyph after the first in + * place, where matching the height would leave the run's right edge short by 6% + * of its length.

+ */ +final class PaymentsStyles { + + private PaymentsStyles() { + } + + static final DocumentPageSize PAGE = DocumentPageSize.A4; + static final double PAGE_WIDTH = PAGE.width(); + + /** The design's raster is 1055 px wide; every length below came off it. */ + static final double PX = PAGE_WIDTH / 1055.0; + + static final double MARGIN_L = px(51); + static final double MARGIN_R = px(52); + static final double MARGIN_T = px(28); + + /** + * The band the page number sits in, measured up from the paper's edge, and + * page one's bottom margin, which is the same thing. + * + *

The design is a one-page sheet and has no page number, but this preset + * flows, and a financial record that paginates has to make a missing page + * detectable. The band is reserved rather than merely drawn into: on a + * paginated invoice page one is all table, and without the margin the last + * row runs down to where the number is.

+ */ + static final double PAGE_NUMBER_BAND = px(32); + static final double MARGIN_B_FIRST = PAGE_NUMBER_BAND; + + /** + * A continuation page reserves more. Its last table row would otherwise end + * against the paper rather than against a margin, which page one never shows + * because its content stops well above the fold. + */ + static final double MARGIN_B_LATER = px(58); + + static final DocumentInsets PAGE_MARGIN = + new DocumentInsets(MARGIN_T, MARGIN_R, MARGIN_B_FIRST, MARGIN_L); + static final DocumentInsets CONTINUATION_MARGIN = + new DocumentInsets(MARGIN_T, MARGIN_R, MARGIN_B_LATER, MARGIN_L); + + /** Every width in this preset is a fraction of this: 952 design px. */ + static final double CONTENT_W = PAGE_WIDTH - MARGIN_L - MARGIN_R; + + /** How far body copy sits inside the content box the table defines. */ + static final double TEXT_INSET = px(11); + + static final DocumentColor ACCENT = DocumentColor.rgb(99, 91, 255); + static final DocumentColor INK = DocumentColor.rgb(14, 24, 72); + static final DocumentColor BODY = DocumentColor.rgb(46, 54, 92); + static final DocumentColor MUTED = DocumentColor.rgb(70, 76, 110); + static final DocumentColor SURFACE = DocumentColor.WHITE; + + /** + * Three lavender surfaces, not one. Sampled as rings inside each disc, clear + * of the glyph: the party and line item discs agree, the notes disc is two + * steps paler and the payment card's is two steps deeper. They look like one + * colour and measure as three. + */ + static final DocumentColor ACCENT_SURFACE = DocumentColor.rgb(224, 218, 253); + static final DocumentColor NOTES_SURFACE = DocumentColor.rgb(226, 222, 253); + static final DocumentColor CARD_DISC_SURFACE = DocumentColor.rgb(216, 208, 252); + static final DocumentColor CARD_SURFACE = DocumentColor.rgb(248, 247, 254); + static final DocumentColor TABLE_HEAD_FILL = DocumentColor.rgb(240, 238, 254); + static final DocumentColor BAND_LAVENDER = DocumentColor.rgb(205, 194, 248); + static final DocumentColor HAIRLINE = DocumentColor.rgb(227, 227, 238); + static final DocumentColor RULE_SOFT = DocumentColor.rgb(213, 208, 239); + static final DocumentColor RULE_STRONG = DocumentColor.rgb(159, 145, 222); + static final DocumentColor DIVIDER = DocumentColor.rgb(199, 191, 236); + + static final FontName FACE = FontName.LATO; + + /** + * The face's cap heights in ems. Regular and bold differ, and the difference + * matters: every size below is a measured cap divided by the ratio for the + * weight it is set in. + */ + private static final double CAP_RATIO_REGULAR = 0.7165; + private static final double CAP_RATIO_BOLD = 0.723; + + /** How far below its own box top a line of text sits. */ + static final double TEXT_TOP_BEARING = 0.235; + + /** + * {@code lineSpacing} is points added between lines over a line box + * of 1.2× the type size, so a measured pitch converts as + * {@code pitch - 1.2 * size}, never as a ratio. Section spacing works the + * same way: it is the gap between sibling boxes, so a measured top-to-top + * pitch has the first box's height taken off it. + */ + static final double LINE_BOX = 1.2; + + static final double TITLE_SIZE = sizeB(46.53); + static final double ISSUER_NAME_SIZE = sizeB(14.65); + static final double PARTY_NAME_SIZE = sizeB(13.11); + static final double PARTY_LABEL_SIZE = sizeB(10.91); + static final double META_LABEL_SIZE = sizeB(11.59); + static final double META_VALUE_SIZE = sizeR(10.35); + static final double BODY_SIZE = sizeR(11.08); + static final double TABLE_HEAD_SIZE = sizeB(10.22); + + /** The currency qualifier after the amount label is a smaller run of it. */ + static final double TABLE_HEAD_SMALL_SIZE = sizeB(8.0); + static final double ITEM_TITLE_SIZE = sizeB(12.18); + static final double ITEM_SUB_SIZE = sizeR(10.17); + static final double CELL_SIZE = sizeR(11.19); + static final double CELL_AMOUNT_SIZE = sizeB(12.25); + static final double CARD_HEAD_SIZE = sizeB(11.30); + static final double CARD_LABEL_SIZE = sizeB(9.44); + static final double CARD_VALUE_SIZE = sizeR(9.33); + static final double TOTALS_LABEL_SIZE = sizeB(12.07); + static final double TOTALS_VALUE_SIZE = sizeR(11.72); + static final double TOTAL_DUE_LABEL_SIZE = sizeB(13.04); + static final double TOTAL_DUE_SUB_SIZE = sizeR(10.79); + static final double TOTAL_DUE_VALUE_SIZE = sizeB(22.18); + static final double NOTES_LABEL_SIZE = sizeB(10.29); + static final double NOTES_BODY_SIZE = sizeR(10.07); + static final double FOOTER_DUE_TITLE_SIZE = sizeB(10.16); + static final double FOOTER_SUPPORT_TITLE_SIZE = sizeB(11.12); + static final double FOOTER_SUB_SIZE = sizeR(10.05); + static final double PAGE_NUMBER_SIZE = sizeR(7.5); + + /* + * The diagonal band: two slanted quadrilaterals in the gutter between the + * lockup and the title, the lavender running from the paper's top edge and + * the navy drawn over it from a third of the way down. Corners are given in + * PAGE design pixels — the coordinates that were actually measured — and + * normalised in one place by nx/ny, because a path's own coordinates run + * 0..1 inside its box with the origin at the BOTTOM-LEFT, which is the + * opposite of the direction every measurement here was taken in. + */ + static final double BAND_LEFT_PX = 385.4; + static final double BAND_RIGHT_PX = 556.0; + static final double BAND_BOTTOM_PX = 360.0; + static final double BAND_W = px(BAND_RIGHT_PX - BAND_LEFT_PX); + static final double BAND_H = px(BAND_BOTTOM_PX); + + /** Top-left, top-right, bottom-right, bottom-left, in page design pixels. */ + static final double[][] BAND_LAVENDER_QUAD = { + {495.0, 0.0}, {539.6, 0.0}, {422.4, 360.0}, {385.4, 360.0} + }; + static final double[][] BAND_NAVY_QUAD = { + {507.7, 98.0}, {554.7, 98.0}, {469.3, 360.0}, {422.3, 360.0} + }; + + /** + * How tall the masthead's layer stack comes out. The band is the tallest + * layer in it, so the stack's own height is the band's — and the header rule + * that follows the stack has to be pulled back up by the difference between + * the band's bottom and where the stack ends. The band is offset up by + * {@link #MARGIN_T} to reach the paper, and the stack is sized to its layers + * without accounting for that offset, so the stack ends that much below the + * band's visible bottom. + */ + static final double HEADER_STACK_BOTTOM_PX = BAND_BOTTOM_PX + 28.0; + + /** + * Where the metadata column starts, as an offset into the content box. The + * title shares it: the title is a left-anchored member of the metadata + * column, not a right-anchored member of the page, and its measured left + * edge is the metadata labels' to the pixel. + */ + static final double META_COL_X = px(639 - 51); + + /** + * The lockup's box, measured off the design's own ink: 136 design px wide + * and 55.3 tall, starting at {@link #BRAND_LOCKUP_INSET} into the content + * box. A caller's logo is sized by the height, so a wider or narrower mark + * keeps the design's optical weight and stays on the same top edge. + */ + static final double BRAND_LOCKUP_W = px(136); + static final double BRAND_LOCKUP_H = px(55.3); + static final double BRAND_LOCKUP_INSET = px(63 - 51); + + /** + * The size a wordmark is set at when a document brings a name rather than a + * logo. Not the lockup's own height: a name is usually longer than a + * drawn mark and set at that height would run out of the column, so it is + * sized to read as a lockup beside the title rather than to fill the box. + */ + static final double WORDMARK_SIZE = sizeB(28); + + /** + * The lockup sets the row's top edge, so the title's own line box needs + * pushing down to its measured cap. The 1.4 px correction is measured, not + * derived: at 46 design px of cap the top bearing runs slightly deeper than + * the fraction that holds at body sizes. + */ + static final double TITLE_DROP = px(65 - 46 - 1.4) - TEXT_TOP_BEARING * TITLE_SIZE; + + static final double ACCENT_BAR_W = px(2); + static final double ACCENT_BAR_H = px(310); + + /** The bar is anchored to the PAGE, 22 design px left of the content box. */ + static final double ACCENT_BAR_OFFSET = px(-22); + + static final double META_LABEL_W = px(781.5 - 639); + static final double META_VALUE_INSET = px(805 - 781.5); + static final double META_PITCH = 30.17; + + static final double HEADER_RULE_W = px(1018 - 30); + + /** How far the rule reaches past the content box: 21 design px left, 15 right. */ + static final double HEADER_RULE_OVERHANG_L = px(51 - 30); + static final double HEADER_RULE_OVERHANG_R = px(1018 - 1003); + static final double RULE_THIN = px(1.4); + static final double RULE_MED = px(2.0); + + static final double DISC_D = px(40); + + /** + * Box, not ink. An icon's size is the box the artwork is fitted into, + * and every glyph here carries about two units of padding on each side of + * its 24-unit viewBox — so the ink comes back at roughly this fraction of + * what is asked for. Each glyph size below is therefore the design's + * measured ink divided by that ratio, which is why they read larger than the + * marks they produce. + */ + static final double GLYPH_INK_RATIO = 0.75; + static final double DISC_GLYPH = glyph(21); + static final double PARTY_DISC_INSET = px(60 - 51); + static final double PARTY_DISC_GAP = px(118 - 100); + static final double PARTY_TEXT_INDENT = DISC_D + PARTY_DISC_GAP; + + /** The second cell's own left padding, past the divider that is its left border. */ + static final double PARTY_CELL_INSET = px(567 - 527); + static final double PARTY_ADDRESS_PITCH = 20.7; + + /** + * Column shares of the content width. Derived from each column's measured + * anchor rather than from boundaries the design never draws: the + * description text's left edge, the quantity digits' centre, the unit + * price's right edge, the tax centre and the amount's right edge. + */ + static final double[] COLUMN_SHARES = { + 379.0 / 952.0, 127.0 / 952.0, 143.0 / 952.0, 139.0 / 952.0, 164.0 / 952.0 + }; + + static final double HEAD_PAD_T = px(11.7); + static final double HEAD_PAD_B = px(12.3); + static final double CELL_PAD_V = px(8.5); + + /** The description cell's own inset; the disc sits on it and the text past it. */ + static final double ITEM_CELL_INSET = px(62 - 51); + static final double ITEM_DISC_GAP = px(118 - 102); + + /** + * What a line's description wraps at. Not a free choice: the design breaks + * one description before its parenthetical and keeps the next whole, which + * puts the width between 248 and 256 design px. Everything about the table's + * row heights follows from it. + */ + static final double ITEM_TEXT_W = px(250); + static final double ITEM_SUB_PITCH = 18.0; + static final double CELL_PAD_R = px(22); + static final double AMOUNT_PAD_R = px(23); + static final double DESC_PAD_L = px(118 - 51); + + static final DocumentTableStyle HEADER_CELL_STYLE = DocumentTableStyle.builder() + .fillColor(TABLE_HEAD_FILL) + .stroke(DocumentStroke.of(HAIRLINE, RULE_THIN)) + .padding(new DocumentInsets(HEAD_PAD_T, 0, HEAD_PAD_B, 0)) + .textAnchor(DocumentTableTextAnchor.CENTER_LEFT) + .build(); + + /** + * Every rule in the table comes from this one stroke. A cell strokes all + * four of its own edges and a one-column table has no interior vertical edge + * — so the same stroke that draws the separator between two rows draws the + * table's left and right sides, and nothing else. That is exactly the + * topology the design shows. + */ + static final DocumentTableStyle ITEM_CELL_STYLE = DocumentTableStyle.builder() + .stroke(DocumentStroke.of(HAIRLINE, RULE_THIN)) + .padding(new DocumentInsets(CELL_PAD_V, 0, CELL_PAD_V, 0)) + .textAnchor(DocumentTableTextAnchor.CENTER_LEFT) + .build(); + + /** + * The settlement split is NOT the even split the two rows above it use: the + * card is 440 design px, the totals cell 455, and the divider sits inside + * the gutter rather than on either cell's edge. That asymmetry is in the + * design, not in the measurement. + */ + static final double CARD_W = px(440); + static final double SETTLEMENT_GUTTER = px(527.5 - 491); + static final double SETTLEMENT_RIGHT_INSET = px(547 - 527.5); + + static final double CARD_RADIUS = px(10); + + /** + * The card's own disc is smaller than the party and line item discs — 38 + * design px against 40 — and it sits 5 px below the card's top edge, not 12. + * Both were measured off the card rather than assumed from the other three, + * and both matter: the disc sets the head row's height, and that height is + * what the field block's margin is measured from. + */ + static final double CARD_DISC_D = px(38); + static final double CARD_GLYPH = glyph(21); + static final DocumentInsets CARD_PAD = + new DocumentInsets(px(1065 - 1060), px(20), px(1252 - 1238.5), 0); + static final double CARD_DISC_INSET = px(63.5 - 51); + static final double CARD_HEAD_GAP = px(118 - 101); + static final double CARD_LABEL_W = px(256 - 116); + static final double CARD_TEXT_INDENT = px(116 - 51); + static final double CARD_FIELD_PITCH = 19.3; + + /** The disc's bottom edge, measured down from the card's content top. */ + static final double CARD_HEAD_BOTTOM_PX = 1065 + 38; + + static final double TOTALS_TEXT_INSET = px(566 - 547); + static final double TOTALS_PAD_R = px(1003 - 987); + static final double TOTALS_PITCH = 38.0; + static final double TOTALS_RULE_W = px(1002 - 547); + + static final double DUE_RADIUS = px(10); + + /** + * The top inset is the distance to the label's box, not to its cap: + * the measured cap gap less what the text hangs below its own box top. + * Taking the cap gap as a padding makes the panel 4 px too tall and pushes + * its bottom past the card's, which the design has ending on the same line. + */ + static final DocumentInsets DUE_PAD = new DocumentInsets( + px(1194 - 1173) - TEXT_TOP_BEARING * TOTAL_DUE_LABEL_SIZE, + px(1002 - 984), + px(1251 - 1235), + px(566 - 547)); + static final double DUE_SUB_PITCH = 28.0; + + static final double NOTES_DISC_D = px(39); + static final double NOTES_DISC_INSET = px(53 - 51); + static final double NOTES_TEXT_INDENT = px(106 - 53); + static final double NOTES_GLYPH = glyph(22); + static final double NOTES_PITCH = 22.0; + + static final double FOOTER_RULE_W = px(1005 - 50); + + /** + * The rule's own gaps. The 1.2 px correction is measured and is taken off + * the gap below as well as added to the gap above: the footer's text already + * sits on the design's line, so the rule has to move without taking the + * footer with it. + */ + static final double FOOTER_RULE_NUDGE = px(1.2); + static final double FOOTER_RULE_GAP_ABOVE = px(1373 - 1343) + FOOTER_RULE_NUDGE; + static final double FOOTER_RULE_GAP_BELOW = px(1397 - 1374) - FOOTER_RULE_NUDGE; + + /** One design px past the content box on the left, two on the right. Measured. */ + static final double FOOTER_RULE_OVERHANG_L = px(51 - 50); + static final double FOOTER_RULE_OVERHANG_R = px(1005 - 1003); + static final double FOOTER_SPLIT_X = px(541 - 51); + static final double FOOTER_DUE_ICON_COL = px(112 - 55); + static final double FOOTER_DUE_ICON_INSET = px(55 - 51); + static final double FOOTER_DUE_ICON = glyph(37); + static final double FOOTER_SUPPORT_CELL_INSET = px(594 - 541); + static final double FOOTER_SUPPORT_ICON_COL = px(659 - 594); + static final double FOOTER_SUPPORT_ICON = glyph(39); + + static double px(double designPixels) { + return designPixels * PX; + } + + /** + * An icon box sized so its ink comes out at {@code inkPx} design pixels — + * see {@link #GLYPH_INK_RATIO}. Every glyph goes through here, so the one + * measured ratio lives in one place. + */ + static double glyph(double inkPx) { + return px(inkPx) / GLYPH_INK_RATIO; + } + + /** Half the padding {@link #glyph} adds — what a left-anchored glyph gives back. */ + static double glyphPad(double inkPx) { + return (glyph(inkPx) - px(inkPx)) / 2.0; + } + + /** A regular-weight size named by the cap height it reproduces, in design px. */ + static double sizeR(double capPx) { + return px(capPx) / CAP_RATIO_REGULAR; + } + + /** The same for bold, whose cap ratio differs. */ + static double sizeB(double capPx) { + return px(capPx) / CAP_RATIO_BOLD; + } + + /** + * Where to start a text box so its caps land {@code capPx} below the top of + * the block it shares a row with — a label beside a glyph, whose design + * position is its own cap top rather than the glyph's centre. + */ + static double capOffset(double capPx, double size) { + return Math.max(0, px(capPx) - TEXT_TOP_BEARING * size); + } + + /** + * A measured top-to-top pitch turned into the gap the engine wants: the + * first box's own height comes off it, because spacing is between boxes. + */ + static double gap(double pitchPx, double sizeOfFirst) { + return Math.max(0, px(pitchPx) - LINE_BOX * sizeOfFirst); + } + + static DocumentTextStyle style(double size, DocumentColor color, + DocumentTextDecoration decoration) { + return DocumentTextStyle.builder() + .fontName(FACE) + .size(size) + .color(color) + .decoration(decoration) + .build(); + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsText.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsText.java new file mode 100644 index 000000000..827ce83cf --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsText.java @@ -0,0 +1,62 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import java.math.BigDecimal; +import java.text.NumberFormat; +import java.util.Currency; +import java.util.Locale; + +/** + * How the Payments sheet writes its figures. + * + *

The locale is stated, never inherited

+ * + *

Both the grouping of a number and the symbol for a currency code are + * locale-dependent — {@code USD} is {@code $} in English and {@code US$} in the + * root locale, {@code JPY} is {@code ¥} or {@code JP¥} — so a preset that let + * the JVM's default locale decide would render a different sheet on a different + * machine, and its baselines would move with the machine rather than with the + * design. Both helpers below pin {@link Locale#ENGLISH}.

+ */ +final class PaymentsText { + + private PaymentsText() { + } + + /** An amount, grouped and always to two places. */ + static String money(BigDecimal value) { + NumberFormat format = NumberFormat.getNumberInstance(Locale.ENGLISH); + format.setGroupingUsed(true); + format.setMinimumFractionDigits(2); + format.setMaximumFractionDigits(2); + return format.format(value); + } + + /** A quantity, written without trailing zeros a whole number does not need. */ + static String quantity(BigDecimal value) { + BigDecimal stripped = value.stripTrailingZeros(); + return stripped.scale() <= 0 ? stripped.toBigInteger().toString() : stripped.toPlainString(); + } + + /** + * The symbol for an ISO currency code, or the code itself when there is no + * symbol for it and the empty string when a document states no currency. + * + * @param currencyCode the ISO code the figures are stated in + * @return what to print before an amount + */ + static String symbol(String currencyCode) { + if (currencyCode == null || currencyCode.isBlank()) { + return ""; + } + try { + return Currency.getInstance(currencyCode.trim()).getSymbol(Locale.ENGLISH); + } catch (IllegalArgumentException notACurrency) { + return currencyCode.trim(); + } + } + + /** An amount behind its currency's symbol. */ + static String amount(String currencyCode, BigDecimal value) { + return symbol(currencyCode) + money(value); + } +} diff --git a/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsWidgets.java b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsWidgets.java new file mode 100644 index 000000000..0fffc324d --- /dev/null +++ b/templates/src/main/java/com/demcha/compose/document/templates/invoice/presets/PaymentsWidgets.java @@ -0,0 +1,129 @@ +package com.demcha.compose.document.templates.invoice.presets; + +import com.demcha.compose.document.dsl.ParagraphBuilder; +import com.demcha.compose.document.dsl.RowBuilder; +import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.dsl.ShapeContainerBuilder; +import com.demcha.compose.document.node.DocumentLinkOptions; +import com.demcha.compose.document.node.DocumentNode; +import com.demcha.compose.document.node.HorizontalAlign; +import com.demcha.compose.document.node.LayerAlign; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentTextDecoration; + +import java.util.List; +import java.util.function.Consumer; + +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DISC_D; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.DISC_GLYPH; +import static com.demcha.compose.document.templates.invoice.presets.PaymentsStyles.style; + +/** + * The pieces more than one part of the Payments sheet draws: the wrapper every + * horizontal pair inside a cell goes through, the disc that owns its glyph, and + * the two text helpers. + */ +final class PaymentsWidgets { + + private PaymentsWidgets() { + } + + /** + * A row that survives inside a row cell. + * + *

A row nested directly in a row cell is refused by the layout compiler. + * Every horizontal pair that lives inside a cell in this preset goes through + * here, wrapped in a single layer of a stack.

+ * + * @param parent the section to add the row to + * @param name the node name, for review and rollback + * @param spec describes the row + */ + static void layeredRow(SectionBuilder parent, String name, Consumer spec) { + SectionBuilder holder = new SectionBuilder(); + holder.name(name + "Holder"); + holder.addRow(name, spec); + DocumentNode node = holder.build(); + parent.addLayerStack(stack -> stack + .name(name + "Layer") + .layer(node, LayerAlign.TOP_LEFT, 0)); + } + + /** + * A filled disc that owns its glyph: the glyph sits inside the fill, so it + * is a child of the shape rather than a coloured circle with an icon + * dropped near it. + * + * @param token the packaged mark + * @param fill the disc colour + * @return the disc node + */ + static DocumentNode disc(String token, DocumentColor fill) { + return disc(token, fill, DISC_D, DISC_GLYPH); + } + + /** + * The same, at a stated diameter — the payment card's and the notes' discs + * are each their own size, measured off the block they belong to. + * + * @param token the packaged mark + * @param fill the disc colour + * @param diameter the disc's diameter + * @param glyph the glyph's box inside it + * @return the disc node + */ + static DocumentNode disc(String token, DocumentColor fill, double diameter, double glyph) { + return new ShapeContainerBuilder() + .name("Disc" + token) + .circle(diameter) + .fillColor(fill) + .center(glyphNode(token, glyph, HorizontalAlign.CENTER)) + .build(); + } + + /** + * A glyph in a box of its own, so a shape can own it. A glyph that leads a + * text row is aligned left: its column's width is the distance to the text, + * not a box for the glyph to sit in the middle of. + * + * @param token the packaged mark + * @param size the glyph's box + * @param align where the glyph sits in it + * @return the glyph node + */ + static DocumentNode glyphNode(String token, double size, HorizontalAlign align) { + return new SectionBuilder() + .name("Glyph" + token) + .spacing(0) + .addSvgIcon(PaymentsIcons.icon(token), size, align) + .build(); + } + + /** + * A block of plain lines, one paragraph each. + * + * @param block the section to fill + * @param prefix the node-name prefix, numbered from one + * @param lines the lines + * @param size their type size + * @param color their colour + */ + static void textLines(SectionBuilder block, String prefix, List lines, + double size, DocumentColor color) { + int index = 0; + for (String line : lines) { + String name = prefix + (++index); + block.addParagraph(p -> p + .name(name) + .text(line) + .textStyle(style(size, color, DocumentTextDecoration.DEFAULT))); + } + } + + /** The paragraph, made reachable when there is somewhere for it to point. */ + static ParagraphBuilder linked(ParagraphBuilder paragraph, String href) { + return href == null || href.isBlank() + ? paragraph + : paragraph.link(new DocumentLinkOptions(href)); + } +} diff --git a/templates/src/main/resources/templates/invoice/payments/icons/bank.svg b/templates/src/main/resources/templates/invoice/payments/icons/bank.svg new file mode 100644 index 000000000..0058b58a9 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/bank.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/bill-to.svg b/templates/src/main/resources/templates/invoice/payments/icons/bill-to.svg new file mode 100644 index 000000000..0aaae9c3f --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/bill-to.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/calendar.svg b/templates/src/main/resources/templates/invoice/payments/icons/calendar.svg new file mode 100644 index 000000000..d1952bcc7 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/calendar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/card-settings.svg b/templates/src/main/resources/templates/invoice/payments/icons/card-settings.svg new file mode 100644 index 000000000..a10a3b2c0 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/card-settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/card.svg b/templates/src/main/resources/templates/invoice/payments/icons/card.svg new file mode 100644 index 000000000..8a9fe32ed --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/document.svg b/templates/src/main/resources/templates/invoice/payments/icons/document.svg new file mode 100644 index 000000000..5aec8edf5 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/document.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/globe.svg b/templates/src/main/resources/templates/invoice/payments/icons/globe.svg new file mode 100644 index 000000000..323edcf15 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/headset.svg b/templates/src/main/resources/templates/invoice/payments/icons/headset.svg new file mode 100644 index 000000000..3031d0940 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/headset.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/mobile.svg b/templates/src/main/resources/templates/invoice/payments/icons/mobile.svg new file mode 100644 index 000000000..4e5915f59 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/mobile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/shield.svg b/templates/src/main/resources/templates/invoice/payments/icons/shield.svg new file mode 100644 index 000000000..b08b7e7a9 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/ship-to.svg b/templates/src/main/resources/templates/invoice/payments/icons/ship-to.svg new file mode 100644 index 000000000..03efd2212 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/ship-to.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/src/main/resources/templates/invoice/payments/icons/support.svg b/templates/src/main/resources/templates/invoice/payments/icons/support.svg new file mode 100644 index 000000000..ef8b01748 --- /dev/null +++ b/templates/src/main/resources/templates/invoice/payments/icons/support.svg @@ -0,0 +1 @@ + \ No newline at end of file From 38cd5a6de8721a66b3f0b1a527609dcc6ecbd50f Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Tue, 1 Sep 2026 07:56:52 +0100 Subject: [PATCH 2/2] fix(examples): re-render the Payments preview from this branch's own build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The committed preview was rendered against jars in the local repository that did not match this branch, so the catalogue's drift test failed on CI while passing locally — and the eleven files that appeared to drift locally were the same staleness seen from the other side. Built from source, the local drift list narrows to exactly the file CI named. Re-rendered, both lists are empty. --- .../readme/examples/invoice-payments-v2.pdf | Bin 32645 -> 32646 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/readme/examples/invoice-payments-v2.pdf b/assets/readme/examples/invoice-payments-v2.pdf index 043843ec7f08bf45c73d02f6fc3a1247c51857e0..ef189d1d948f938ab5e0476f90c314d47062cad8 100644 GIT binary patch delta 2065 zcmbuA`#%$m0>*9O-R7Q!yv>%&T+24I$=z&=S2j$-GS)Gf8o9hvE}PQaSq z=SAt?4X{127|YVn?;>f1$Th&NRpFYZlKp_(e|X#8^8K{2ODS(gJ(?MMAwT-bHeH11 zwFy*IX9#VNKsW*c==OTU5Fh|20+_6dz9O|nAmn?I5e3=~G1WH}B~hRvI|@PMmk4by zpgc4aT}k|}@iG;vi?u^Tto=`&U?HrjN1|v69Eddqfkpr9qRS_<K`se2g3XKw zazap{|8__(|EYd0!q>nBkfas2NMCG)TdW)swug`XKK#NP7Hp zev6#&0&~uSr6cDOl;1xnPUs2qcmUo8QUJMY0`|DMmLodcmLxp|;I!gM=I}Y#giZC_ zxDMBGLzMl2=$@O{+TQ9{n5wINY;f_)uNoBC0 zlFbjEo3iZ~>^#Q4G_D<|JYng}c$EtKw(kA%2jxbHhDV6&a^GpfbEsSL9chDAYk)_m zjZ%OljhnUdrf8xUb)B@Peun4FUhue5ew_U7A?C;vAW%w+iY2 za8#=DZi^>)aIT$ZGBG&4{&Mk{cp?_g<=d+!D^8|y1$FnnX-@V#jVz$9wxm5Dd7?vJ z>kv;xz()s}2k4`faY9j%dZn>SNzY`J$*OZ>dGC2#&vD?foPaLaVk*%lQ;Vb4p?v!{ zoxQ>BD))u#h%$Bxp~Uoa-N3!Mxw%iH)ZtfS?)-$ORMTI15=HYzaPboFDHmVIcf2S? za5C486z)gqjCdNpnj-Tm|6i=lVx^scu#`~`ZdLj{hiabq8LR5slFY`eqcHRJiM_N{B}aFhAB zYnDYL=QlSuGZ*H69Epq`7KbKVe2A+8awboF;^J20uYL(kA<5L-2W3-KNGveV#!|{oNyl{)L%l*#ny4CAY&tw=Dlcegu#E+$YPY zJ2wQ3Swh;Gbb6l_u?~gJM?SCjExuI39dmy`rP(pg|I=`z-#*Gn`%wWXCoarqgYLz! zgiI<9y=|*MMPh126oa6AB}U(VbV2i}g3`QWU&hYGasmP68NliBj5e~}m;g$;IkKGR zHfzy>Jt{;P{d&MW5xy=18MmYc4;Ws5p^F^N+`RnhP|Q+!D{sbk16K5&v0dY&zJZKA zHQOZdsmKbEy?w@Zp1?`}SUSf!47Cp zA|AC5kHHcNXd4omh{ur7STY7hCjJaCII;~IjUv0_P-rw3YeRO&;80|YEsBUI5^Ztr zZu{(<5sv>4!t6hckpEp%pdTv&VohTwu@JU6h_z>QIO`;Wj`}G?*Lc=^*pp7R9v>)C zaw;Np=zjW&kaHysW7UNQYvpVDLOBRODesKvFuS2})m8vWkgEbL8VQXRR$c21lG^Xs z5uyqwVT7cSdR8wiORMjESkBIcz_9Ec&nLoiVTKPqq*l(4r?z?x%rS3Dc_|Lk$QNFv c-7G;bDWJ_9-nK+@QS=GdmHc}{Q4C+_Z>MLeHUIzs delta 2100 zcmbuAS5%V;0)+|1V1S_oG9pMws3XEp5)zOip+pD}nhtH1h(wAcRH?!b3l1SPF@REr zF1S*RKomhhktThlh$R}q1BfCW>8!hZ_HEzx?cQ_G`Odvh_m4x!jY9~Bs|>-ivnle~ z90^dO$3!LxDRpEt-eD#8AtVBlJ-JeCkBLnbf1Zw)AC5Y3Z2N&SnuyiiXv@?@7^1Z- zNmxl8T#|1|u$)5fw`pnnh_NWh|s7G3E<@9nF*_%?0KC0COsHP+7$#Ooq zqJL*0bKs<7WjUO;Vpg4oYB}=l9KltjSQ!Aa3z9<}8>6Tul7{gaUx|^bX>`A_$P4nGL&d+~A zsn7t_2@#{W5NB^;;pdq;K+KITzF_wjH;0K(zmV|WY(n@_5#T)i=5iD9X-uw{2{?E) z8?0q~z1s)Ut8ASDJ};ZUXYSRu2E~?jeSO_pfC9Z73KyDob;$WP&q4fD`qOJ3a1u?l zg({|8V5zqO@v-Sp+?MXzV#w@zzrB?JqXr+X~6|&9S-pv$F+6>5nmY(t})ROqV zL`)GH-7&admxv#o^znGY>EP{1jje~+y&EkG%VPCUsP);2bcFbd#4-JM45}o6ch9>1 zBDX^0n0`A3<@5wRpY(E2p0t#t>|OA|*F)QO+n-xI7Kl^G7%}aLa^2v)^d}TDw!6hD z`#^>UugO2i%Cxu~jKS}}I4baQe87fBsd?mUbgzIUac%wn?l|7f1x*K`hpVf$ogMdr zmV76sOIpo#b?(IVXz-Q9xr?vf#cbAnFSOxGT<0}aM7*gLdCAvLUkY5T3~G_@u{!wT zU36g5T2tWuvF&dkM&@|shhOS1;dI zrgZ4I)U(aMQ++nLkbBE{%}Saq_HG%ZUJP+dcQ37Y?DtrvJr69>M^w;e;3gA+Md9bns>+^~ zxDL5rRxCDW^|(5Qlh7e*TC6vh`%ntvD)uEiY0}mob~$-+AtMY_etnBqPtXU~u;Jyz z{%xUK-(RnvHNNJsHomlcZj4nud30`{RqYt6cbFCB5x53lWIAm77FRVJ&digQA}Rgi z+E!yZI8fGh;@K-)g=!ews9nyM?kHr-J?;iO3@!{i$tZ}z$q+)YtYI}qe_~-aG_^2b z$lfq`OkRi}`vgTmf089gTfee-A0Ge0o;!Ob&~2lja7A2|QFT}E*Y{r66CWv1jg>`h zOey-+%7~s{^Jf*E!XvHvtxe2w)D;}|lCf|l@KxSg^}h7p`{f*?;?R@^puMWLQbV(q zx0Db))Zk^z^sVs!Ay@KxkHEOOHM1Y+hc3nz&TVb2-rjPO11*QP_R3mnN`C8{Yh1{C zkni-Rg~2$Szj6Dz(@<}m{#Esg&4}N73$LCt%((qVRzqJ^spqK?*wCdl2FhgAkZE$ z{69`cABP0k_amhRu^9GBoGfTTFd$-a7%ME6geU0Zi56B^j0FGyID(ZqmH^;^pCJ*8 zCz=B|98u5E0G<2+e;pF8ueY+?;7wV7e~;F*KyUK1|n! z;X{i;dICQUyCz;2lpA^?(dh`c{3{xt=04P(6zKw?yOk@XB``_Ia*YME%Gm?Hs;fdq zWe>c6tXnT?**@1!(tSO=?FRnzJjzTmP8{eGy_|f9$~rddMopEQoT8>FZ5r^IvZyX= v?e_jxw|5<~RnA_Dp7BU+l=E`mW}iRCXehAX&*Poh5!w)nML4rBfLi|qX@kP>