@aglyn/plugins-commerce 1.0.0-beta.230 → 1.0.0-beta.232
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -13
- package/src/index.d.ts +0 -1
- package/src/index.js +0 -1
- package/src/index.js.map +1 -1
- package/src/lib/barcode/barcode-decode.d.ts +71 -0
- package/src/lib/barcode/barcode-decode.js +498 -0
- package/src/lib/barcode/barcode-decode.js.map +1 -0
- package/src/lib/barcode/barcode-encode.d.ts +44 -0
- package/src/lib/barcode/barcode-encode.js +138 -0
- package/src/lib/barcode/barcode-encode.js.map +1 -0
- package/src/lib/barcode/barcode-scanner.component.d.ts +23 -0
- package/src/lib/barcode/barcode-scanner.component.js +260 -0
- package/src/lib/barcode/barcode-scanner.component.js.map +1 -0
- package/src/lib/barcode/scan-button.component.d.ts +10 -0
- package/src/lib/barcode/scan-button.component.js +62 -0
- package/src/lib/barcode/scan-button.component.js.map +1 -0
- package/src/lib/barcode/scanner-wedge.d.ts +35 -0
- package/src/lib/barcode/scanner-wedge.js +108 -0
- package/src/lib/barcode/scanner-wedge.js.map +1 -0
- package/src/lib/components/account.js +10 -1
- package/src/lib/components/account.js.map +1 -1
- package/src/lib/components/cart-extras.d.ts +45 -0
- package/src/lib/components/cart-extras.js +127 -0
- package/src/lib/components/cart-extras.js.map +1 -0
- package/src/lib/components/cart.js +82 -15
- package/src/lib/components/cart.js.map +1 -1
- package/src/lib/components/checkout-return-notice.d.ts +26 -0
- package/src/lib/components/checkout-return-notice.js +48 -0
- package/src/lib/components/checkout-return-notice.js.map +1 -0
- package/src/lib/components/commerce-console-page.js +124 -0
- package/src/lib/components/commerce-console-page.js.map +1 -1
- package/src/lib/components/commerce-console-sections.d.ts +1 -1
- package/src/lib/components/commerce-console-sections.js +4 -0
- package/src/lib/components/commerce-console-sections.js.map +1 -1
- package/src/lib/components/console/bulk-fulfill.d.ts +44 -0
- package/src/lib/components/console/bulk-fulfill.js +84 -0
- package/src/lib/components/console/bulk-fulfill.js.map +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js +1 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/customer-notifications-card.component.d.ts +19 -0
- package/src/lib/components/console/customer-notifications-card.component.js +149 -0
- package/src/lib/components/console/customer-notifications-card.component.js.map +1 -0
- package/src/lib/components/console/host-orders-card.component.js +88 -6
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/locations-card.component.js +164 -57
- package/src/lib/components/console/locations-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +209 -61
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/order-fulfillment-panel.component.d.ts +48 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js +542 -0
- package/src/lib/components/console/order-fulfillment-panel.component.js.map +1 -0
- package/src/lib/components/console/order-invoice.component.d.ts +33 -0
- package/src/lib/components/console/order-invoice.component.js +81 -0
- package/src/lib/components/console/order-invoice.component.js.map +1 -0
- package/src/lib/components/console/order-receipt-resend.component.d.ts +21 -0
- package/src/lib/components/console/order-receipt-resend.component.js +203 -0
- package/src/lib/components/console/order-receipt-resend.component.js.map +1 -0
- package/src/lib/components/console/order-returns.component.d.ts +36 -0
- package/src/lib/components/console/order-returns.component.js +142 -0
- package/src/lib/components/console/order-returns.component.js.map +1 -0
- package/src/lib/components/console/order-shipping-actions.component.d.ts +54 -0
- package/src/lib/components/console/order-shipping-actions.component.js +149 -0
- package/src/lib/components/console/order-shipping-actions.component.js.map +1 -0
- package/src/lib/components/console/order-webhooks-card.component.d.ts +50 -0
- package/src/lib/components/console/order-webhooks-card.component.js +623 -0
- package/src/lib/components/console/order-webhooks-card.component.js.map +1 -0
- package/src/lib/components/console/order-zones.d.ts +155 -0
- package/src/lib/components/console/order-zones.js +40 -0
- package/src/lib/components/console/order-zones.js.map +1 -0
- package/src/lib/components/console/payment-methods-card.component.d.ts +67 -0
- package/src/lib/components/console/payment-methods-card.component.js +395 -0
- package/src/lib/components/console/payment-methods-card.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-api.d.ts +124 -0
- package/src/lib/components/console/pos/pos-api.js +101 -0
- package/src/lib/components/console/pos/pos-api.js.map +1 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +36 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js +160 -0
- package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +39 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js +352 -0
- package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-product-grid.component.d.ts +47 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js +272 -0
- package/src/lib/components/console/pos/pos-product-grid.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.d.ts +27 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js +282 -0
- package/src/lib/components/console/pos/pos-receipt-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +53 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js +445 -0
- package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +31 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js +640 -0
- package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -0
- package/src/lib/components/console/pos/use-pos-display.d.ts +43 -0
- package/src/lib/components/console/pos/use-pos-display.js +161 -0
- package/src/lib/components/console/pos/use-pos-display.js.map +1 -0
- package/src/lib/components/console/pos-devices-card.component.d.ts +14 -0
- package/src/lib/components/console/pos-devices-card.component.js +546 -0
- package/src/lib/components/console/pos-devices-card.component.js.map +1 -0
- package/src/lib/components/console/pos-display/brand-screen.d.ts +33 -0
- package/src/lib/components/console/pos-display/brand-screen.js +85 -0
- package/src/lib/components/console/pos-display/brand-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/cart-screen.d.ts +29 -0
- package/src/lib/components/console/pos-display/cart-screen.js +166 -0
- package/src/lib/components/console/pos-display/cart-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pairing-screen.d.ts +24 -0
- package/src/lib/components/console/pos-display/pairing-screen.js +127 -0
- package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/pos-display-api.d.ts +90 -0
- package/src/lib/components/console/pos-display/pos-display-api.js +140 -0
- package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -0
- package/src/lib/components/console/pos-display/receipt-screen.d.ts +35 -0
- package/src/lib/components/console/pos-display/receipt-screen.js +200 -0
- package/src/lib/components/console/pos-display/receipt-screen.js.map +1 -0
- package/src/lib/components/console/pos-display/tip-screen.d.ts +36 -0
- package/src/lib/components/console/pos-display/tip-screen.js +211 -0
- package/src/lib/components/console/pos-display/tip-screen.js.map +1 -0
- package/src/lib/components/console/pos-display-page.component.d.ts +16 -0
- package/src/lib/components/console/pos-display-page.component.js +407 -0
- package/src/lib/components/console/pos-display-page.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js +289 -0
- package/src/lib/components/console/pos-ops/pos-customer-lookup.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js +61 -0
- package/src/lib/components/console/pos-ops/pos-last-receipt.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +38 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +129 -0
- package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js +60 -0
- package/src/lib/components/console/pos-ops/pos-ops-api.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.d.ts +48 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js +220 -0
- package/src/lib/components/console/pos-ops/pos-pin-pad.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.d.ts +63 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js +186 -0
- package/src/lib/components/console/pos-ops/pos-receipt-actions.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-receipt.d.ts +39 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js +182 -0
- package/src/lib/components/console/pos-ops/pos-receipt.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js +465 -0
- package/src/lib/components/console/pos-ops/pos-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.d.ts +29 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +253 -0
- package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +34 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +494 -0
- package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.d.ts +37 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js +102 -0
- package/src/lib/components/console/pos-ops/pos-shift-report.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.d.ts +30 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js +277 -0
- package/src/lib/components/console/pos-ops/pos-staff-pins-card.component.js.map +1 -0
- package/src/lib/components/console/pos-ops/register-ops.d.ts +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js +28 -0
- package/src/lib/components/console/pos-ops/register-ops.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.d.ts +46 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js +128 -0
- package/src/lib/components/console/pos-ops/use-pos-cashier.js.map +1 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.d.ts +36 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js +64 -0
- package/src/lib/components/console/pos-ops/use-pos-sale-receipt.js.map +1 -0
- package/src/lib/components/console/pos-page.component.d.ts +13 -5
- package/src/lib/components/console/pos-page.component.js +756 -654
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/pos-zones.d.ts +23 -0
- package/src/lib/components/console/pos-zones.js +31 -0
- package/src/lib/components/console/pos-zones.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.js +61 -71
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-labels-dialog.component.d.ts +13 -0
- package/src/lib/components/console/product-labels-dialog.component.js +197 -0
- package/src/lib/components/console/product-labels-dialog.component.js.map +1 -0
- package/src/lib/components/console/product-register-fields.component.d.ts +19 -0
- package/src/lib/components/console/product-register-fields.component.js +241 -0
- package/src/lib/components/console/product-register-fields.component.js.map +1 -0
- package/src/lib/components/console/product-zones.d.ts +44 -0
- package/src/lib/components/console/product-zones.js.map +1 -1
- package/src/lib/components/console/products-hub-card.component.js +23 -20
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/register-hardware-card.component.d.ts +33 -0
- package/src/lib/components/console/register-hardware-card.component.js +826 -0
- package/src/lib/components/console/register-hardware-card.component.js.map +1 -0
- package/src/lib/components/console/registers-card.component.js +24 -5
- package/src/lib/components/console/registers-card.component.js.map +1 -1
- package/src/lib/components/console/return-actions.d.ts +38 -0
- package/src/lib/components/console/return-actions.js +76 -0
- package/src/lib/components/console/return-actions.js.map +1 -0
- package/src/lib/components/console/return-detail-dialog.component.d.ts +34 -0
- package/src/lib/components/console/return-detail-dialog.component.js +718 -0
- package/src/lib/components/console/return-detail-dialog.component.js.map +1 -0
- package/src/lib/components/console/return-settings-card.component.d.ts +34 -0
- package/src/lib/components/console/return-settings-card.component.js +195 -0
- package/src/lib/components/console/return-settings-card.component.js.map +1 -0
- package/src/lib/components/console/return-zones.d.ts +87 -0
- package/src/lib/components/console/return-zones.js +31 -0
- package/src/lib/components/console/return-zones.js.map +1 -0
- package/src/lib/components/console/returns-card.component.d.ts +45 -0
- package/src/lib/components/console/returns-card.component.js +159 -0
- package/src/lib/components/console/returns-card.component.js.map +1 -0
- package/src/lib/components/console/shipping-settings-card.component.js +161 -5
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
- package/src/lib/components/console/shippingeasy-card.component.d.ts +59 -0
- package/src/lib/components/console/shippingeasy-card.component.js +378 -0
- package/src/lib/components/console/shippingeasy-card.component.js.map +1 -0
- package/src/lib/components/console/shipstation-card.component.d.ts +35 -0
- package/src/lib/components/console/shipstation-card.component.js +345 -0
- package/src/lib/components/console/shipstation-card.component.js.map +1 -0
- package/src/lib/components/console/start-return-dialog.component.d.ts +40 -0
- package/src/lib/components/console/start-return-dialog.component.js +243 -0
- package/src/lib/components/console/start-return-dialog.component.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.js +2 -1
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/console/store-settings-card.component.js +2 -66
- package/src/lib/components/console/store-settings-card.component.js.map +1 -1
- package/src/lib/components/console/store-zones.d.ts +42 -0
- package/src/lib/components/console/store-zones.js +39 -0
- package/src/lib/components/console/store-zones.js.map +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
- package/src/lib/components/order-status.d.ts +36 -0
- package/src/lib/components/order-status.js +502 -0
- package/src/lib/components/order-status.js.map +1 -0
- package/src/lib/components/product-detail.js +41 -2
- package/src/lib/components/product-detail.js.map +1 -1
- package/src/lib/components/return-request.d.ts +32 -0
- package/src/lib/components/return-request.js +576 -0
- package/src/lib/components/return-request.js.map +1 -0
- package/src/lib/components/storefront-payment-appearance.d.ts +32 -0
- package/src/lib/components/storefront-payment-appearance.js +114 -0
- package/src/lib/components/storefront-payment-appearance.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +57 -1
- package/src/lib/components/storefront-payment-element.js +332 -33
- package/src/lib/components/storefront-payment-element.js.map +1 -1
- package/src/lib/constants/order-status.d.ts +22 -0
- package/src/lib/constants/order-status.js +22 -0
- package/src/lib/constants/order-status.js.map +1 -0
- package/src/lib/constants/return-request.d.ts +27 -0
- package/src/lib/constants/return-request.js +32 -0
- package/src/lib/constants/return-request.js.map +1 -0
- package/src/lib/constants/stock-movement-query.js +2 -1
- package/src/lib/constants/stock-movement-query.js.map +1 -1
- package/src/lib/declarations.console-server.js +9 -0
- package/src/lib/declarations.console-server.js.map +1 -1
- package/src/lib/declarations.server.d.ts +2 -1
- package/src/lib/declarations.server.js +68 -1
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/model/buyer-notifications.d.ts +59 -0
- package/src/lib/model/buyer-notifications.js +97 -0
- package/src/lib/model/buyer-notifications.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +171 -2
- package/src/lib/model/commerce-orders.js +26 -16
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce-payment-methods.d.ts +146 -0
- package/src/lib/model/commerce-payment-methods.js +247 -0
- package/src/lib/model/commerce-payment-methods.js.map +1 -0
- package/src/lib/model/commerce-pos-ops.d.ts +437 -0
- package/src/lib/model/commerce-pos-ops.js +721 -0
- package/src/lib/model/commerce-pos-ops.js.map +1 -0
- package/src/lib/model/commerce-pos.d.ts +263 -0
- package/src/lib/model/commerce-pos.js +375 -0
- package/src/lib/model/commerce-pos.js.map +1 -0
- package/src/lib/model/commerce-printers.d.ts +211 -0
- package/src/lib/model/commerce-printers.js +181 -0
- package/src/lib/model/commerce-printers.js.map +1 -0
- package/src/lib/model/commerce-receipt.d.ts +97 -0
- package/src/lib/model/commerce-receipt.js +180 -0
- package/src/lib/model/commerce-receipt.js.map +1 -0
- package/src/lib/model/commerce-returns.d.ts +207 -0
- package/src/lib/model/commerce-returns.js +300 -0
- package/src/lib/model/commerce-returns.js.map +1 -0
- package/src/lib/model/commerce-shipping.d.ts +44 -1
- package/src/lib/model/commerce-shipping.js +53 -9
- package/src/lib/model/commerce-shipping.js.map +1 -1
- package/src/lib/model/commerce-tax-engine.d.ts +90 -0
- package/src/lib/model/commerce-tax-engine.js +129 -0
- package/src/lib/model/commerce-tax-engine.js.map +1 -0
- package/src/lib/model/commerce.d.ts +91 -2
- package/src/lib/model/commerce.js +89 -1
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/index.d.ts +16 -0
- package/src/lib/model/index.js +16 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/order-events.d.ts +154 -0
- package/src/lib/model/order-events.js +153 -0
- package/src/lib/model/order-events.js.map +1 -0
- package/src/lib/model/order-fulfillment.d.ts +117 -0
- package/src/lib/model/order-fulfillment.js +217 -0
- package/src/lib/model/order-fulfillment.js.map +1 -0
- package/src/lib/model/order-history.d.ts +58 -0
- package/src/lib/model/order-history.js +22 -0
- package/src/lib/model/order-history.js.map +1 -0
- package/src/lib/model/order-list-fields.d.ts +9 -1
- package/src/lib/model/order-list-fields.js +7 -1
- package/src/lib/model/order-list-fields.js.map +1 -1
- package/src/lib/model/order-shipping-export.d.ts +91 -0
- package/src/lib/model/order-shipping-export.js +192 -0
- package/src/lib/model/order-shipping-export.js.map +1 -0
- package/src/lib/model/order-status-view.d.ts +103 -0
- package/src/lib/model/order-status-view.js +156 -0
- package/src/lib/model/order-status-view.js.map +1 -0
- package/src/lib/model/order-webhooks.d.ts +142 -0
- package/src/lib/model/order-webhooks.js +91 -0
- package/src/lib/model/order-webhooks.js.map +1 -0
- package/src/lib/model/product-channel.d.ts +56 -0
- package/src/lib/model/product-channel.js +86 -0
- package/src/lib/model/product-channel.js.map +1 -0
- package/src/lib/model/product-modifiers.d.ts +80 -0
- package/src/lib/model/product-modifiers.js +140 -0
- package/src/lib/model/product-modifiers.js.map +1 -0
- package/src/lib/model/product-write.d.ts +186 -0
- package/src/lib/model/product-write.js +116 -0
- package/src/lib/model/product-write.js.map +1 -0
- package/src/lib/model/shippingeasy.d.ts +94 -0
- package/src/lib/model/shippingeasy.js +267 -0
- package/src/lib/model/shippingeasy.js.map +1 -0
- package/src/lib/model/shipstation.d.ts +125 -0
- package/src/lib/model/shipstation.js +399 -0
- package/src/lib/model/shipstation.js.map +1 -0
- package/src/lib/model/smart-collection-reads.d.ts +32 -0
- package/src/lib/model/smart-collection-reads.js +63 -0
- package/src/lib/model/smart-collection-reads.js.map +1 -0
- package/src/lib/model/tracking-url.d.ts +74 -0
- package/src/lib/model/tracking-url.js +159 -0
- package/src/lib/model/tracking-url.js.map +1 -0
- package/src/lib/plugin-config.d.ts +13 -0
- package/src/lib/plugin-config.js +77 -5
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +26 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/pos-ops-config.d.ts +39 -0
- package/src/lib/pos-ops-config.js +88 -0
- package/src/lib/pos-ops-config.js.map +1 -0
- package/src/lib/printing/print-document.d.ts +106 -0
- package/src/lib/printing/print-document.js +464 -0
- package/src/lib/printing/print-document.js.map +1 -0
- package/src/lib/printing/product-labels.d.ts +58 -0
- package/src/lib/printing/product-labels.js +116 -0
- package/src/lib/printing/product-labels.js.map +1 -0
- package/src/lib/printing/render-epson.d.ts +57 -0
- package/src/lib/printing/render-epson.js +135 -0
- package/src/lib/printing/render-epson.js.map +1 -0
- package/src/lib/printing/render-star.d.ts +45 -0
- package/src/lib/printing/render-star.js +100 -0
- package/src/lib/printing/render-star.js.map +1 -0
- package/src/lib/printing/render-text.d.ts +25 -0
- package/src/lib/printing/render-text.js +53 -0
- package/src/lib/printing/render-text.js.map +1 -0
- package/src/lib/server/api-v1/openapi.js +27 -4
- package/src/lib/server/api-v1/openapi.js.map +1 -1
- package/src/lib/server/api-v1/order-view.d.ts +67 -0
- package/src/lib/server/api-v1/order-view.js +120 -0
- package/src/lib/server/api-v1/order-view.js.map +1 -0
- package/src/lib/server/api-v1/orders-and-products.js +58 -65
- package/src/lib/server/api-v1/orders-and-products.js.map +1 -1
- package/src/lib/server/billing-webhook.js +135 -28
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +29 -0
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/carrier-rates-availability.d.ts +26 -0
- package/src/lib/server/carrier-rates-availability.js +76 -0
- package/src/lib/server/carrier-rates-availability.js.map +1 -0
- package/src/lib/server/carrier-shipping.d.ts +84 -0
- package/src/lib/server/carrier-shipping.js +135 -0
- package/src/lib/server/carrier-shipping.js.map +1 -0
- package/src/lib/server/cart-checkout.d.ts +2 -0
- package/src/lib/server/cart-checkout.js +226 -22
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/channel-order-updates.d.ts +50 -0
- package/src/lib/server/channel-order-updates.js +290 -0
- package/src/lib/server/channel-order-updates.js.map +1 -0
- package/src/lib/server/channel-orders.d.ts +85 -0
- package/src/lib/server/channel-orders.js +543 -0
- package/src/lib/server/channel-orders.js.map +1 -0
- package/src/lib/server/checkout-extras.d.ts +64 -0
- package/src/lib/server/checkout-extras.js +157 -0
- package/src/lib/server/checkout-extras.js.map +1 -0
- package/src/lib/server/{feed.d.ts → checkout-status.d.ts} +2 -7
- package/src/lib/server/checkout-status.js +111 -0
- package/src/lib/server/checkout-status.js.map +1 -0
- package/src/lib/server/checkout.js +86 -9
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/draft-order.js +34 -5
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/fulfill-order.d.ts +127 -10
- package/src/lib/server/fulfill-order.js +451 -49
- package/src/lib/server/fulfill-order.js.map +1 -1
- package/src/lib/server/legacy-feed.d.ts +28 -0
- package/src/lib/server/legacy-feed.js +52 -0
- package/src/lib/server/legacy-feed.js.map +1 -0
- package/src/lib/server/native-checkout.d.ts +34 -15
- package/src/lib/server/native-checkout.js +32 -17
- package/src/lib/server/native-checkout.js.map +1 -1
- package/src/lib/server/order-event-host-emit.d.ts +23 -0
- package/src/lib/server/order-event-host-emit.js +30 -0
- package/src/lib/server/order-event-host-emit.js.map +1 -0
- package/src/lib/server/order-event-triggers.d.ts +37 -0
- package/src/lib/server/order-event-triggers.js +119 -0
- package/src/lib/server/order-event-triggers.js.map +1 -0
- package/src/lib/server/order-events.d.ts +62 -0
- package/src/lib/server/order-events.js +109 -0
- package/src/lib/server/order-events.js.map +1 -0
- package/src/lib/server/order-history.d.ts +23 -0
- package/src/lib/server/order-history.js +65 -0
- package/src/lib/server/order-history.js.map +1 -0
- package/src/lib/server/order-notifications.d.ts +185 -0
- package/src/lib/server/order-notifications.js +567 -0
- package/src/lib/server/order-notifications.js.map +1 -0
- package/src/lib/server/order-receipt-send.d.ts +39 -0
- package/src/lib/server/order-receipt-send.js +151 -0
- package/src/lib/server/order-receipt-send.js.map +1 -0
- package/src/lib/server/order-status-token.d.ts +31 -0
- package/src/lib/server/order-status-token.js +75 -0
- package/src/lib/server/order-status-token.js.map +1 -0
- package/src/lib/server/order-status.d.ts +58 -0
- package/src/lib/server/order-status.js +141 -0
- package/src/lib/server/order-status.js.map +1 -0
- package/src/lib/server/order-webhooks.d.ts +108 -0
- package/src/lib/server/order-webhooks.js +622 -0
- package/src/lib/server/order-webhooks.js.map +1 -0
- package/src/lib/server/orders-shipping-prepare.d.ts +26 -0
- package/src/lib/server/orders-shipping-prepare.js +121 -0
- package/src/lib/server/orders-shipping-prepare.js.map +1 -0
- package/src/lib/server/payment-method-domains.d.ts +209 -0
- package/src/lib/server/payment-method-domains.js +444 -0
- package/src/lib/server/payment-method-domains.js.map +1 -0
- package/src/lib/server/payment-methods.d.ts +77 -0
- package/src/lib/server/payment-methods.js +284 -0
- package/src/lib/server/payment-methods.js.map +1 -0
- package/src/lib/server/pos-auth.d.ts +50 -0
- package/src/lib/server/pos-auth.js +121 -0
- package/src/lib/server/pos-auth.js.map +1 -0
- package/src/lib/server/pos-customer.d.ts +49 -0
- package/src/lib/server/pos-customer.js +257 -0
- package/src/lib/server/pos-customer.js.map +1 -0
- package/src/lib/server/pos-display.d.ts +57 -0
- package/src/lib/server/pos-display.js +419 -0
- package/src/lib/server/pos-display.js.map +1 -0
- package/src/lib/server/pos-fee-month.d.ts +34 -0
- package/src/lib/server/pos-fee-month.js +36 -0
- package/src/lib/server/pos-fee-month.js.map +1 -0
- package/src/lib/server/pos-ops-gate.d.ts +161 -0
- package/src/lib/server/pos-ops-gate.js +295 -0
- package/src/lib/server/pos-ops-gate.js.map +1 -0
- package/src/lib/server/pos-ops-routes.d.ts +22 -0
- package/src/lib/server/pos-ops-routes.js +36 -0
- package/src/lib/server/pos-ops-routes.js.map +1 -0
- package/src/lib/server/pos-order.d.ts +1 -18
- package/src/lib/server/pos-order.js +222 -42
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/pos-payment.d.ts +39 -0
- package/src/lib/server/pos-payment.js +922 -0
- package/src/lib/server/pos-payment.js.map +1 -0
- package/src/lib/server/pos-print.d.ts +82 -0
- package/src/lib/server/pos-print.js +193 -0
- package/src/lib/server/pos-print.js.map +1 -0
- package/src/lib/server/pos-readers.d.ts +27 -0
- package/src/lib/server/pos-readers.js +276 -0
- package/src/lib/server/pos-readers.js.map +1 -0
- package/src/lib/server/pos-refund-authority.d.ts +60 -0
- package/src/lib/server/pos-refund-authority.js +72 -0
- package/src/lib/server/pos-refund-authority.js.map +1 -0
- package/src/lib/server/pos-return.d.ts +58 -0
- package/src/lib/server/pos-return.js +891 -0
- package/src/lib/server/pos-return.js.map +1 -0
- package/src/lib/server/pos-sale-stamp.d.ts +66 -0
- package/src/lib/server/pos-sale-stamp.js +84 -0
- package/src/lib/server/pos-sale-stamp.js.map +1 -0
- package/src/lib/server/pos-sale.d.ts +170 -0
- package/src/lib/server/pos-sale.js +461 -0
- package/src/lib/server/pos-sale.js.map +1 -0
- package/src/lib/server/pos-shift.d.ts +45 -0
- package/src/lib/server/pos-shift.js +484 -0
- package/src/lib/server/pos-shift.js.map +1 -0
- package/src/lib/server/pos-staff-pin.d.ts +26 -0
- package/src/lib/server/pos-staff-pin.js +339 -0
- package/src/lib/server/pos-staff-pin.js.map +1 -0
- package/src/lib/server/pos-stripe.d.ts +91 -0
- package/src/lib/server/pos-stripe.js +129 -0
- package/src/lib/server/pos-stripe.js.map +1 -0
- package/src/lib/server/pos-terminal-connection-token.d.ts +48 -0
- package/src/lib/server/pos-terminal-connection-token.js +166 -0
- package/src/lib/server/pos-terminal-connection-token.js.map +1 -0
- package/src/lib/server/pos-terminal.d.ts +218 -0
- package/src/lib/server/pos-terminal.js +1014 -0
- package/src/lib/server/pos-terminal.js.map +1 -0
- package/src/lib/server/print-queue.d.ts +124 -0
- package/src/lib/server/print-queue.js +301 -0
- package/src/lib/server/print-queue.js.map +1 -0
- package/src/lib/server/printer-poll.d.ts +75 -0
- package/src/lib/server/printer-poll.js +325 -0
- package/src/lib/server/printer-poll.js.map +1 -0
- package/src/lib/server/printer-secret.d.ts +39 -0
- package/src/lib/server/printer-secret.js +56 -0
- package/src/lib/server/printer-secret.js.map +1 -0
- package/src/lib/server/printers.d.ts +114 -0
- package/src/lib/server/printers.js +546 -0
- package/src/lib/server/printers.js.map +1 -0
- package/src/lib/server/product-catalog.d.ts +42 -0
- package/src/lib/server/product-catalog.js +309 -0
- package/src/lib/server/product-catalog.js.map +1 -0
- package/src/lib/server/product-drafts.d.ts +5 -1
- package/src/lib/server/product-drafts.js +3 -3
- package/src/lib/server/product-drafts.js.map +1 -1
- package/src/lib/server/product-writer.d.ts +19 -0
- package/src/lib/server/product-writer.js +261 -0
- package/src/lib/server/product-writer.js.map +1 -0
- package/src/lib/server/products-write.d.ts +61 -0
- package/src/lib/server/products-write.js +375 -0
- package/src/lib/server/products-write.js.map +1 -0
- package/src/lib/server/refund.js +110 -45
- package/src/lib/server/refund.js.map +1 -1
- package/src/lib/server/reserve.js +2 -0
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/return-status-action.d.ts +37 -0
- package/src/lib/server/return-status-action.js +57 -0
- package/src/lib/server/return-status-action.js.map +1 -0
- package/src/lib/server/returns.d.ts +119 -0
- package/src/lib/server/returns.js +938 -0
- package/src/lib/server/returns.js.map +1 -0
- package/src/lib/server/shipment-records.d.ts +36 -0
- package/src/lib/server/shipment-records.js +289 -0
- package/src/lib/server/shipment-records.js.map +1 -0
- package/src/lib/server/shipping-connector-gates.d.ts +40 -0
- package/src/lib/server/shipping-connector-gates.js +97 -0
- package/src/lib/server/shipping-connector-gates.js.map +1 -0
- package/src/lib/server/shipping-connectors.d.ts +29 -0
- package/src/lib/server/shipping-connectors.js +236 -0
- package/src/lib/server/shipping-connectors.js.map +1 -0
- package/src/lib/server/shippingeasy.d.ts +238 -0
- package/src/lib/server/shippingeasy.js +787 -0
- package/src/lib/server/shippingeasy.js.map +1 -0
- package/src/lib/server/shipstation.d.ts +129 -0
- package/src/lib/server/shipstation.js +483 -0
- package/src/lib/server/shipstation.js.map +1 -0
- package/src/lib/server/site-page-resolver.d.ts +5 -0
- package/src/lib/server/site-page-resolver.js +156 -1
- package/src/lib/server/site-page-resolver.js.map +1 -1
- package/src/lib/server/stock-levels.d.ts +21 -0
- package/src/lib/server/stock-levels.js +263 -0
- package/src/lib/server/stock-levels.js.map +1 -0
- package/src/lib/server/stripe-refund.d.ts +47 -0
- package/src/lib/server/stripe-refund.js +87 -0
- package/src/lib/server/stripe-refund.js.map +1 -0
- package/src/lib/server/supplier-update.js +46 -5
- package/src/lib/server/supplier-update.js.map +1 -1
- package/src/lib/server/tax-engine-quote.d.ts +47 -0
- package/src/lib/server/tax-engine-quote.js +105 -0
- package/src/lib/server/tax-engine-quote.js.map +1 -0
- package/src/lib/server.js +143 -2
- package/src/lib/server.js.map +1 -1
- package/src/lib/site.js +12 -0
- package/src/lib/site.js.map +1 -1
- package/src/lib/subprocessors.d.ts +26 -0
- package/src/lib/subprocessors.js +50 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/tenant-emails.js +461 -3
- package/src/lib/tenant-emails.js.map +1 -1
- package/src/lib/testing/fake-firestore.d.ts +45 -0
- package/src/lib/testing/fake-firestore.js +189 -0
- package/src/lib/testing/fake-firestore.js.map +1 -0
- package/src/lib/testing/memory-firestore.d.ts +136 -0
- package/src/lib/testing/memory-firestore.js +282 -0
- package/src/lib/testing/memory-firestore.js.map +1 -0
- package/src/lib/testing/pos-ops-harness.d.ts +50 -0
- package/src/lib/testing/pos-ops-harness.js +184 -0
- package/src/lib/testing/pos-ops-harness.js.map +1 -0
- package/src/lib/testing/pos-ops-memory-firestore.d.ts +55 -0
- package/src/lib/testing/pos-ops-memory-firestore.js +376 -0
- package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -0
- package/src/lib/transfer/products.server.d.ts +5 -0
- package/src/lib/transfer/products.server.js +2 -2
- package/src/lib/transfer/products.server.js.map +1 -1
- package/src/lib/transfer/records-transfer.d.ts +11 -1
- package/src/lib/transfer/records-transfer.js +127 -5
- package/src/lib/transfer/records-transfer.js.map +1 -1
- package/src/lib/transfer/records.server.d.ts +9 -2
- package/src/lib/transfer/records.server.js +58 -7
- package/src/lib/transfer/records.server.js.map +1 -1
- package/src/lib/transfer/register-transfer-resources.js +40 -1
- package/src/lib/transfer/register-transfer-resources.js.map +1 -1
- package/src/lib/transfer/register-transfer-ui.js +4 -1
- package/src/lib/transfer/register-transfer-ui.js.map +1 -1
- package/src/lib/transfer/shipping-presets.d.ts +23 -0
- package/src/lib/transfer/shipping-presets.js +156 -0
- package/src/lib/transfer/shipping-presets.js.map +1 -0
- package/src/lib/transfer/tracking-transfer.d.ts +101 -0
- package/src/lib/transfer/tracking-transfer.js +546 -0
- package/src/lib/transfer/tracking-transfer.js.map +1 -0
- package/src/lib/transfer/tracking.server.d.ts +37 -0
- package/src/lib/transfer/tracking.server.js +393 -0
- package/src/lib/transfer/tracking.server.js.map +1 -0
- package/src/lib/transfer/transfer-keys.d.ts +2 -1
- package/src/lib/transfer/transfer-keys.js +6 -2
- package/src/lib/transfer/transfer-keys.js.map +1 -1
- package/src/lib/utils/code128.d.ts +37 -0
- package/src/lib/utils/code128.js +199 -0
- package/src/lib/utils/code128.js.map +1 -0
- package/src/lib/utils/order-invoice.d.ts +55 -0
- package/src/lib/utils/order-invoice.js +127 -0
- package/src/lib/utils/order-invoice.js.map +1 -0
- package/src/lib/utils/use-checkout-return-notice.d.ts +34 -0
- package/src/lib/utils/use-checkout-return-notice.js +78 -0
- package/src/lib/utils/use-checkout-return-notice.js.map +1 -0
- package/src/lib/server/feed.js +0 -69
- package/src/lib/server/feed.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/barcode/barcode-decode.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A small 1D barcode reader for camera frames (AGL-3619): the fallback the\n * camera scanner uses where the browser has no `BarcodeDetector` — Safari on\n * the iPad a register most often runs on, and Chrome on Windows.\n *\n * Why not zxing: its WebAssembly build cannot be compiled under the console's\n * enforcing `script-src` (no `'wasm-unsafe-eval'`), and its JavaScript build\n * is ~400 KB that does not tree-shake. A counter scans three symbologies —\n * EAN-13 / UPC-A on retail goods, EAN-8 on small packs, and Code128 on the\n * order number Aglyn prints and on most warehouse labels — and reading those\n * from a horizontal pass needs a few kilobytes, loaded only when the scanner\n * opens on a browser that lacks the native detector.\n *\n * The reader takes LUMINANCE ROWS, binarizes each against its local mean,\n * turns it into bar/space runs and tries each symbology in both directions.\n * Every symbology carries a check digit and every candidate must pass it, so\n * a misread is rejected rather than returned; the scanner additionally waits\n * for two agreeing reads.\n */\n\nexport type DecodedFormat = 'ean_13' | 'upc_a' | 'ean_8' | 'code_128'\n\nexport interface DecodedBarcode {\n format: DecodedFormat\n text: string\n}\n\ninterface Run {\n dark: boolean\n width: number\n}\n\n/** Bar/space runs of a binarized row; `dark` is a bar. */\nexport function rowRuns(dark: ArrayLike<boolean>): Run[] {\n const runs: Run[] = []\n for (let index = 0; index < dark.length; index += 1) {\n const value = Boolean(dark[index])\n const last = runs[runs.length - 1]\n if (last && last.dark === value) last.width += 1\n else runs.push({ dark: value, width: 1 })\n }\n return runs\n}\n\n/**\n * A row binarized against a local mean, so a shadow across the label or a\n * glossy hot spot does not swallow half the bars. Rows with too little\n * contrast to hold a barcode answer `null`.\n */\nexport function binarizeRow(luma: ArrayLike<number>): boolean[] | null {\n const length = luma.length\n if (length < 32) return null\n let min = Infinity\n let max = -Infinity\n const smooth = new Float32Array(length)\n for (let index = 0; index < length; index += 1) {\n const value =\n (Number(luma[Math.max(0, index - 1)]) + 2 * Number(luma[index]) + Number(luma[Math.min(length - 1, index + 1)])) / 4\n smooth[index] = value\n if (value < min) min = value\n if (value > max) max = value\n }\n if (max - min < 24) return null\n const half = Math.max(8, Math.round(length / 24))\n const prefix = new Float64Array(length + 1)\n for (let index = 0; index < length; index += 1) prefix[index + 1] = prefix[index] + smooth[index]\n const globalMid = (min + max) / 2\n const out: boolean[] = new Array(length)\n for (let index = 0; index < length; index += 1) {\n const from = Math.max(0, index - half)\n const to = Math.min(length, index + half + 1)\n const local = (prefix[to] - prefix[from]) / (to - from)\n // Lean on the global midpoint in flat stretches (quiet zones), where a\n // local mean would turn paper grain into bars.\n const threshold = 0.6 * local + 0.4 * globalMid\n out[index] = smooth[index] < threshold\n }\n return out\n}\n\n/** Distance between measured run widths and a pattern, both scaled to the same total. */\nfunction patternError(widths: readonly number[], pattern: readonly number[], modules: number): number {\n const total = widths.reduce((sum, width) => sum + width, 0)\n if (!total) return Infinity\n const scale = modules / total\n let error = 0\n for (let index = 0; index < pattern.length; index += 1) {\n error += Math.abs(widths[index] * scale - pattern[index])\n }\n return error\n}\n\nfunction bestMatch(\n widths: readonly number[],\n patterns: readonly (readonly number[])[],\n modules: number,\n maxError: number,\n): number {\n let best = -1\n let bestError = maxError\n for (let index = 0; index < patterns.length; index += 1) {\n const error = patternError(widths, patterns[index], modules)\n if (error < bestError) {\n bestError = error\n best = index\n }\n }\n return best\n}\n\nconst digits = (spec: string) => spec.split('').map(Number)\n\n/*==========================================\n * EAN-13 / UPC-A / EAN-8\n *=========================================*/\n\n/** Space-bar-space-bar widths of the odd-parity (L) left-hand digits 0-9. */\nconst EAN_L = ['3211', '2221', '2122', '1411', '1132', '1231', '1114', '1312', '1213', '3112'].map(digits)\n/** Even parity (G) is L reversed. */\nconst EAN_G = EAN_L.map((pattern) => [...pattern].reverse())\n/** Left-half parity of an EAN-13 per first digit; 1 = G. */\nconst EAN_FIRST_DIGIT_PARITY = [\n '000000', '001011', '001101', '001110', '010011', '011001', '011100', '010101', '010110', '011010',\n]\n\nexport function eanCheckDigitValid(code: string): boolean {\n if (!/^\\d+$/.test(code)) return false\n const body = code.slice(0, -1)\n let sum = 0\n for (let index = 0; index < body.length; index += 1) {\n // Weights run 3,1,3,1… from the digit nearest the check digit.\n const fromRight = body.length - 1 - index\n sum += Number(body[index]) * (fromRight % 2 === 0 ? 3 : 1)\n }\n return (10 - (sum % 10)) % 10 === Number(code[code.length - 1])\n}\n\nconst GUARD = [1, 1, 1]\nconst MIDDLE = [1, 1, 1, 1, 1]\n\nfunction widthsAt(runs: Run[], start: number, count: number): number[] | null {\n if (start + count > runs.length) return null\n return runs.slice(start, start + count).map((run) => run.width)\n}\n\nfunction guardOk(runs: Run[], start: number, count: number, moduleWidth: number): boolean {\n const widths = widthsAt(runs, start, count)\n if (!widths) return false\n return widths.every((width) => width > moduleWidth * 0.35 && width < moduleWidth * 2.2)\n}\n\nfunction quietBefore(runs: Run[], start: number, moduleWidth: number): boolean {\n return start === 0 || runs[start - 1].width >= moduleWidth * 2.5\n}\n\nfunction decodeEanDigits(\n runs: Run[],\n start: number,\n count: number,\n leftHalf: boolean,\n): { digits: number[]; parity: string } | null {\n const out: number[] = []\n let parity = ''\n for (let index = 0; index < count; index += 1) {\n const widths = widthsAt(runs, start + index * 4, 4)\n if (!widths) return null\n if (leftHalf) {\n const l = bestMatch(widths, EAN_L, 7, 2.2)\n const g = bestMatch(widths, EAN_G, 7, 2.2)\n const lError = l < 0 ? Infinity : patternError(widths, EAN_L[l], 7)\n const gError = g < 0 ? Infinity : patternError(widths, EAN_G[g], 7)\n if (l < 0 && g < 0) return null\n if (lError <= gError) {\n out.push(l)\n parity += '0'\n } else {\n out.push(g)\n parity += '1'\n }\n } else {\n const r = bestMatch(widths, EAN_L, 7, 2.2)\n if (r < 0) return null\n out.push(r)\n }\n }\n return { digits: out, parity }\n}\n\nfunction decodeEan13At(runs: Run[], start: number): DecodedBarcode | null {\n if (start + 59 > runs.length || !runs[start].dark) return null\n const total = runs.slice(start, start + 59).reduce((sum, run) => sum + run.width, 0)\n const moduleWidth = total / 95\n if (!quietBefore(runs, start, moduleWidth)) return null\n if (!guardOk(runs, start, 3, moduleWidth) || !guardOk(runs, start + 27, 5, moduleWidth) || !guardOk(runs, start + 56, 3, moduleWidth)) {\n return null\n }\n if (patternError(widthsAt(runs, start, 3)!, GUARD, 3) > 1.2) return null\n if (patternError(widthsAt(runs, start + 27, 5)!, MIDDLE, 5) > 1.6) return null\n const left = decodeEanDigits(runs, start + 3, 6, true)\n const right = decodeEanDigits(runs, start + 32, 6, false)\n if (!left || !right) return null\n const first = EAN_FIRST_DIGIT_PARITY.indexOf(left.parity)\n if (first < 0) return null\n const code = [first, ...left.digits, ...right.digits].join('')\n if (!eanCheckDigitValid(code)) return null\n // An EAN-13 that starts with 0 IS a UPC-A, and a UPC-A is what a keyboard\n // scanner types and what most product records hold: twelve digits.\n return code.startsWith('0') ? { format: 'upc_a', text: code.slice(1) } : { format: 'ean_13', text: code }\n}\n\nfunction decodeEan8At(runs: Run[], start: number): DecodedBarcode | null {\n if (start + 43 > runs.length || !runs[start].dark) return null\n const total = runs.slice(start, start + 43).reduce((sum, run) => sum + run.width, 0)\n const moduleWidth = total / 67\n if (!quietBefore(runs, start, moduleWidth)) return null\n if (!guardOk(runs, start, 3, moduleWidth) || !guardOk(runs, start + 19, 5, moduleWidth) || !guardOk(runs, start + 40, 3, moduleWidth)) {\n return null\n }\n const left = decodeEanDigits(runs, start + 3, 4, true)\n const right = decodeEanDigits(runs, start + 24, 4, false)\n if (!left || !right || left.parity !== '0000') return null\n const code = [...left.digits, ...right.digits].join('')\n return eanCheckDigitValid(code) ? { format: 'ean_8', text: code } : null\n}\n\n/*==========================================\n * CODE 128\n *=========================================*/\n\n/** Bar-space widths of symbol values 0-105 (each 11 modules); 106 is STOP (13 modules). */\nexport const CODE128_PATTERNS: readonly (readonly number[])[] = [\n '212222', '222122', '222221', '121223', '121322', '131222', '122213', '122312', '132212', '221213',\n '221312', '231212', '112232', '122132', '122231', '113222', '123122', '123221', '223211', '221132',\n '221231', '213212', '223112', '312131', '311222', '321122', '321221', '312212', '322112', '322211',\n '212123', '212321', '232121', '111323', '131123', '131321', '112313', '132113', '132311', '211313',\n '231113', '231311', '112133', '112331', '132131', '113123', '113321', '133121', '313121', '211331',\n '231131', '213113', '213311', '213131', '311123', '311321', '331121', '312113', '312311', '332111',\n '314111', '221411', '431111', '111224', '111422', '121124', '121421', '141122', '141221', '112214',\n '112412', '122114', '122411', '142112', '142211', '241211', '221114', '413111', '241112', '134111',\n '111242', '121142', '121241', '114212', '124112', '124211', '411212', '421112', '421211', '212141',\n '214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', '411311', '113141',\n '114131', '311141', '411131', '211412', '211214', '211232', '2331112',\n].map(digits)\n\nconst CODE128_DATA = CODE128_PATTERNS.slice(0, 106)\nconst START_A = 103\nconst START_B = 104\nconst START_C = 105\nconst STOP = CODE128_PATTERNS[106]\n\nfunction decodeCode128At(runs: Run[], start: number): DecodedBarcode | null {\n if (!runs[start]?.dark) return null\n const startWidths = widthsAt(runs, start, 6)\n if (!startWidths) return null\n const startValue = bestMatch(startWidths, CODE128_DATA, 11, 2.0)\n if (startValue < START_A) return null\n const moduleWidth = startWidths.reduce((sum, width) => sum + width, 0) / 11\n if (!quietBefore(runs, start, moduleWidth)) return null\n const values: number[] = [startValue]\n let at = start + 6\n for (let guard = 0; guard < 60; guard += 1) {\n const widths = widthsAt(runs, at, 6)\n const value = widths ? bestMatch(widths, CODE128_DATA, 11, 2.0) : -1\n const dataError = value >= 0 && widths ? patternError(widths, CODE128_DATA[value], 11) : Infinity\n // STOP is seven runs and ends the symbol at a quiet zone. A data symbol\n // and the bar after it can look like one, so it wins only where it fits\n // better than any data symbol AND white space follows it.\n const stop = widthsAt(runs, at, 7)\n if (stop) {\n const stopError = patternError(stop, STOP, 13)\n const stopModule = stop.reduce((sum, width) => sum + width, 0) / 13\n const after = runs[at + 7]\n const quietAfter = !after || after.width >= moduleWidth * 2.5\n if (stopError < 2.2 && stopError < dataError && quietAfter) {\n if (Math.abs(stopModule - moduleWidth) > moduleWidth * 0.4) return null\n return finishCode128(values)\n }\n }\n if (!widths || value < 0 || value >= START_A) return null\n const symbolModule = widths.reduce((sum, width) => sum + width, 0) / 11\n if (Math.abs(symbolModule - moduleWidth) > moduleWidth * 0.4) return null\n values.push(value)\n at += 6\n }\n return null\n}\n\nfunction finishCode128(values: number[]): DecodedBarcode | null {\n if (values.length < 3) return null\n const check = values[values.length - 1]\n const data = values.slice(1, -1)\n let sum = values[0]\n data.forEach((value, index) => {\n sum += value * (index + 1)\n })\n if (sum % 103 !== check) return null\n let set: 'A' | 'B' | 'C' = values[0] === START_A ? 'A' : values[0] === START_B ? 'B' : 'C'\n let shift = false\n let text = ''\n for (const value of data) {\n const current: 'A' | 'B' | 'C' = shift ? (set === 'A' ? 'B' : 'A') : set\n shift = false\n if (current === 'C') {\n if (value < 100) text += String(value).padStart(2, '0')\n else if (value === 100) set = 'B'\n else if (value === 101) set = 'A'\n // 102 is FNC1 (GS1 framing): nothing to type.\n continue\n }\n if (value < 96) {\n if (current === 'B') text += String.fromCharCode(value + 32)\n else text += String.fromCharCode(value < 64 ? value + 32 : value - 64)\n continue\n }\n if (value === 98) shift = true\n else if (value === 99) set = 'C'\n else if (value === 100 && current === 'A') set = 'B'\n else if (value === 101 && current === 'B') set = 'A'\n // 96, 97 and the remaining FNC codes carry nothing printable.\n }\n // Control characters (set A) are not something a product lookup types.\n text = Array.from(text).filter((char) => char.charCodeAt(0) >= 0x20).join('')\n return text ? { format: 'code_128', text } : null\n}\n\n/*==========================================\n * A ROW\n *=========================================*/\n\nconst DECODERS = [decodeEan13At, decodeEan8At, decodeCode128At]\n\nfunction decodeRuns(runs: Run[]): DecodedBarcode | null {\n for (let start = 0; start < runs.length; start += 1) {\n if (!runs[start].dark) continue\n for (const decode of DECODERS) {\n const found = decode(runs, start)\n if (found) return found\n }\n }\n return null\n}\n\n/** The barcode in one luminance row, read in either direction, or `null`. */\nexport function decodeLumaRow(luma: ArrayLike<number>): DecodedBarcode | null {\n const dark = binarizeRow(luma)\n if (!dark) return null\n const runs = rowRuns(dark)\n return decodeRuns(runs) ?? decodeRuns([...runs].reverse())\n}\n\n/**\n * The barcode in an RGBA frame (a canvas `ImageData`), sampling horizontal\n * rows across the band a barcode is held in. The middle rows go first: that\n * is where the on-screen guide asks for the label.\n */\nexport function decodeImageData(\n image: { data: ArrayLike<number>; width: number; height: number },\n options: { rows?: number; band?: number } = {},\n): DecodedBarcode | null {\n const { width, height, data } = image\n const rows = options.rows ?? 15\n const band = Math.min(1, Math.max(0.05, options.band ?? 0.5))\n const centre = height / 2\n const spread = (height * band) / 2\n const order: number[] = []\n for (let index = 0; index < rows; index += 1) {\n const step = Math.ceil(index / 2) * (index % 2 ? -1 : 1)\n order.push(Math.round(centre + (step * spread) / Math.ceil(rows / 2)))\n }\n const luma = new Float32Array(width)\n for (const y of order) {\n if (y < 0 || y >= height) continue\n const offset = y * width * 4\n for (let x = 0; x < width; x += 1) {\n const pixel = offset + x * 4\n luma[x] = 0.299 * Number(data[pixel]) + 0.587 * Number(data[pixel + 1]) + 0.114 * Number(data[pixel + 2])\n }\n const found = decodeLumaRow(luma)\n if (found) return found\n }\n return null\n}\n"],"names":["rowRuns","dark","runs","index","length","value","Boolean","last","width","push","binarizeRow","luma","min","Infinity","max","smooth","Float32Array","Number","Math","half","round","prefix","Float64Array","globalMid","out","Array","from","to","local","threshold","patternError","widths","pattern","modules","total","reduce","sum","scale","error","abs","bestMatch","patterns","maxError","best","bestError","digits","spec","split","map","EAN_L","EAN_G","reverse","EAN_FIRST_DIGIT_PARITY","eanCheckDigitValid","code","test","body","slice","fromRight","GUARD","MIDDLE","widthsAt","start","count","run","guardOk","moduleWidth","every","quietBefore","decodeEanDigits","leftHalf","parity","l","g","lError","gError","r","decodeEan13At","left","right","first","indexOf","join","startsWith","format","text","decodeEan8At","CODE128_PATTERNS","CODE128_DATA","START_A","START_B","START_C","STOP","decodeCode128At","startWidths","startValue","values","at","guard","dataError","stop","stopError","stopModule","after","quietAfter","finishCode128","symbolModule","check","data","forEach","set","shift","current","String","padStart","fromCharCode","filter","char","charCodeAt","DECODERS","decodeRuns","decode","found","decodeLumaRow","decodeImageData","image","options","height","rows","band","centre","spread","order","step","ceil","y","offset","x","pixel"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;;;;CAkBC,GAcD,wDAAwD,GACxD,OAAO,SAASA,QAAQC,IAAwB;IAC9C,MAAMC,OAAc,EAAE;IACtB,IAAK,IAAIC,QAAQ,GAAGA,QAAQF,KAAKG,MAAM,EAAED,SAAS,EAAG;QACnD,MAAME,QAAQC,QAAQL,IAAI,CAACE,MAAM;QACjC,MAAMI,OAAOL,IAAI,CAACA,KAAKE,MAAM,GAAG,EAAE;QAClC,IAAIG,QAAQA,KAAKN,IAAI,KAAKI,OAAOE,KAAKC,KAAK,IAAI;aAC1CN,KAAKO,IAAI,CAAC;YAAER,MAAMI;YAAOG,OAAO;QAAE;IACzC;IACA,OAAON;AACT;AAEA;;;;CAIC,GACD,OAAO,SAASQ,YAAYC,IAAuB;IACjD,MAAMP,SAASO,KAAKP,MAAM;IAC1B,IAAIA,SAAS,IAAI,OAAO;IACxB,IAAIQ,MAAMC;IACV,IAAIC,MAAM,CAACD;IACX,MAAME,SAAS,IAAIC,aAAaZ;IAChC,IAAK,IAAID,QAAQ,GAAGA,QAAQC,QAAQD,SAAS,EAAG;QAC9C,MAAME,QACJ,AAACY,CAAAA,OAAON,IAAI,CAACO,KAAKJ,GAAG,CAAC,GAAGX,QAAQ,GAAG,IAAI,IAAIc,OAAON,IAAI,CAACR,MAAM,IAAIc,OAAON,IAAI,CAACO,KAAKN,GAAG,CAACR,SAAS,GAAGD,QAAQ,GAAG,CAAA,IAAK;QACrHY,MAAM,CAACZ,MAAM,GAAGE;QAChB,IAAIA,QAAQO,KAAKA,MAAMP;QACvB,IAAIA,QAAQS,KAAKA,MAAMT;IACzB;IACA,IAAIS,MAAMF,MAAM,IAAI,OAAO;IAC3B,MAAMO,OAAOD,KAAKJ,GAAG,CAAC,GAAGI,KAAKE,KAAK,CAAChB,SAAS;IAC7C,MAAMiB,SAAS,IAAIC,aAAalB,SAAS;IACzC,IAAK,IAAID,QAAQ,GAAGA,QAAQC,QAAQD,SAAS,EAAGkB,MAAM,CAAClB,QAAQ,EAAE,GAAGkB,MAAM,CAAClB,MAAM,GAAGY,MAAM,CAACZ,MAAM;IACjG,MAAMoB,YAAY,AAACX,CAAAA,MAAME,GAAE,IAAK;IAChC,MAAMU,MAAiB,IAAIC,MAAMrB;IACjC,IAAK,IAAID,QAAQ,GAAGA,QAAQC,QAAQD,SAAS,EAAG;QAC9C,MAAMuB,OAAOR,KAAKJ,GAAG,CAAC,GAAGX,QAAQgB;QACjC,MAAMQ,KAAKT,KAAKN,GAAG,CAACR,QAAQD,QAAQgB,OAAO;QAC3C,MAAMS,QAAQ,AAACP,CAAAA,MAAM,CAACM,GAAG,GAAGN,MAAM,CAACK,KAAK,AAAD,IAAMC,CAAAA,KAAKD,IAAG;QACrD,uEAAuE;QACvE,+CAA+C;QAC/C,MAAMG,YAAY,MAAMD,QAAQ,MAAML;QACtCC,GAAG,CAACrB,MAAM,GAAGY,MAAM,CAACZ,MAAM,GAAG0B;IAC/B;IACA,OAAOL;AACT;AAEA,uFAAuF,GACvF,SAASM,aAAaC,MAAyB,EAAEC,OAA0B,EAAEC,OAAe;IAC1F,MAAMC,QAAQH,OAAOI,MAAM,CAAC,CAACC,KAAK5B,QAAU4B,MAAM5B,OAAO;IACzD,IAAI,CAAC0B,OAAO,OAAOrB;IACnB,MAAMwB,QAAQJ,UAAUC;IACxB,IAAII,QAAQ;IACZ,IAAK,IAAInC,QAAQ,GAAGA,QAAQ6B,QAAQ5B,MAAM,EAAED,SAAS,EAAG;QACtDmC,SAASpB,KAAKqB,GAAG,CAACR,MAAM,CAAC5B,MAAM,GAAGkC,QAAQL,OAAO,CAAC7B,MAAM;IAC1D;IACA,OAAOmC;AACT;AAEA,SAASE,UACPT,MAAyB,EACzBU,QAAwC,EACxCR,OAAe,EACfS,QAAgB;IAEhB,IAAIC,OAAO,CAAC;IACZ,IAAIC,YAAYF;IAChB,IAAK,IAAIvC,QAAQ,GAAGA,QAAQsC,SAASrC,MAAM,EAAED,SAAS,EAAG;QACvD,MAAMmC,QAAQR,aAAaC,QAAQU,QAAQ,CAACtC,MAAM,EAAE8B;QACpD,IAAIK,QAAQM,WAAW;YACrBA,YAAYN;YACZK,OAAOxC;QACT;IACF;IACA,OAAOwC;AACT;AAEA,MAAME,SAAS,CAACC,OAAiBA,KAAKC,KAAK,CAAC,IAAIC,GAAG,CAAC/B;AAEpD;;2CAE2C,GAE3C,2EAA2E,GAC3E,MAAMgC,QAAQ;IAAC;IAAQ;IAAQ;IAAQ;IAAQ;IAAQ;IAAQ;IAAQ;IAAQ;IAAQ;CAAO,CAACD,GAAG,CAACH;AACnG,mCAAmC,GACnC,MAAMK,QAAQD,MAAMD,GAAG,CAAC,CAAChB,UAAY;WAAIA;KAAQ,CAACmB,OAAO;AACzD,0DAA0D,GAC1D,MAAMC,yBAAyB;IAC7B;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;CAC3F;AAED,OAAO,SAASC,mBAAmBC,IAAY;IAC7C,IAAI,CAAC,QAAQC,IAAI,CAACD,OAAO,OAAO;IAChC,MAAME,OAAOF,KAAKG,KAAK,CAAC,GAAG,CAAC;IAC5B,IAAIrB,MAAM;IACV,IAAK,IAAIjC,QAAQ,GAAGA,QAAQqD,KAAKpD,MAAM,EAAED,SAAS,EAAG;QACnD,+DAA+D;QAC/D,MAAMuD,YAAYF,KAAKpD,MAAM,GAAG,IAAID;QACpCiC,OAAOnB,OAAOuC,IAAI,CAACrD,MAAM,IAAKuD,CAAAA,YAAY,MAAM,IAAI,IAAI,CAAA;IAC1D;IACA,OAAO,AAAC,CAAA,KAAMtB,MAAM,EAAE,IAAK,OAAOnB,OAAOqC,IAAI,CAACA,KAAKlD,MAAM,GAAG,EAAE;AAChE;AAEA,MAAMuD,QAAQ;IAAC;IAAG;IAAG;CAAE;AACvB,MAAMC,SAAS;IAAC;IAAG;IAAG;IAAG;IAAG;CAAE;AAE9B,SAASC,SAAS3D,IAAW,EAAE4D,KAAa,EAAEC,KAAa;IACzD,IAAID,QAAQC,QAAQ7D,KAAKE,MAAM,EAAE,OAAO;IACxC,OAAOF,KAAKuD,KAAK,CAACK,OAAOA,QAAQC,OAAOf,GAAG,CAAC,CAACgB,MAAQA,IAAIxD,KAAK;AAChE;AAEA,SAASyD,QAAQ/D,IAAW,EAAE4D,KAAa,EAAEC,KAAa,EAAEG,WAAmB;IAC7E,MAAMnC,SAAS8B,SAAS3D,MAAM4D,OAAOC;IACrC,IAAI,CAAChC,QAAQ,OAAO;IACpB,OAAOA,OAAOoC,KAAK,CAAC,CAAC3D,QAAUA,QAAQ0D,cAAc,QAAQ1D,QAAQ0D,cAAc;AACrF;AAEA,SAASE,YAAYlE,IAAW,EAAE4D,KAAa,EAAEI,WAAmB;IAClE,OAAOJ,UAAU,KAAK5D,IAAI,CAAC4D,QAAQ,EAAE,CAACtD,KAAK,IAAI0D,cAAc;AAC/D;AAEA,SAASG,gBACPnE,IAAW,EACX4D,KAAa,EACbC,KAAa,EACbO,QAAiB;IAEjB,MAAM9C,MAAgB,EAAE;IACxB,IAAI+C,SAAS;IACb,IAAK,IAAIpE,QAAQ,GAAGA,QAAQ4D,OAAO5D,SAAS,EAAG;QAC7C,MAAM4B,SAAS8B,SAAS3D,MAAM4D,QAAQ3D,QAAQ,GAAG;QACjD,IAAI,CAAC4B,QAAQ,OAAO;QACpB,IAAIuC,UAAU;YACZ,MAAME,IAAIhC,UAAUT,QAAQkB,OAAO,GAAG;YACtC,MAAMwB,IAAIjC,UAAUT,QAAQmB,OAAO,GAAG;YACtC,MAAMwB,SAASF,IAAI,IAAI3D,WAAWiB,aAAaC,QAAQkB,KAAK,CAACuB,EAAE,EAAE;YACjE,MAAMG,SAASF,IAAI,IAAI5D,WAAWiB,aAAaC,QAAQmB,KAAK,CAACuB,EAAE,EAAE;YACjE,IAAID,IAAI,KAAKC,IAAI,GAAG,OAAO;YAC3B,IAAIC,UAAUC,QAAQ;gBACpBnD,IAAIf,IAAI,CAAC+D;gBACTD,UAAU;YACZ,OAAO;gBACL/C,IAAIf,IAAI,CAACgE;gBACTF,UAAU;YACZ;QACF,OAAO;YACL,MAAMK,IAAIpC,UAAUT,QAAQkB,OAAO,GAAG;YACtC,IAAI2B,IAAI,GAAG,OAAO;YAClBpD,IAAIf,IAAI,CAACmE;QACX;IACF;IACA,OAAO;QAAE/B,QAAQrB;QAAK+C;IAAO;AAC/B;AAEA,SAASM,cAAc3E,IAAW,EAAE4D,KAAa;IAC/C,IAAIA,QAAQ,KAAK5D,KAAKE,MAAM,IAAI,CAACF,IAAI,CAAC4D,MAAM,CAAC7D,IAAI,EAAE,OAAO;IAC1D,MAAMiC,QAAQhC,KAAKuD,KAAK,CAACK,OAAOA,QAAQ,IAAI3B,MAAM,CAAC,CAACC,KAAK4B,MAAQ5B,MAAM4B,IAAIxD,KAAK,EAAE;IAClF,MAAM0D,cAAchC,QAAQ;IAC5B,IAAI,CAACkC,YAAYlE,MAAM4D,OAAOI,cAAc,OAAO;IACnD,IAAI,CAACD,QAAQ/D,MAAM4D,OAAO,GAAGI,gBAAgB,CAACD,QAAQ/D,MAAM4D,QAAQ,IAAI,GAAGI,gBAAgB,CAACD,QAAQ/D,MAAM4D,QAAQ,IAAI,GAAGI,cAAc;QACrI,OAAO;IACT;IACA,IAAIpC,aAAa+B,SAAS3D,MAAM4D,OAAO,IAAKH,OAAO,KAAK,KAAK,OAAO;IACpE,IAAI7B,aAAa+B,SAAS3D,MAAM4D,QAAQ,IAAI,IAAKF,QAAQ,KAAK,KAAK,OAAO;IAC1E,MAAMkB,OAAOT,gBAAgBnE,MAAM4D,QAAQ,GAAG,GAAG;IACjD,MAAMiB,QAAQV,gBAAgBnE,MAAM4D,QAAQ,IAAI,GAAG;IACnD,IAAI,CAACgB,QAAQ,CAACC,OAAO,OAAO;IAC5B,MAAMC,QAAQ5B,uBAAuB6B,OAAO,CAACH,KAAKP,MAAM;IACxD,IAAIS,QAAQ,GAAG,OAAO;IACtB,MAAM1B,OAAO;QAAC0B;WAAUF,KAAKjC,MAAM;WAAKkC,MAAMlC,MAAM;KAAC,CAACqC,IAAI,CAAC;IAC3D,IAAI,CAAC7B,mBAAmBC,OAAO,OAAO;IACtC,0EAA0E;IAC1E,mEAAmE;IACnE,OAAOA,KAAK6B,UAAU,CAAC,OAAO;QAAEC,QAAQ;QAASC,MAAM/B,KAAKG,KAAK,CAAC;IAAG,IAAI;QAAE2B,QAAQ;QAAUC,MAAM/B;IAAK;AAC1G;AAEA,SAASgC,aAAapF,IAAW,EAAE4D,KAAa;IAC9C,IAAIA,QAAQ,KAAK5D,KAAKE,MAAM,IAAI,CAACF,IAAI,CAAC4D,MAAM,CAAC7D,IAAI,EAAE,OAAO;IAC1D,MAAMiC,QAAQhC,KAAKuD,KAAK,CAACK,OAAOA,QAAQ,IAAI3B,MAAM,CAAC,CAACC,KAAK4B,MAAQ5B,MAAM4B,IAAIxD,KAAK,EAAE;IAClF,MAAM0D,cAAchC,QAAQ;IAC5B,IAAI,CAACkC,YAAYlE,MAAM4D,OAAOI,cAAc,OAAO;IACnD,IAAI,CAACD,QAAQ/D,MAAM4D,OAAO,GAAGI,gBAAgB,CAACD,QAAQ/D,MAAM4D,QAAQ,IAAI,GAAGI,gBAAgB,CAACD,QAAQ/D,MAAM4D,QAAQ,IAAI,GAAGI,cAAc;QACrI,OAAO;IACT;IACA,MAAMY,OAAOT,gBAAgBnE,MAAM4D,QAAQ,GAAG,GAAG;IACjD,MAAMiB,QAAQV,gBAAgBnE,MAAM4D,QAAQ,IAAI,GAAG;IACnD,IAAI,CAACgB,QAAQ,CAACC,SAASD,KAAKP,MAAM,KAAK,QAAQ,OAAO;IACtD,MAAMjB,OAAO;WAAIwB,KAAKjC,MAAM;WAAKkC,MAAMlC,MAAM;KAAC,CAACqC,IAAI,CAAC;IACpD,OAAO7B,mBAAmBC,QAAQ;QAAE8B,QAAQ;QAASC,MAAM/B;IAAK,IAAI;AACtE;AAEA;;2CAE2C,GAE3C,yFAAyF,GACzF,OAAO,MAAMiC,mBAAmD;IAC9D;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;IAC1F;IAAU;IAAU;IAAU;IAAU;IAAU;IAAU;CAC7D,CAACvC,GAAG,CAACH,QAAO;AAEb,MAAM2C,eAAeD,iBAAiB9B,KAAK,CAAC,GAAG;AAC/C,MAAMgC,UAAU;AAChB,MAAMC,UAAU;AAChB,MAAMC,UAAU;AAChB,MAAMC,OAAOL,gBAAgB,CAAC,IAAI;AAElC,SAASM,gBAAgB3F,IAAW,EAAE4D,KAAa;QAC5C5D;IAAL,IAAI,GAACA,cAAAA,IAAI,CAAC4D,MAAM,qBAAX5D,YAAaD,IAAI,GAAE,OAAO;IAC/B,MAAM6F,cAAcjC,SAAS3D,MAAM4D,OAAO;IAC1C,IAAI,CAACgC,aAAa,OAAO;IACzB,MAAMC,aAAavD,UAAUsD,aAAaN,cAAc,IAAI;IAC5D,IAAIO,aAAaN,SAAS,OAAO;IACjC,MAAMvB,cAAc4B,YAAY3D,MAAM,CAAC,CAACC,KAAK5B,QAAU4B,MAAM5B,OAAO,KAAK;IACzE,IAAI,CAAC4D,YAAYlE,MAAM4D,OAAOI,cAAc,OAAO;IACnD,MAAM8B,SAAmB;QAACD;KAAW;IACrC,IAAIE,KAAKnC,QAAQ;IACjB,IAAK,IAAIoC,QAAQ,GAAGA,QAAQ,IAAIA,SAAS,EAAG;QAC1C,MAAMnE,SAAS8B,SAAS3D,MAAM+F,IAAI;QAClC,MAAM5F,QAAQ0B,SAASS,UAAUT,QAAQyD,cAAc,IAAI,OAAO,CAAC;QACnE,MAAMW,YAAY9F,SAAS,KAAK0B,SAASD,aAAaC,QAAQyD,YAAY,CAACnF,MAAM,EAAE,MAAMQ;QACzF,wEAAwE;QACxE,wEAAwE;QACxE,0DAA0D;QAC1D,MAAMuF,OAAOvC,SAAS3D,MAAM+F,IAAI;QAChC,IAAIG,MAAM;YACR,MAAMC,YAAYvE,aAAasE,MAAMR,MAAM;YAC3C,MAAMU,aAAaF,KAAKjE,MAAM,CAAC,CAACC,KAAK5B,QAAU4B,MAAM5B,OAAO,KAAK;YACjE,MAAM+F,QAAQrG,IAAI,CAAC+F,KAAK,EAAE;YAC1B,MAAMO,aAAa,CAACD,SAASA,MAAM/F,KAAK,IAAI0D,cAAc;YAC1D,IAAImC,YAAY,OAAOA,YAAYF,aAAaK,YAAY;gBAC1D,IAAItF,KAAKqB,GAAG,CAAC+D,aAAapC,eAAeA,cAAc,KAAK,OAAO;gBACnE,OAAOuC,cAAcT;YACvB;QACF;QACA,IAAI,CAACjE,UAAU1B,QAAQ,KAAKA,SAASoF,SAAS,OAAO;QACrD,MAAMiB,eAAe3E,OAAOI,MAAM,CAAC,CAACC,KAAK5B,QAAU4B,MAAM5B,OAAO,KAAK;QACrE,IAAIU,KAAKqB,GAAG,CAACmE,eAAexC,eAAeA,cAAc,KAAK,OAAO;QACrE8B,OAAOvF,IAAI,CAACJ;QACZ4F,MAAM;IACR;IACA,OAAO;AACT;AAEA,SAASQ,cAAcT,MAAgB;IACrC,IAAIA,OAAO5F,MAAM,GAAG,GAAG,OAAO;IAC9B,MAAMuG,QAAQX,MAAM,CAACA,OAAO5F,MAAM,GAAG,EAAE;IACvC,MAAMwG,OAAOZ,OAAOvC,KAAK,CAAC,GAAG,CAAC;IAC9B,IAAIrB,MAAM4D,MAAM,CAAC,EAAE;IACnBY,KAAKC,OAAO,CAAC,CAACxG,OAAOF;QACnBiC,OAAO/B,QAASF,CAAAA,QAAQ,CAAA;IAC1B;IACA,IAAIiC,MAAM,QAAQuE,OAAO,OAAO;IAChC,IAAIG,MAAuBd,MAAM,CAAC,EAAE,KAAKP,UAAU,MAAMO,MAAM,CAAC,EAAE,KAAKN,UAAU,MAAM;IACvF,IAAIqB,QAAQ;IACZ,IAAI1B,OAAO;IACX,KAAK,MAAMhF,SAASuG,KAAM;QACxB,MAAMI,UAA2BD,QAASD,QAAQ,MAAM,MAAM,MAAOA;QACrEC,QAAQ;QACR,IAAIC,YAAY,KAAK;YACnB,IAAI3G,QAAQ,KAAKgF,QAAQ4B,OAAO5G,OAAO6G,QAAQ,CAAC,GAAG;iBAC9C,IAAI7G,UAAU,KAAKyG,MAAM;iBACzB,IAAIzG,UAAU,KAAKyG,MAAM;YAE9B;QACF;QACA,IAAIzG,QAAQ,IAAI;YACd,IAAI2G,YAAY,KAAK3B,QAAQ4B,OAAOE,YAAY,CAAC9G,QAAQ;iBACpDgF,QAAQ4B,OAAOE,YAAY,CAAC9G,QAAQ,KAAKA,QAAQ,KAAKA,QAAQ;YACnE;QACF;QACA,IAAIA,UAAU,IAAI0G,QAAQ;aACrB,IAAI1G,UAAU,IAAIyG,MAAM;aACxB,IAAIzG,UAAU,OAAO2G,YAAY,KAAKF,MAAM;aAC5C,IAAIzG,UAAU,OAAO2G,YAAY,KAAKF,MAAM;IACjD,8DAA8D;IAChE;IACA,uEAAuE;IACvEzB,OAAO5D,MAAMC,IAAI,CAAC2D,MAAM+B,MAAM,CAAC,CAACC,OAASA,KAAKC,UAAU,CAAC,MAAM,MAAMpC,IAAI,CAAC;IAC1E,OAAOG,OAAO;QAAED,QAAQ;QAAYC;IAAK,IAAI;AAC/C;AAEA;;2CAE2C,GAE3C,MAAMkC,WAAW;IAAC1C;IAAeS;IAAcO;CAAgB;AAE/D,SAAS2B,WAAWtH,IAAW;IAC7B,IAAK,IAAI4D,QAAQ,GAAGA,QAAQ5D,KAAKE,MAAM,EAAE0D,SAAS,EAAG;QACnD,IAAI,CAAC5D,IAAI,CAAC4D,MAAM,CAAC7D,IAAI,EAAE;QACvB,KAAK,MAAMwH,UAAUF,SAAU;YAC7B,MAAMG,QAAQD,OAAOvH,MAAM4D;YAC3B,IAAI4D,OAAO,OAAOA;QACpB;IACF;IACA,OAAO;AACT;AAEA,2EAA2E,GAC3E,OAAO,SAASC,cAAchH,IAAuB;QAI5C6G;IAHP,MAAMvH,OAAOS,YAAYC;IACzB,IAAI,CAACV,MAAM,OAAO;IAClB,MAAMC,OAAOF,QAAQC;IACrB,QAAOuH,cAAAA,WAAWtH,iBAAXsH,cAAoBA,WAAW;WAAItH;KAAK,CAACiD,OAAO;AACzD;AAEA;;;;CAIC,GACD,OAAO,SAASyE,gBACdC,KAAiE,EACjEC,UAA4C,CAAC,CAAC;QAGjCA,eAC2BA;IAFxC,MAAM,EAAEtH,KAAK,EAAEuH,MAAM,EAAEnB,IAAI,EAAE,GAAGiB;IAChC,MAAMG,QAAOF,gBAAAA,QAAQE,IAAI,YAAZF,gBAAgB;IAC7B,MAAMG,OAAO/G,KAAKN,GAAG,CAAC,GAAGM,KAAKJ,GAAG,CAAC,OAAMgH,gBAAAA,QAAQG,IAAI,YAAZH,gBAAgB;IACxD,MAAMI,SAASH,SAAS;IACxB,MAAMI,SAAS,AAACJ,SAASE,OAAQ;IACjC,MAAMG,QAAkB,EAAE;IAC1B,IAAK,IAAIjI,QAAQ,GAAGA,QAAQ6H,MAAM7H,SAAS,EAAG;QAC5C,MAAMkI,OAAOnH,KAAKoH,IAAI,CAACnI,QAAQ,KAAMA,CAAAA,QAAQ,IAAI,CAAC,IAAI,CAAA;QACtDiI,MAAM3H,IAAI,CAACS,KAAKE,KAAK,CAAC8G,SAAS,AAACG,OAAOF,SAAUjH,KAAKoH,IAAI,CAACN,OAAO;IACpE;IACA,MAAMrH,OAAO,IAAIK,aAAaR;IAC9B,KAAK,MAAM+H,KAAKH,MAAO;QACrB,IAAIG,IAAI,KAAKA,KAAKR,QAAQ;QAC1B,MAAMS,SAASD,IAAI/H,QAAQ;QAC3B,IAAK,IAAIiI,IAAI,GAAGA,IAAIjI,OAAOiI,KAAK,EAAG;YACjC,MAAMC,QAAQF,SAASC,IAAI;YAC3B9H,IAAI,CAAC8H,EAAE,GAAG,QAAQxH,OAAO2F,IAAI,CAAC8B,MAAM,IAAI,QAAQzH,OAAO2F,IAAI,CAAC8B,QAAQ,EAAE,IAAI,QAAQzH,OAAO2F,IAAI,CAAC8B,QAAQ,EAAE;QAC1G;QACA,MAAMhB,QAAQC,cAAchH;QAC5B,IAAI+G,OAAO,OAAOA;IACpB;IACA,OAAO;AACT"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Barcodes drawn for product labels (AGL-3619), in the symbologies the
|
|
19
|
+
* register's scanners read back: a valid EAN-13, UPC-A or EAN-8 prints as
|
|
20
|
+
* itself (a retail scanner and a supplier's catalog both expect that), and
|
|
21
|
+
* anything else (a SKU, an internal code) prints as Code 128.
|
|
22
|
+
*
|
|
23
|
+
* The output is a string of modules, `1` for a bar and `0` for a space, so
|
|
24
|
+
* the same encoding draws an SVG for the browser and is checked against the
|
|
25
|
+
* decoder in tests.
|
|
26
|
+
*/
|
|
27
|
+
export type EncodedFormat = 'ean_13' | 'upc_a' | 'ean_8' | 'code_128';
|
|
28
|
+
export interface EncodedBarcode {
|
|
29
|
+
format: EncodedFormat;
|
|
30
|
+
/** The text the barcode carries (and is printed under it). */
|
|
31
|
+
text: string;
|
|
32
|
+
modules: string;
|
|
33
|
+
}
|
|
34
|
+
/** Code 128 set B carries printable ASCII; labels cap the code where a 2-inch label still scans. */
|
|
35
|
+
export declare const LABEL_CODE_MAX_LENGTH = 24;
|
|
36
|
+
/** The barcode a value prints as, or null when it has nothing printable. */
|
|
37
|
+
export declare function encodeBarcode(raw: unknown): EncodedBarcode | null;
|
|
38
|
+
/**
|
|
39
|
+
* The barcode as an SVG, one unit per module plus the ten-module quiet zone a
|
|
40
|
+
* scanner needs either side. It scales to whatever width the label gives it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function barcodeSvg(encoded: EncodedBarcode, options?: {
|
|
43
|
+
height?: number;
|
|
44
|
+
}): string;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { CODE128_PATTERNS, eanCheckDigitValid } from "./barcode-decode.js";
|
|
17
|
+
const EAN_L = [
|
|
18
|
+
'0001101',
|
|
19
|
+
'0011001',
|
|
20
|
+
'0010011',
|
|
21
|
+
'0111101',
|
|
22
|
+
'0100011',
|
|
23
|
+
'0110001',
|
|
24
|
+
'0101111',
|
|
25
|
+
'0111011',
|
|
26
|
+
'0110111',
|
|
27
|
+
'0001011'
|
|
28
|
+
];
|
|
29
|
+
const EAN_G = EAN_L.map((code)=>[
|
|
30
|
+
...code
|
|
31
|
+
].map((bit)=>bit === '1' ? '0' : '1').reverse().join(''));
|
|
32
|
+
const EAN_R = EAN_L.map((code)=>[
|
|
33
|
+
...code
|
|
34
|
+
].map((bit)=>bit === '1' ? '0' : '1').join(''));
|
|
35
|
+
const EAN_PARITY = [
|
|
36
|
+
'LLLLLL',
|
|
37
|
+
'LLGLGG',
|
|
38
|
+
'LLGGLG',
|
|
39
|
+
'LLGGGL',
|
|
40
|
+
'LGLLGG',
|
|
41
|
+
'LGGLLG',
|
|
42
|
+
'LGGGLL',
|
|
43
|
+
'LGLGLG',
|
|
44
|
+
'LGLGGL',
|
|
45
|
+
'LGGLGL'
|
|
46
|
+
];
|
|
47
|
+
function ean13(code) {
|
|
48
|
+
const parity = EAN_PARITY[Number(code[0])];
|
|
49
|
+
let out = '101';
|
|
50
|
+
for(let index = 1; index <= 6; index += 1){
|
|
51
|
+
out += (parity[index - 1] === 'L' ? EAN_L : EAN_G)[Number(code[index])];
|
|
52
|
+
}
|
|
53
|
+
out += '01010';
|
|
54
|
+
for(let index = 7; index <= 12; index += 1)out += EAN_R[Number(code[index])];
|
|
55
|
+
return `${out}101`;
|
|
56
|
+
}
|
|
57
|
+
function ean8(code) {
|
|
58
|
+
let out = '101';
|
|
59
|
+
for(let index = 0; index < 4; index += 1)out += EAN_L[Number(code[index])];
|
|
60
|
+
out += '01010';
|
|
61
|
+
for(let index = 4; index < 8; index += 1)out += EAN_R[Number(code[index])];
|
|
62
|
+
return `${out}101`;
|
|
63
|
+
}
|
|
64
|
+
const widthsToModules = (widths)=>widths.map((width, index)=>(index % 2 ? '0' : '1').repeat(width)).join('');
|
|
65
|
+
/** Code 128: set C for an even run of digits (half as wide), set B otherwise. */ function code128(text) {
|
|
66
|
+
const numeric = /^\d+$/.test(text) && text.length % 2 === 0 && text.length >= 4;
|
|
67
|
+
const values = numeric ? [
|
|
68
|
+
105
|
|
69
|
+
] : [
|
|
70
|
+
104
|
|
71
|
+
];
|
|
72
|
+
if (numeric) {
|
|
73
|
+
for(let index = 0; index < text.length; index += 2)values.push(Number(text.slice(index, index + 2)));
|
|
74
|
+
} else {
|
|
75
|
+
for (const char of text)values.push(char.charCodeAt(0) - 32);
|
|
76
|
+
}
|
|
77
|
+
const checksum = values.reduce((sum, value, index)=>sum + value * Math.max(1, index), 0) % 103;
|
|
78
|
+
values.push(checksum, 106);
|
|
79
|
+
return values.map((value)=>widthsToModules(CODE128_PATTERNS[value])).join('');
|
|
80
|
+
}
|
|
81
|
+
/** Code 128 set B carries printable ASCII; labels cap the code where a 2-inch label still scans. */ export const LABEL_CODE_MAX_LENGTH = 24;
|
|
82
|
+
/** The barcode a value prints as, or null when it has nothing printable. */ export function encodeBarcode(raw) {
|
|
83
|
+
const value = String(raw != null ? raw : '').trim();
|
|
84
|
+
if (!value) return null;
|
|
85
|
+
if (/^\d{13}$/.test(value) && eanCheckDigitValid(value)) {
|
|
86
|
+
return {
|
|
87
|
+
format: 'ean_13',
|
|
88
|
+
text: value,
|
|
89
|
+
modules: ean13(value)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (/^\d{12}$/.test(value) && eanCheckDigitValid(value)) {
|
|
93
|
+
// UPC-A is EAN-13 with a leading zero; the bars are identical.
|
|
94
|
+
return {
|
|
95
|
+
format: 'upc_a',
|
|
96
|
+
text: value,
|
|
97
|
+
modules: ean13(`0${value}`)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (/^\d{8}$/.test(value) && eanCheckDigitValid(value)) {
|
|
101
|
+
return {
|
|
102
|
+
format: 'ean_8',
|
|
103
|
+
text: value,
|
|
104
|
+
modules: ean8(value)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const printable = value.replace(/[^\x20-\x7e]/g, '').slice(0, LABEL_CODE_MAX_LENGTH);
|
|
108
|
+
if (!printable) return null;
|
|
109
|
+
return {
|
|
110
|
+
format: 'code_128',
|
|
111
|
+
text: printable,
|
|
112
|
+
modules: code128(printable)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The barcode as an SVG, one unit per module plus the ten-module quiet zone a
|
|
117
|
+
* scanner needs either side. It scales to whatever width the label gives it.
|
|
118
|
+
*/ export function barcodeSvg(encoded, options = {}) {
|
|
119
|
+
var _options_height;
|
|
120
|
+
const quiet = 10;
|
|
121
|
+
const height = (_options_height = options.height) != null ? _options_height : 50;
|
|
122
|
+
const width = encoded.modules.length + quiet * 2;
|
|
123
|
+
let path = '';
|
|
124
|
+
let index = 0;
|
|
125
|
+
while(index < encoded.modules.length){
|
|
126
|
+
if (encoded.modules[index] !== '1') {
|
|
127
|
+
index += 1;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
let run = 1;
|
|
131
|
+
while(encoded.modules[index + run] === '1')run += 1;
|
|
132
|
+
path += `M${index + quiet} 0h${run}v${height}h-${run}z`;
|
|
133
|
+
index += run;
|
|
134
|
+
}
|
|
135
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" ` + `preserveAspectRatio="none" shape-rendering="crispEdges"><path d="${path}" fill="currentColor"/></svg>`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=barcode-encode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/barcode/barcode-encode.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CODE128_PATTERNS, eanCheckDigitValid } from './barcode-decode'\n\n/**\n * Barcodes drawn for product labels (AGL-3619), in the symbologies the\n * register's scanners read back: a valid EAN-13, UPC-A or EAN-8 prints as\n * itself (a retail scanner and a supplier's catalog both expect that), and\n * anything else (a SKU, an internal code) prints as Code 128.\n *\n * The output is a string of modules, `1` for a bar and `0` for a space, so\n * the same encoding draws an SVG for the browser and is checked against the\n * decoder in tests.\n */\n\nexport type EncodedFormat = 'ean_13' | 'upc_a' | 'ean_8' | 'code_128'\n\nexport interface EncodedBarcode {\n format: EncodedFormat\n /** The text the barcode carries (and is printed under it). */\n text: string\n modules: string\n}\n\nconst EAN_L = ['0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011']\nconst EAN_G = EAN_L.map((code) => [...code].map((bit) => (bit === '1' ? '0' : '1')).reverse().join(''))\nconst EAN_R = EAN_L.map((code) => [...code].map((bit) => (bit === '1' ? '0' : '1')).join(''))\nconst EAN_PARITY = ['LLLLLL', 'LLGLGG', 'LLGGLG', 'LLGGGL', 'LGLLGG', 'LGGLLG', 'LGGGLL', 'LGLGLG', 'LGLGGL', 'LGGLGL']\n\nfunction ean13(code: string): string {\n const parity = EAN_PARITY[Number(code[0])]\n let out = '101'\n for (let index = 1; index <= 6; index += 1) {\n out += (parity[index - 1] === 'L' ? EAN_L : EAN_G)[Number(code[index])]\n }\n out += '01010'\n for (let index = 7; index <= 12; index += 1) out += EAN_R[Number(code[index])]\n return `${out}101`\n}\n\nfunction ean8(code: string): string {\n let out = '101'\n for (let index = 0; index < 4; index += 1) out += EAN_L[Number(code[index])]\n out += '01010'\n for (let index = 4; index < 8; index += 1) out += EAN_R[Number(code[index])]\n return `${out}101`\n}\n\nconst widthsToModules = (widths: readonly number[]) =>\n widths.map((width, index) => (index % 2 ? '0' : '1').repeat(width)).join('')\n\n/** Code 128: set C for an even run of digits (half as wide), set B otherwise. */\nfunction code128(text: string): string {\n const numeric = /^\\d+$/.test(text) && text.length % 2 === 0 && text.length >= 4\n const values = numeric ? [105] : [104]\n if (numeric) {\n for (let index = 0; index < text.length; index += 2) values.push(Number(text.slice(index, index + 2)))\n } else {\n for (const char of text) values.push(char.charCodeAt(0) - 32)\n }\n const checksum = values.reduce((sum, value, index) => sum + value * Math.max(1, index), 0) % 103\n values.push(checksum, 106)\n return values.map((value) => widthsToModules(CODE128_PATTERNS[value])).join('')\n}\n\n/** Code 128 set B carries printable ASCII; labels cap the code where a 2-inch label still scans. */\nexport const LABEL_CODE_MAX_LENGTH = 24\n\n/** The barcode a value prints as, or null when it has nothing printable. */\nexport function encodeBarcode(raw: unknown): EncodedBarcode | null {\n const value = String(raw ?? '').trim()\n if (!value) return null\n if (/^\\d{13}$/.test(value) && eanCheckDigitValid(value)) {\n return { format: 'ean_13', text: value, modules: ean13(value) }\n }\n if (/^\\d{12}$/.test(value) && eanCheckDigitValid(value)) {\n // UPC-A is EAN-13 with a leading zero; the bars are identical.\n return { format: 'upc_a', text: value, modules: ean13(`0${value}`) }\n }\n if (/^\\d{8}$/.test(value) && eanCheckDigitValid(value)) {\n return { format: 'ean_8', text: value, modules: ean8(value) }\n }\n const printable = value.replace(/[^\\x20-\\x7e]/g, '').slice(0, LABEL_CODE_MAX_LENGTH)\n if (!printable) return null\n return { format: 'code_128', text: printable, modules: code128(printable) }\n}\n\n/**\n * The barcode as an SVG, one unit per module plus the ten-module quiet zone a\n * scanner needs either side. It scales to whatever width the label gives it.\n */\nexport function barcodeSvg(encoded: EncodedBarcode, options: { height?: number } = {}): string {\n const quiet = 10\n const height = options.height ?? 50\n const width = encoded.modules.length + quiet * 2\n let path = ''\n let index = 0\n while (index < encoded.modules.length) {\n if (encoded.modules[index] !== '1') {\n index += 1\n continue\n }\n let run = 1\n while (encoded.modules[index + run] === '1') run += 1\n path += `M${index + quiet} 0h${run}v${height}h-${run}z`\n index += run\n }\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" ` +\n `preserveAspectRatio=\"none\" shape-rendering=\"crispEdges\"><path d=\"${path}\" fill=\"currentColor\"/></svg>`\n )\n}\n"],"names":["CODE128_PATTERNS","eanCheckDigitValid","EAN_L","EAN_G","map","code","bit","reverse","join","EAN_R","EAN_PARITY","ean13","parity","Number","out","index","ean8","widthsToModules","widths","width","repeat","code128","text","numeric","test","length","values","push","slice","char","charCodeAt","checksum","reduce","sum","value","Math","max","LABEL_CODE_MAX_LENGTH","encodeBarcode","raw","String","trim","format","modules","printable","replace","barcodeSvg","encoded","options","quiet","height","path","run"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera barcode scanning (AGL-3619), for a register on a tablet or phone
|
|
3
|
+
* and for the product editor's barcode field.
|
|
4
|
+
*
|
|
5
|
+
* The browser's own `BarcodeDetector` reads the frames where it exists
|
|
6
|
+
* (Chrome on Android and macOS); elsewhere — Safari on the iPad, Chrome on
|
|
7
|
+
* Windows — the small reader in `barcode-decode.ts` does, loaded only when
|
|
8
|
+
* the scanner first opens there. Either way the result is the TEXT a USB or
|
|
9
|
+
* Bluetooth scanner would have typed, handed to the same lookup.
|
|
10
|
+
*/
|
|
11
|
+
export interface BarcodeScannerProps {
|
|
12
|
+
open: boolean;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
onDetected: (code: string, format: string) => void;
|
|
15
|
+
title?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Why the camera could not start, in words a cashier can act on. */
|
|
18
|
+
export declare function cameraErrorMessage(error: unknown): string;
|
|
19
|
+
export declare function BarcodeScanner(props: BarcodeScannerProps): import("react").JSX.Element;
|
|
20
|
+
export declare namespace BarcodeScanner {
|
|
21
|
+
var displayName: string;
|
|
22
|
+
}
|
|
23
|
+
export default BarcodeScanner;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography, useMediaQuery, useTheme } from "@mui/material";
|
|
19
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
20
|
+
/** Formats a counter scans; the native detector is asked for these and no others. */ const NATIVE_FORMATS = [
|
|
21
|
+
'ean_13',
|
|
22
|
+
'ean_8',
|
|
23
|
+
'upc_a',
|
|
24
|
+
'upc_e',
|
|
25
|
+
'code_128',
|
|
26
|
+
'code_39',
|
|
27
|
+
'qr_code'
|
|
28
|
+
];
|
|
29
|
+
/** Frames read per second: enough to feel instant, little enough to leave a tablet cool. */ const FRAME_INTERVAL_MS = 120;
|
|
30
|
+
/** The fallback reader confirms a code by reading it twice within this window. */ const CONFIRM_WITHIN_MS = 1500;
|
|
31
|
+
async function nativeReader() {
|
|
32
|
+
const Detector = globalThis.BarcodeDetector;
|
|
33
|
+
if (typeof Detector !== 'function') return null;
|
|
34
|
+
try {
|
|
35
|
+
var _ref;
|
|
36
|
+
const supported = (_ref = await (Detector.getSupportedFormats == null ? void 0 : Detector.getSupportedFormats.call(Detector))) != null ? _ref : [];
|
|
37
|
+
const formats = NATIVE_FORMATS.filter((format)=>supported.includes(format));
|
|
38
|
+
if (!formats.length) return null;
|
|
39
|
+
const detector = new Detector({
|
|
40
|
+
formats
|
|
41
|
+
});
|
|
42
|
+
return async (video)=>{
|
|
43
|
+
const [found] = await detector.detect(video);
|
|
44
|
+
return (found == null ? void 0 : found.rawValue) ? {
|
|
45
|
+
format: found.format,
|
|
46
|
+
text: found.rawValue
|
|
47
|
+
} : null;
|
|
48
|
+
};
|
|
49
|
+
} catch (unused) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function fallbackReader() {
|
|
54
|
+
const { decodeImageData } = await import("./barcode-decode.js");
|
|
55
|
+
const canvas = document.createElement('canvas');
|
|
56
|
+
const context = canvas.getContext('2d', {
|
|
57
|
+
willReadFrequently: true
|
|
58
|
+
});
|
|
59
|
+
return async (video)=>{
|
|
60
|
+
if (!context || !video.videoWidth) return null;
|
|
61
|
+
// A 1D reader needs width, not height: a wide, short strip through the
|
|
62
|
+
// guide is enough, and a smaller canvas is a faster read.
|
|
63
|
+
const width = Math.min(1280, video.videoWidth);
|
|
64
|
+
const height = Math.round(video.videoHeight * width / video.videoWidth);
|
|
65
|
+
const strip = Math.round(height * 0.4);
|
|
66
|
+
canvas.width = width;
|
|
67
|
+
canvas.height = strip;
|
|
68
|
+
context.drawImage(video, 0, (video.videoHeight - strip * video.videoWidth / width) / 2, video.videoWidth, strip * video.videoWidth / width, 0, 0, width, strip);
|
|
69
|
+
return decodeImageData(context.getImageData(0, 0, width, strip), {
|
|
70
|
+
rows: 11,
|
|
71
|
+
band: 0.9
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Why the camera could not start, in words a cashier can act on. */ export function cameraErrorMessage(error) {
|
|
76
|
+
var _ref;
|
|
77
|
+
const name = (_ref = error == null ? void 0 : error.name) != null ? _ref : '';
|
|
78
|
+
if (name === 'NotAllowedError' || name === 'SecurityError') {
|
|
79
|
+
return 'Camera access is blocked. Allow the camera for this site in the browser settings, then try again.';
|
|
80
|
+
}
|
|
81
|
+
if (name === 'NotFoundError' || name === 'OverconstrainedError') {
|
|
82
|
+
return 'No camera was found on this device. Use a USB or Bluetooth scanner, or type the code.';
|
|
83
|
+
}
|
|
84
|
+
if (name === 'NotReadableError') {
|
|
85
|
+
return 'The camera is in use by another app. Close it and try again.';
|
|
86
|
+
}
|
|
87
|
+
return 'The camera could not be started. Type the code instead.';
|
|
88
|
+
}
|
|
89
|
+
export function BarcodeScanner(props) {
|
|
90
|
+
const { open, onClose, onDetected, title } = props;
|
|
91
|
+
const theme = useTheme();
|
|
92
|
+
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
|
93
|
+
const videoRef = useRef(null);
|
|
94
|
+
const [error, setError] = useState('');
|
|
95
|
+
const [starting, setStarting] = useState(false);
|
|
96
|
+
const detectedRef = useRef(onDetected);
|
|
97
|
+
detectedRef.current = onDetected;
|
|
98
|
+
const stopRef = useRef(()=>undefined);
|
|
99
|
+
const close = useCallback(()=>{
|
|
100
|
+
stopRef.current();
|
|
101
|
+
onClose();
|
|
102
|
+
}, [
|
|
103
|
+
onClose
|
|
104
|
+
]);
|
|
105
|
+
useEffect(()=>{
|
|
106
|
+
if (!open) return;
|
|
107
|
+
let cancelled = false;
|
|
108
|
+
let stream = null;
|
|
109
|
+
let timer;
|
|
110
|
+
let lastRead = null;
|
|
111
|
+
const stop = ()=>{
|
|
112
|
+
cancelled = true;
|
|
113
|
+
if (timer) clearTimeout(timer);
|
|
114
|
+
stream == null ? void 0 : stream.getTracks().forEach((track)=>track.stop());
|
|
115
|
+
stream = null;
|
|
116
|
+
};
|
|
117
|
+
stopRef.current = stop;
|
|
118
|
+
setError('');
|
|
119
|
+
setStarting(true);
|
|
120
|
+
void (async ()=>{
|
|
121
|
+
var _navigator_mediaDevices;
|
|
122
|
+
if (!((_navigator_mediaDevices = navigator.mediaDevices) == null ? void 0 : _navigator_mediaDevices.getUserMedia)) {
|
|
123
|
+
setError('This browser cannot use the camera here. Type the code, or use a USB or Bluetooth scanner.');
|
|
124
|
+
setStarting(false);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
stream = await navigator.mediaDevices.getUserMedia({
|
|
129
|
+
video: {
|
|
130
|
+
facingMode: {
|
|
131
|
+
ideal: 'environment'
|
|
132
|
+
},
|
|
133
|
+
width: {
|
|
134
|
+
ideal: 1920
|
|
135
|
+
},
|
|
136
|
+
height: {
|
|
137
|
+
ideal: 1080
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
audio: false
|
|
141
|
+
});
|
|
142
|
+
} catch (cause) {
|
|
143
|
+
if (!cancelled) {
|
|
144
|
+
setError(cameraErrorMessage(cause));
|
|
145
|
+
setStarting(false);
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (cancelled) return stop();
|
|
150
|
+
const video = videoRef.current;
|
|
151
|
+
if (!video) return stop();
|
|
152
|
+
video.srcObject = stream;
|
|
153
|
+
video.setAttribute('playsinline', 'true');
|
|
154
|
+
await video.play().catch(()=>undefined);
|
|
155
|
+
const native = await nativeReader();
|
|
156
|
+
const read = native != null ? native : await fallbackReader();
|
|
157
|
+
const needsConfirm = !native;
|
|
158
|
+
if (cancelled) return;
|
|
159
|
+
setStarting(false);
|
|
160
|
+
const tick = async ()=>{
|
|
161
|
+
if (cancelled) return;
|
|
162
|
+
const found = await read(video).catch(()=>null);
|
|
163
|
+
if (cancelled) return;
|
|
164
|
+
if (found) {
|
|
165
|
+
const now = Date.now();
|
|
166
|
+
const confirmed = !needsConfirm || lastRead && lastRead.text === found.text && now - lastRead.atMs < CONFIRM_WITHIN_MS;
|
|
167
|
+
lastRead = {
|
|
168
|
+
text: found.text,
|
|
169
|
+
atMs: now
|
|
170
|
+
};
|
|
171
|
+
if (confirmed) {
|
|
172
|
+
navigator.vibrate == null ? void 0 : navigator.vibrate.call(navigator, 40);
|
|
173
|
+
stop();
|
|
174
|
+
detectedRef.current(found.text, found.format);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
timer = setTimeout(tick, FRAME_INTERVAL_MS);
|
|
179
|
+
};
|
|
180
|
+
void tick();
|
|
181
|
+
})();
|
|
182
|
+
return stop;
|
|
183
|
+
}, [
|
|
184
|
+
open
|
|
185
|
+
]);
|
|
186
|
+
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
187
|
+
open: open,
|
|
188
|
+
onClose: close,
|
|
189
|
+
fullScreen: fullScreen,
|
|
190
|
+
fullWidth: true,
|
|
191
|
+
maxWidth: "sm",
|
|
192
|
+
children: [
|
|
193
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
194
|
+
children: title != null ? title : 'Scan a barcode'
|
|
195
|
+
}),
|
|
196
|
+
/*#__PURE__*/ _jsxs(DialogContent, {
|
|
197
|
+
children: [
|
|
198
|
+
error ? /*#__PURE__*/ _jsx(Alert, {
|
|
199
|
+
severity: "warning",
|
|
200
|
+
children: error
|
|
201
|
+
}) : /*#__PURE__*/ _jsxs(Box, {
|
|
202
|
+
sx: {
|
|
203
|
+
position: 'relative',
|
|
204
|
+
width: '100%',
|
|
205
|
+
aspectRatio: '4 / 3',
|
|
206
|
+
bgcolor: 'common.black',
|
|
207
|
+
borderRadius: 1,
|
|
208
|
+
overflow: 'hidden'
|
|
209
|
+
},
|
|
210
|
+
children: [
|
|
211
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
212
|
+
component: "video",
|
|
213
|
+
ref: videoRef,
|
|
214
|
+
muted: true,
|
|
215
|
+
playsInline: true,
|
|
216
|
+
"aria-label": "Camera preview",
|
|
217
|
+
sx: {
|
|
218
|
+
width: '100%',
|
|
219
|
+
height: '100%',
|
|
220
|
+
objectFit: 'cover'
|
|
221
|
+
}
|
|
222
|
+
}),
|
|
223
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
224
|
+
"aria-hidden": true,
|
|
225
|
+
sx: {
|
|
226
|
+
position: 'absolute',
|
|
227
|
+
left: '8%',
|
|
228
|
+
right: '8%',
|
|
229
|
+
top: '35%',
|
|
230
|
+
bottom: '35%',
|
|
231
|
+
border: 2,
|
|
232
|
+
borderColor: 'primary.main',
|
|
233
|
+
borderRadius: 1
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
]
|
|
237
|
+
}),
|
|
238
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
239
|
+
variant: "body2",
|
|
240
|
+
color: "text.secondary",
|
|
241
|
+
sx: {
|
|
242
|
+
mt: 1
|
|
243
|
+
},
|
|
244
|
+
children: starting ? 'Starting the camera…' : 'Hold the barcode flat inside the frame, lines running up and down.'
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
}),
|
|
248
|
+
/*#__PURE__*/ _jsx(DialogActions, {
|
|
249
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
250
|
+
onClick: close,
|
|
251
|
+
children: 'Cancel'
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
]
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
BarcodeScanner.displayName = 'BarcodeScanner';
|
|
258
|
+
export default BarcodeScanner;
|
|
259
|
+
|
|
260
|
+
//# sourceMappingURL=barcode-scanner.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/barcode/barcode-scanner.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n Alert,\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Typography,\n useMediaQuery,\n useTheme,\n} from '@mui/material'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { DecodedBarcode } from './barcode-decode'\n\n/**\n * Camera barcode scanning (AGL-3619), for a register on a tablet or phone\n * and for the product editor's barcode field.\n *\n * The browser's own `BarcodeDetector` reads the frames where it exists\n * (Chrome on Android and macOS); elsewhere — Safari on the iPad, Chrome on\n * Windows — the small reader in `barcode-decode.ts` does, loaded only when\n * the scanner first opens there. Either way the result is the TEXT a USB or\n * Bluetooth scanner would have typed, handed to the same lookup.\n */\nexport interface BarcodeScannerProps {\n open: boolean\n onClose: () => void\n onDetected: (code: string, format: string) => void\n title?: string\n}\n\n/** Formats a counter scans; the native detector is asked for these and no others. */\nconst NATIVE_FORMATS = ['ean_13', 'ean_8', 'upc_a', 'upc_e', 'code_128', 'code_39', 'qr_code']\n\n/** Frames read per second: enough to feel instant, little enough to leave a tablet cool. */\nconst FRAME_INTERVAL_MS = 120\n\n/** The fallback reader confirms a code by reading it twice within this window. */\nconst CONFIRM_WITHIN_MS = 1500\n\ntype Reader = (video: HTMLVideoElement) => Promise<DecodedBarcode | null>\n\ninterface BarcodeDetectorLike {\n detect(source: CanvasImageSource): Promise<Array<{ rawValue: string; format: string }>>\n}\n\nasync function nativeReader(): Promise<Reader | null> {\n const Detector = (globalThis as any).BarcodeDetector\n if (typeof Detector !== 'function') return null\n try {\n const supported: string[] = (await Detector.getSupportedFormats?.()) ?? []\n const formats = NATIVE_FORMATS.filter((format) => supported.includes(format))\n if (!formats.length) return null\n const detector: BarcodeDetectorLike = new Detector({ formats })\n return async (video) => {\n const [found] = await detector.detect(video)\n return found?.rawValue ? { format: found.format as DecodedBarcode['format'], text: found.rawValue } : null\n }\n } catch {\n return null\n }\n}\n\nasync function fallbackReader(): Promise<Reader> {\n const { decodeImageData } = await import('./barcode-decode')\n const canvas = document.createElement('canvas')\n const context = canvas.getContext('2d', { willReadFrequently: true })\n return async (video) => {\n if (!context || !video.videoWidth) return null\n // A 1D reader needs width, not height: a wide, short strip through the\n // guide is enough, and a smaller canvas is a faster read.\n const width = Math.min(1280, video.videoWidth)\n const height = Math.round((video.videoHeight * width) / video.videoWidth)\n const strip = Math.round(height * 0.4)\n canvas.width = width\n canvas.height = strip\n context.drawImage(\n video,\n 0,\n (video.videoHeight - (strip * video.videoWidth) / width) / 2,\n video.videoWidth,\n (strip * video.videoWidth) / width,\n 0,\n 0,\n width,\n strip,\n )\n return decodeImageData(context.getImageData(0, 0, width, strip), { rows: 11, band: 0.9 })\n }\n}\n\n/** Why the camera could not start, in words a cashier can act on. */\nexport function cameraErrorMessage(error: unknown): string {\n const name = (error as { name?: string })?.name ?? ''\n if (name === 'NotAllowedError' || name === 'SecurityError') {\n return 'Camera access is blocked. Allow the camera for this site in the browser settings, then try again.'\n }\n if (name === 'NotFoundError' || name === 'OverconstrainedError') {\n return 'No camera was found on this device. Use a USB or Bluetooth scanner, or type the code.'\n }\n if (name === 'NotReadableError') {\n return 'The camera is in use by another app. Close it and try again.'\n }\n return 'The camera could not be started. Type the code instead.'\n}\n\nexport function BarcodeScanner(props: BarcodeScannerProps) {\n const { open, onClose, onDetected, title } = props\n const theme = useTheme()\n const fullScreen = useMediaQuery(theme.breakpoints.down('sm'))\n const videoRef = useRef<HTMLVideoElement | null>(null)\n const [error, setError] = useState('')\n const [starting, setStarting] = useState(false)\n const detectedRef = useRef(onDetected)\n detectedRef.current = onDetected\n\n const stopRef = useRef<() => void>(() => undefined)\n const close = useCallback(() => {\n stopRef.current()\n onClose()\n }, [onClose])\n\n useEffect(() => {\n if (!open) return\n let cancelled = false\n let stream: MediaStream | null = null\n let timer: ReturnType<typeof setTimeout> | undefined\n let lastRead: { text: string; atMs: number } | null = null\n const stop = () => {\n cancelled = true\n if (timer) clearTimeout(timer)\n stream?.getTracks().forEach((track) => track.stop())\n stream = null\n }\n stopRef.current = stop\n setError('')\n setStarting(true)\n void (async () => {\n if (!navigator.mediaDevices?.getUserMedia) {\n setError('This browser cannot use the camera here. Type the code, or use a USB or Bluetooth scanner.')\n setStarting(false)\n return\n }\n try {\n stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { ideal: 'environment' }, width: { ideal: 1920 }, height: { ideal: 1080 } },\n audio: false,\n })\n } catch (cause) {\n if (!cancelled) {\n setError(cameraErrorMessage(cause))\n setStarting(false)\n }\n return\n }\n if (cancelled) return stop()\n const video = videoRef.current\n if (!video) return stop()\n video.srcObject = stream\n video.setAttribute('playsinline', 'true')\n await video.play().catch(() => undefined)\n const native = await nativeReader()\n const read = native ?? (await fallbackReader())\n const needsConfirm = !native\n if (cancelled) return\n setStarting(false)\n const tick = async () => {\n if (cancelled) return\n const found: DecodedBarcode | null = await read(video).catch(() => null)\n if (cancelled) return\n if (found) {\n const now = Date.now()\n const confirmed =\n !needsConfirm ||\n (lastRead && lastRead.text === found.text && now - lastRead.atMs < CONFIRM_WITHIN_MS)\n lastRead = { text: found.text, atMs: now }\n if (confirmed) {\n navigator.vibrate?.(40)\n stop()\n detectedRef.current(found.text, found.format)\n return\n }\n }\n timer = setTimeout(tick, FRAME_INTERVAL_MS)\n }\n void tick()\n })()\n return stop\n }, [open])\n\n return (\n <Dialog open={open} onClose={close} fullScreen={fullScreen} fullWidth maxWidth=\"sm\">\n <DialogTitle>{title ?? 'Scan a barcode'}</DialogTitle>\n <DialogContent>\n {error ? (\n <Alert severity=\"warning\">{error}</Alert>\n ) : (\n <Box\n sx={{\n position: 'relative',\n width: '100%',\n aspectRatio: '4 / 3',\n bgcolor: 'common.black',\n borderRadius: 1,\n overflow: 'hidden',\n }}\n >\n <Box\n component=\"video\"\n ref={videoRef}\n muted\n playsInline\n aria-label=\"Camera preview\"\n sx={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n <Box\n aria-hidden\n sx={{\n position: 'absolute',\n left: '8%',\n right: '8%',\n top: '35%',\n bottom: '35%',\n border: 2,\n borderColor: 'primary.main',\n borderRadius: 1,\n }}\n />\n </Box>\n )}\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1 }}>\n {starting\n ? 'Starting the camera…'\n : 'Hold the barcode flat inside the frame, lines running up and down.'}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={close}>{'Cancel'}</Button>\n </DialogActions>\n </Dialog>\n )\n}\nBarcodeScanner.displayName = 'BarcodeScanner'\n\nexport default BarcodeScanner\n"],"names":["Alert","Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","Typography","useMediaQuery","useTheme","useCallback","useEffect","useRef","useState","NATIVE_FORMATS","FRAME_INTERVAL_MS","CONFIRM_WITHIN_MS","nativeReader","Detector","globalThis","BarcodeDetector","supported","getSupportedFormats","formats","filter","format","includes","length","detector","video","found","detect","rawValue","text","fallbackReader","decodeImageData","canvas","document","createElement","context","getContext","willReadFrequently","videoWidth","width","Math","min","height","round","videoHeight","strip","drawImage","getImageData","rows","band","cameraErrorMessage","error","name","BarcodeScanner","props","open","onClose","onDetected","title","theme","fullScreen","breakpoints","down","videoRef","setError","starting","setStarting","detectedRef","current","stopRef","undefined","close","cancelled","stream","timer","lastRead","stop","clearTimeout","getTracks","forEach","track","navigator","mediaDevices","getUserMedia","facingMode","ideal","audio","cause","srcObject","setAttribute","play","catch","native","read","needsConfirm","tick","now","Date","confirmed","atMs","vibrate","setTimeout","fullWidth","maxWidth","severity","sx","position","aspectRatio","bgcolor","borderRadius","overflow","component","ref","muted","playsInline","aria-label","objectFit","aria-hidden","left","right","top","bottom","border","borderColor","variant","color","mt","onClick","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The camera scan button that sits at the end of a search or barcode field
|
|
3
|
+
* (AGL-3619): it opens the camera scanner and hands back the code, the way a
|
|
4
|
+
* keyboard-mode scanner would have typed it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ScanAdornment(props: {
|
|
7
|
+
label: string;
|
|
8
|
+
onScan: (code: string) => void;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
export default ScanAdornment;
|