{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "shipping-label-printer",
  "title": "Shipping Label Printer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/shipping-label-printer/shipping-label-printer.component.ts",
      "content": "// Multi-carrier shipping label creator and dispatch station: live carrier rate cards,\n// digital scale sync with dimensional weight, signature + insurance accessorials, a priced\n// dispatch summary, and a realistic 4×6 thermal label preview with ZPL payload export.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal } from '@angular/core'\nimport {\n  Barcode,\n  Check,\n  Copy,\n  Download,\n  FileCode2,\n  LucideAngularModule,\n  Package,\n  Printer,\n  RefreshCw,\n  Scale,\n  ShieldCheck,\n  Truck,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { UiRadioGroupComponent, UiRadioGroupItemComponent } from '@/ui/radio-group/radio-group.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\n\nexport type CarrierId = 'fedex' | 'ups' | 'usps' | 'dhl'\n\nexport interface CarrierOption {\n  id: CarrierId\n  name: string\n  code: string\n  serviceBanner: string\n  rate: number\n  transitDays: string\n  badge: string\n  badgeVariant: 'default' | 'secondary' | 'outline' | 'success'\n  trackingNumber: string\n  barcodeString: string\n  routingZip: string\n  routingZone: string\n  hubCode: string\n}\n\nconst CARRIERS: Record<CarrierId, CarrierOption> = {\n  fedex: {\n    id: 'fedex',\n    name: 'FedEx Express Priority',\n    code: 'FEDEX',\n    serviceBanner: 'FEDEX 2DAY AIR · DELIVER BY 10:30 AM',\n    rate: 24.5,\n    transitDays: 'Next Business Day (10:30 AM)',\n    badge: 'Fastest',\n    badgeVariant: 'default',\n    trackingNumber: '#TRK-9284-1029-4810-US',\n    barcodeString: '*4209110192841029481029*',\n    routingZip: 'PRIORITY 91101',\n    routingZone: 'ZONE 8 · ROUTE W-04',\n    hubCode: 'MEM (Memphis SuperHub)',\n  },\n  ups: {\n    id: 'ups',\n    name: 'UPS Ground',\n    code: 'UPS',\n    serviceBanner: 'UPS GROUND · GUARANTEED TRACKED',\n    rate: 11.2,\n    transitDays: '2-3 Business Days',\n    badge: 'Best Value',\n    badgeVariant: 'secondary',\n    trackingNumber: '#1Z-9999-9992-8410-2948',\n    barcodeString: '*420911011Z99999992841029*',\n    routingZip: 'GROUND 91101',\n    routingZone: 'ZONE 4 · ROUTE CA-08',\n    hubCode: 'ONT (Ontario West Hub)',\n  },\n  usps: {\n    id: 'usps',\n    name: 'USPS Priority Mail',\n    code: 'USPS',\n    serviceBanner: 'USPS PRIORITY MAIL 2-DAY · COMMERCIAL BASE',\n    rate: 9.85,\n    transitDays: '1-3 Business Days',\n    badge: 'Standard',\n    badgeVariant: 'outline',\n    trackingNumber: '#9400-1118-9922-3849-1029',\n    barcodeString: '*4209110194001118992238*',\n    routingZip: 'PRIORITY 91101',\n    routingZone: 'ZONE 8 · ROUTE P-12',\n    hubCode: 'LAX (Los Angeles P&DC)',\n  },\n  dhl: {\n    id: 'dhl',\n    name: 'DHL Express',\n    code: 'DHL',\n    serviceBanner: 'DHL EXPRESS WORLDWIDE · TIME DEFINITE',\n    rate: 38.0,\n    transitDays: 'Next Day by End of Day',\n    badge: 'Express Air',\n    badgeVariant: 'default',\n    trackingNumber: '#DHL-92841-102948-US',\n    barcodeString: '*42091101DHL9284102948*',\n    routingZip: 'EXPRESS 91101',\n    routingZone: 'ZONE INTL · GATEWAY LAX',\n    hubCode: 'CVG (Cincinnati Hub)',\n  },\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-shipping-label-printer, [ui-shipping-label-printer]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiInputComponent,\n    UiRadioGroupComponent,\n    UiRadioGroupItemComponent,\n    UiSeparatorComponent,\n    UiSwitchComponent,\n  ],\n  template: `\n    <div data-slot=\"shipping-label-printer\" [class]=\"rootClass\">\n      <!-- Header Control Bar -->\n      <div\n        class=\"border-border bg-card flex flex-col gap-4 rounded-xl border p-4 shadow-xs sm:flex-row sm:items-center sm:justify-between\"\n      >\n        <div class=\"space-y-1\">\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <span ui-badge variant=\"outline\" class=\"gap-1.5 font-mono text-xs\">\n              <lucide-icon [img]=\"Truck\" class=\"text-primary size-3.5\" aria-hidden=\"true\" />\n              Dispatch Station #04\n            </span>\n            <div\n              class=\"border-success/20 bg-success/10 text-success inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium\"\n            >\n              <span class=\"relative flex size-1.5\">\n                <span class=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\"></span>\n                <span class=\"bg-success relative inline-flex size-1.5 rounded-full\"></span>\n              </span>\n              Zebra ZD421 Ready · 203 DPI\n            </div>\n          </div>\n\n          <div class=\"flex flex-wrap items-center gap-2 pt-1\">\n            <h1 class=\"text-foreground text-xl font-semibold tracking-tight sm:text-2xl\">\n              Shipping Label Creation &amp; Dispatch\n            </h1>\n            <button\n              type=\"button\"\n              class=\"hover:bg-muted focus-visible:ring-ring border-border bg-muted/40 text-foreground inline-flex min-h-6 items-center gap-1.5 rounded border px-2 py-0.5 font-mono text-xs font-semibold transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n              title=\"Click to copy order reference\"\n              (click)=\"copyOrderRef()\"\n            >\n              {{ orderRef() }}\n              @if (copiedOrder()) {\n                <lucide-icon [img]=\"Check\" class=\"text-success size-3\" aria-hidden=\"true\" />\n              } @else {\n                <lucide-icon [img]=\"Copy\" class=\"text-muted-foreground size-3\" aria-hidden=\"true\" />\n              }\n            </button>\n          </div>\n          <p class=\"text-muted-foreground text-xs\">\n            Multi-carrier rate rating, automated scale synchronization, and instant 4×6 thermal direct label generation.\n          </p>\n        </div>\n\n        <!-- Action Buttons -->\n        <div class=\"flex flex-wrap items-center gap-2 sm:self-center\">\n          <button\n            ui-button\n            aria-label=\"Download attachment\"\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"gap-1.5 text-xs shadow-xs\"\n            (click)=\"handleDownloadZpl()\"\n          >\n            @if (copiedZpl()) {\n              <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" aria-hidden=\"true\" />\n            } @else {\n              <lucide-icon [img]=\"Download\" class=\"size-3.5\" aria-hidden=\"true\" />\n            }\n            <span>{{ copiedZpl() ? 'Copied ZPL II' : 'Download ZPL / PDF' }}</span>\n          </button>\n\n          <button ui-button size=\"sm\" class=\"gap-1.5 text-xs shadow-xs\" (click)=\"handlePrint()\">\n            <lucide-icon [img]=\"Printer\" class=\"size-3.5\" aria-hidden=\"true\" />\n            <span>{{ isPrinted() ? 'Sending to Thermal...' : 'Print 4x6 Thermal Label' }}</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- 2-Column Shipping Station Grid -->\n      <div class=\"grid grid-cols-1 gap-6 lg:grid-cols-12\">\n        <!-- Left Column: Carrier & Package Inputs (7 cols on lg) -->\n        <div class=\"space-y-6 lg:col-span-7\">\n          <!-- 1. Carrier Selector Radio Cards -->\n          <div ui-card class=\"border shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"Truck\" class=\"text-primary size-4\" aria-hidden=\"true\" />\n                  <h3 ui-card-title class=\"text-base font-semibold\">Carrier &amp; Service Rate Selection</h3>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">Live API Rates</span>\n              </div>\n              <p ui-card-description>\n                Select optimal carrier routing based on transit time guarantee and negotiated rates\n              </p>\n            </div>\n\n            <div ui-card-content class=\"space-y-3\">\n              <ui-radio-group\n                [value]=\"selectedCarrier()\"\n                (valueChange)=\"setCarrier($event)\"\n                class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\"\n              >\n                @for (carrier of carrierList; track carrier.id) {\n                  <label\n                    [class]=\"\n                      cn(\n                        'relative flex cursor-pointer flex-col justify-between rounded-lg border p-3.5 transition-colors',\n                        selectedCarrier() === carrier.id\n                          ? 'border-primary bg-primary/5 ring-primary shadow-xs ring-1'\n                          : 'border-border bg-card hover:bg-muted/40'\n                      )\n                    \"\n                  >\n                    <div class=\"flex items-start justify-between gap-2\">\n                      <div class=\"flex items-center gap-2.5\">\n                        <ui-radio-group-item [id]=\"carrier.id\" [value]=\"carrier.id\" class=\"mt-0.5\" />\n                        <div>\n                          <div class=\"text-foreground flex items-center gap-1.5 text-sm font-semibold\">\n                            {{ carrier.name }}\n                          </div>\n                          <p class=\"text-muted-foreground text-xs\">{{ carrier.transitDays }}</p>\n                        </div>\n                      </div>\n                      <span ui-badge [variant]=\"carrier.badgeVariant\" class=\"font-mono text-xs\">\n                        {{ carrier.badge }}\n                      </span>\n                    </div>\n\n                    <div class=\"border-border/60 mt-3 flex items-center justify-between border-t pt-2\">\n                      <span class=\"text-muted-foreground font-mono text-xs\">{{ carrier.code }} Commercial Rate</span>\n                      <span class=\"text-foreground font-mono text-sm font-semibold tabular-nums\">\n                        {{ '$' + carrier.rate.toFixed(2) }}\n                      </span>\n                    </div>\n                  </label>\n                }\n              </ui-radio-group>\n            </div>\n          </div>\n\n          <!-- 2. Package Weight & Scale Sync -->\n          <div ui-card class=\"border shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"Scale\" class=\"text-primary size-4\" aria-hidden=\"true\" />\n                  <h3 ui-card-title class=\"text-base font-semibold\">Package Weight &amp; Digital Scale</h3>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">USB COM3</span>\n              </div>\n              <p ui-card-description>Live gross weight measurement captured via certified USB benchtop parcel scale</p>\n            </div>\n\n            <div ui-card-content class=\"space-y-4\">\n              <!-- Scale Telemetry Banner -->\n              <div\n                class=\"border-border bg-muted/20 flex flex-col gap-2.5 rounded-lg border p-3 sm:flex-row sm:items-center sm:justify-between\"\n              >\n                <div class=\"flex items-center gap-2.5\">\n                  <div class=\"bg-success/10 text-success rounded-md p-2\">\n                    <lucide-icon [img]=\"Scale\" class=\"size-4 shrink-0\" aria-hidden=\"true\" />\n                  </div>\n                  <div>\n                    <div class=\"flex items-center gap-2\">\n                      <span class=\"text-foreground text-xs font-semibold\">Fairbanks SC-200 Bench Scale</span>\n                      <span class=\"bg-success size-1.5 animate-pulse rounded-full\"></span>\n                    </div>\n                    <p class=\"text-muted-foreground font-mono text-xs\">\n                      Live Auto-Sync Active &bull; Certified NIST Class III\n                    </p>\n                  </div>\n                </div>\n\n                <div class=\"flex items-center gap-2 self-end sm:self-auto\">\n                  <span\n                    ui-badge\n                    variant=\"outline\"\n                    class=\"border-success/30 bg-success/10 text-success font-mono text-xs font-semibold\"\n                  >\n                    4 lbs 8.0 oz (2.04 kg)\n                  </span>\n                  <button\n                    ui-button\n                    variant=\"outline\"\n                    size=\"sm\"\n                    class=\"h-7 gap-1 px-2 text-xs\"\n                    [disabled]=\"isScaleSyncing()\"\n                    (click)=\"handleSyncScale()\"\n                  >\n                    <lucide-icon\n                      [img]=\"RefreshCw\"\n                      [class]=\"cn('size-3', isScaleSyncing() && 'animate-spin')\"\n                      aria-hidden=\"true\"\n                    />\n                    <span>{{ isScaleSyncing() ? 'Syncing...' : 'Re-weigh' }}</span>\n                  </button>\n                </div>\n              </div>\n\n              <!-- Weight & Dimensions Form Inputs -->\n              <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n                <!-- Weight Inputs -->\n                <div class=\"space-y-1.5\">\n                  <label class=\"text-foreground text-xs font-semibold\"> Gross Billed Weight </label>\n                  <div class=\"grid grid-cols-2 gap-2\">\n                    <div class=\"relative\">\n                      <ui-input\n                        [value]=\"weightLbs()\"\n                        (valueChange)=\"weightLbs.set(toNum($event))\"\n                        type=\"number\"\n                        [min]=\"0\"\n                        [max]=\"150\"\n                        class=\"pr-8 font-mono text-xs\"\n                      />\n                      <span\n                        class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 font-mono text-xs\"\n                      >\n                        lbs\n                      </span>\n                    </div>\n                    <div class=\"relative\">\n                      <ui-input\n                        [value]=\"weightOz()\"\n                        (valueChange)=\"weightOz.set(toNum($event))\"\n                        type=\"number\"\n                        [min]=\"0\"\n                        [max]=\"15.9\"\n                        [step]=\"0.1\"\n                        class=\"pr-8 font-mono text-xs\"\n                      />\n                      <span\n                        class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-2.5 -translate-y-1/2 font-mono text-xs\"\n                      >\n                        oz\n                      </span>\n                    </div>\n                  </div>\n                </div>\n\n                <!-- Package Dimensions -->\n                <div class=\"space-y-1.5\">\n                  <div class=\"flex items-center justify-between\">\n                    <label class=\"text-foreground text-xs font-semibold\"> Package Dimensions (L × W × H) </label>\n                    <span class=\"text-muted-foreground font-mono text-xs\">{{ dimWeightLbs() }} lbs Dim Wt</span>\n                  </div>\n                  <div class=\"grid grid-cols-3 gap-1.5\">\n                    <div class=\"relative\">\n                      <ui-input\n                        [value]=\"dimLength()\"\n                        (valueChange)=\"dimLength.set(toNum($event))\"\n                        type=\"number\"\n                        [min]=\"1\"\n                        class=\"pr-6 font-mono text-xs\"\n                      />\n                      <span\n                        class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-2 -translate-y-1/2 font-mono text-xs\"\n                      >\n                        L\n                      </span>\n                    </div>\n                    <div class=\"relative\">\n                      <ui-input\n                        [value]=\"dimWidth()\"\n                        (valueChange)=\"dimWidth.set(toNum($event))\"\n                        type=\"number\"\n                        [min]=\"1\"\n                        class=\"pr-6 font-mono text-xs\"\n                      />\n                      <span\n                        class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-2 -translate-y-1/2 font-mono text-xs\"\n                      >\n                        W\n                      </span>\n                    </div>\n                    <div class=\"relative\">\n                      <ui-input\n                        [value]=\"dimHeight()\"\n                        (valueChange)=\"dimHeight.set(toNum($event))\"\n                        type=\"number\"\n                        [min]=\"1\"\n                        class=\"pr-6 font-mono text-xs\"\n                      />\n                      <span\n                        class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-2 -translate-y-1/2 font-mono text-xs\"\n                      >\n                        H\n                      </span>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <!-- 3. Value-Added Services & Declared Value -->\n          <div ui-card class=\"border shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"ShieldCheck\" class=\"text-primary size-4\" aria-hidden=\"true\" />\n                  <h3 ui-card-title class=\"text-base font-semibold\">Delivery Access &amp; Insurance Options</h3>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">Carrier Accessorials</span>\n              </div>\n            </div>\n\n            <div ui-card-content class=\"space-y-4\">\n              <!-- Signature on Delivery Switch -->\n              <div\n                class=\"border-border bg-card flex items-start justify-between gap-4 rounded-lg border p-3.5 shadow-xs\"\n              >\n                <div class=\"space-y-1\">\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"text-foreground text-sm font-semibold\">Direct Signature Required</span>\n                    <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">+$5.50</span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                    Carrier will obtain a physical in-person signature from recipient at doorstep. Cannot be left\n                    unattended.\n                  </p>\n                </div>\n                <button\n                  ui-switch\n                  [checked]=\"requireSignature()\"\n                  (checkedChange)=\"requireSignature.set($event)\"\n                  aria-label=\"Toggle direct signature required\"\n                ></button>\n              </div>\n\n              <!-- Declared Value / Cargo Insurance -->\n              <div\n                class=\"border-border bg-card flex flex-col gap-3 rounded-lg border p-3.5 shadow-xs sm:flex-row sm:items-center sm:justify-between\"\n              >\n                <div class=\"space-y-0.5\">\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"text-foreground text-sm font-semibold\">Declared Insurance Value</span>\n                    <span ui-badge variant=\"outline\" class=\"text-xs\">Full Loss Protection</span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs\">\n                    Coverage up to declared amount for transit loss, theft, or damage (+$3.20 premium)\n                  </p>\n                </div>\n                <div class=\"relative w-full sm:w-36\">\n                  <span\n                    class=\"text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 -translate-y-1/2 font-mono text-xs font-semibold\"\n                  >\n                    $\n                  </span>\n                  <ui-input\n                    [value]=\"declaredValue()\"\n                    (valueChange)=\"declaredValue.set($event)\"\n                    type=\"text\"\n                    class=\"pl-6 text-right font-mono text-xs\"\n                  />\n                </div>\n              </div>\n\n              <!-- Package Items Summary Strip -->\n              <div class=\"border-border bg-muted/20 rounded-lg border p-3 text-xs\">\n                <div class=\"flex items-center justify-between\">\n                  <div class=\"flex items-center gap-2\">\n                    <lucide-icon [img]=\"Package\" class=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n                    <span class=\"text-foreground font-semibold\">Package Contents:</span>\n                    <span class=\"text-muted-foreground\">Pro Studio Headphones X9, Braided Cable (2 items)</span>\n                  </div>\n                  <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">SKU-AUD-9821</span>\n                </div>\n              </div>\n            </div>\n          </div>\n\n          <!-- 4. Pricing & Dispatch Cost Summary -->\n          <div ui-card class=\"border-border bg-muted/20 border shadow-xs\">\n            <div ui-card-content class=\"space-y-3 p-4\">\n              <div class=\"flex items-center justify-between text-xs\">\n                <span class=\"text-muted-foreground\">Base Carrier Rate ({{ activeCarrier().name }}):</span>\n                <span class=\"text-foreground font-mono font-medium tabular-nums\">{{\n                  '$' + activeCarrier().rate.toFixed(2)\n                }}</span>\n              </div>\n              <div class=\"flex items-center justify-between text-xs\">\n                <span class=\"text-muted-foreground\">Direct Signature Confirmation:</span>\n                <span class=\"text-foreground font-mono font-medium tabular-nums\">{{\n                  '$' + signatureFee().toFixed(2)\n                }}</span>\n              </div>\n              <div class=\"flex items-center justify-between text-xs\">\n                <span class=\"text-muted-foreground\">Declared Value Cargo Protection ($300.00):</span>\n                <span class=\"text-foreground font-mono font-medium tabular-nums\">{{\n                  '$' + insuranceFee().toFixed(2)\n                }}</span>\n              </div>\n              <ui-separator />\n              <div class=\"flex items-center justify-between\">\n                <span class=\"text-foreground text-sm font-semibold\">Total Label &amp; Dispatch Cost:</span>\n                <span class=\"text-primary font-mono text-base font-semibold tabular-nums\">\n                  {{ '$' + totalShippingCost().toFixed(2) + ' USD' }}\n                </span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Right Column: 4x6 Thermal Printable Label Card (5 cols on lg) -->\n        <div class=\"space-y-4 lg:col-span-5\">\n          <div ui-card class=\"border shadow-xs\">\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"Barcode\" class=\"text-primary size-4\" aria-hidden=\"true\" />\n                  <h3 ui-card-title class=\"text-base font-semibold\">4×6 Thermal Label Preview</h3>\n                </div>\n                <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">ZPL II 203 DPI</span>\n              </div>\n              <p ui-card-description>Direct thermal printable output formatted for 4\" × 6\" standard roll label stock</p>\n            </div>\n\n            <div ui-card-content class=\"space-y-4\">\n              <!-- Thermal Label Canvas Container -->\n              <div\n                class=\"border-border bg-muted/40 relative flex flex-col items-center justify-center rounded-xl border p-4 shadow-inner sm:p-6\"\n              >\n                <!-- Top Thermal Stock Perforation Marker -->\n                <div class=\"text-muted-foreground/60 mb-2 flex items-center gap-1 font-mono text-xs select-none\">\n                  <span>&#9986;</span>\n                  <span class=\"border-muted-foreground/40 inline-block w-48 border-b border-dashed\"></span>\n                  <span>4\" TEAR LINE</span>\n                </div>\n\n                <!-- REALISTIC 4x6 CARRIER SHIPPING LABEL MOCKUP -->\n                <div\n                  class=\"w-full max-w-[340px] space-y-2.5 rounded-sm border-2 border-black bg-white p-4 font-mono text-xs leading-tight text-black shadow-lg select-none\"\n                >\n                  <!-- Label Header: Carrier Code & Meta -->\n                  <div class=\"flex items-start justify-between border-b-2 border-black pb-2\">\n                    <div>\n                      <div\n                        class=\"inline-block border-2 border-black px-2 py-0.5 text-base font-bold tracking-wider uppercase\"\n                      >\n                        {{ activeCarrier().code }}\n                      </div>\n                      <div class=\"mt-1 text-xs font-semibold text-black\">PRIORITY DISPATCH</div>\n                    </div>\n\n                    <div class=\"space-y-0.5 text-right text-xs\">\n                      <div class=\"font-semibold\">WT: {{ weightLbs() }} LBS {{ weightOz() }} OZ</div>\n                      <div>DIM: {{ dimLength() }}x{{ dimWidth() }}x{{ dimHeight() }} IN</div>\n                      <div>DATE: 21AUG26</div>\n                    </div>\n                  </div>\n\n                  <!-- Service Banner -->\n                  <div\n                    class=\"bg-black px-1.5 py-1 text-center text-xs font-semibold tracking-wider text-white uppercase\"\n                  >\n                    {{ activeCarrier().serviceBanner }}\n                  </div>\n\n                  <!-- Origin & 2D MaxiCode Block -->\n                  <div class=\"grid grid-cols-12 items-center gap-2 py-1\">\n                    <!-- Ship From Address -->\n                    <div class=\"col-span-8 space-y-0.5 text-xs leading-none\">\n                      <div class=\"font-semibold tracking-wider uppercase\">SHIP FROM:</div>\n                      <div class=\"font-semibold\">ACME LOGISTICS DC #4</div>\n                      <div>100 ENTERPRISE WAY, STE 200</div>\n                      <div>NEWARK NJ 07102-4100</div>\n                      <div class=\"pt-1 text-xs\">REF: {{ orderRef() }}</div>\n                    </div>\n\n                    <!-- 2D MaxiCode / PDF417 Vector Barcode -->\n                    <div class=\"col-span-4 flex justify-end\">\n                      <svg\n                        viewBox=\"0 0 100 100\"\n                        class=\"size-16 shrink-0 text-black\"\n                        fill=\"currentColor\"\n                        aria-label=\"MaxiCode 2D Routing Matrix\"\n                      >\n                        <circle cx=\"50\" cy=\"50\" r=\"15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" />\n                        <circle cx=\"50\" cy=\"50\" r=\"7\" fill=\"currentColor\" />\n                        <rect x=\"8\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"22\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"36\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"55\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"69\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"8\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"8\" y=\"22\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"22\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"8\" y=\"36\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"22\" y=\"36\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"69\" y=\"36\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"36\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"8\" y=\"55\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"22\" y=\"55\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"69\" y=\"55\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"55\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"8\" y=\"69\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"69\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"8\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"22\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"36\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"55\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"69\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                        <rect x=\"83\" y=\"83\" width=\"9\" height=\"9\" rx=\"1\" />\n                      </svg>\n                    </div>\n                  </div>\n\n                  <!-- Destination Address Block -->\n                  <div class=\"space-y-0.5 border-t-2 border-black pt-2\">\n                    <div class=\"font-semibold tracking-wider uppercase\">SHIP TO:</div>\n                    <div class=\"text-sm font-semibold\">ALEXANDRA CHEN</div>\n                    <div class=\"font-medium\">742 EVERGREEN TERRACE, APT 4B</div>\n                    <div class=\"text-sm font-semibold tracking-tight\">PASADENA CA 91101-2104</div>\n                    <div class=\"text-xs\">TEL: (555) 019-2831</div>\n                  </div>\n\n                  <!-- Large Bold Zip Code Routing Bar -->\n                  <div class=\"my-1 border-2 border-black bg-white p-2 text-center\">\n                    <div class=\"text-lg font-bold tracking-widest uppercase\">{{ activeCarrier().routingZip }}</div>\n                    <div class=\"mt-0.5 text-xs font-semibold tracking-wider\">\n                      {{ activeCarrier().routingZone }} &bull; {{ activeCarrier().hubCode }}\n                    </div>\n                  </div>\n\n                  <!-- Signature Required Strip -->\n                  @if (requireSignature()) {\n                    <div class=\"bg-black px-1.5 py-0.5 text-center text-xs font-semibold tracking-wider text-white\">\n                      *** DIRECT SIGNATURE REQUIRED ***\n                    </div>\n                  }\n\n                  <!-- Large Code 128 Tracking Barcode -->\n                  <div class=\"space-y-1 border-t-2 border-black pt-2\">\n                    <div class=\"flex w-full justify-center overflow-hidden py-1\">\n                      <svg\n                        viewBox=\"0 0 320 54\"\n                        class=\"h-12 w-full text-black\"\n                        fill=\"currentColor\"\n                        preserveAspectRatio=\"none\"\n                        aria-label=\"Code 128 Tracking Barcode\"\n                      >\n                        <rect x=\"0\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"5\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"9\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"16\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"20\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"26\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"29\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"37\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"42\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"46\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"52\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"56\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"63\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"68\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"71\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"79\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"83\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"89\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"94\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"98\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"105\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"109\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"115\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"118\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"126\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"131\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"135\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"142\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"147\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"151\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"157\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"161\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"169\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"172\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"178\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"183\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"187\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"194\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"199\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"202\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"210\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"214\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"220\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"225\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"229\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"236\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"240\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"246\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"249\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"257\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"262\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"266\" y=\"0\" width=\"5\" height=\"54\" />\n                        <rect x=\"273\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"278\" y=\"0\" width=\"1\" height=\"54\" />\n                        <rect x=\"281\" y=\"0\" width=\"6\" height=\"54\" />\n                        <rect x=\"289\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"293\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"299\" y=\"0\" width=\"3\" height=\"54\" />\n                        <rect x=\"304\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"308\" y=\"0\" width=\"4\" height=\"54\" />\n                        <rect x=\"314\" y=\"0\" width=\"2\" height=\"54\" />\n                        <rect x=\"318\" y=\"0\" width=\"2\" height=\"54\" />\n                      </svg>\n                    </div>\n                    <div class=\"text-center text-xs font-semibold tracking-widest\">\n                      {{ activeCarrier().barcodeString }}\n                    </div>\n                  </div>\n\n                  <!-- Tracking Number Line -->\n                  <div class=\"border-t border-black pt-1 text-center\">\n                    <div class=\"text-xs font-semibold tracking-wider\">\n                      TRACKING #: {{ activeCarrier().trackingNumber }}\n                    </div>\n                  </div>\n\n                  <!-- Label Footer -->\n                  <div class=\"flex items-center justify-between border-t border-black pt-1 text-xs font-semibold\">\n                    <span>POSTAGE PAID</span>\n                    <span>4x6 THERMAL</span>\n                    <span>PKG 1 OF 1</span>\n                  </div>\n                </div>\n              </div>\n\n              <!-- Print Actions & Quick Copy Toolbar -->\n              <div class=\"flex flex-wrap items-center justify-between gap-2 text-xs\">\n                <div class=\"text-muted-foreground flex items-center gap-1.5 font-mono\">\n                  <span>Tracking:</span>\n                  <button\n                    type=\"button\"\n                    class=\"hover:bg-muted focus-visible:ring-ring bg-muted/60 text-foreground inline-flex min-h-6 items-center gap-1 rounded px-1.5 py-0.5 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                    title=\"Click to copy tracking number\"\n                    (click)=\"copyTracking()\"\n                  >\n                    <span>{{ activeCarrier().trackingNumber }}</span>\n                    @if (copiedTracking()) {\n                      <lucide-icon [img]=\"Check\" class=\"text-success size-3\" aria-hidden=\"true\" />\n                    } @else {\n                      <lucide-icon [img]=\"Copy\" class=\"size-3\" aria-hidden=\"true\" />\n                    }\n                  </button>\n                </div>\n\n                <div class=\"flex items-center gap-2\">\n                  <button\n                    ui-button\n                    variant=\"outline\"\n                    size=\"sm\"\n                    class=\"h-7 gap-1 px-2 text-xs\"\n                    (click)=\"handleDownloadZpl()\"\n                  >\n                    <lucide-icon [img]=\"FileCode2\" class=\"size-3\" aria-hidden=\"true\" />\n                    <span>ZPL Payload</span>\n                  </button>\n                  <button ui-button size=\"sm\" class=\"h-7 gap-1 px-2.5 text-xs\" (click)=\"handlePrint()\">\n                    <lucide-icon [img]=\"Printer\" class=\"size-3\" aria-hidden=\"true\" />\n                    <span>Print Label</span>\n                  </button>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiShippingLabelPrinterComponent {\n  protected readonly cn = cn\n  protected readonly Barcode = Barcode\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Download = Download\n  protected readonly FileCode2 = FileCode2\n  protected readonly Package = Package\n  protected readonly Printer = Printer\n  protected readonly RefreshCw = RefreshCw\n  protected readonly Scale = Scale\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Truck = Truck\n\n  @Input('initialOrderRef') set initialOrderRefInput(v: string | undefined) {\n    if (v !== undefined) this.orderRef.set(v)\n  }\n  @Input('initialCarrier') set initialCarrierInput(v: CarrierId | undefined) {\n    if (v) this.selectedCarrier.set(v)\n  }\n  @Input('class') className?: string\n\n  @Output() print = new EventEmitter<void>()\n  @Output('download-zpl') downloadZpl = new EventEmitter<string>()\n\n  readonly orderRef = signal('#ORD-92841')\n  readonly selectedCarrier = signal<CarrierId>('fedex')\n  readonly weightLbs = signal(4)\n  readonly weightOz = signal(8)\n  readonly dimLength = signal(14)\n  readonly dimWidth = signal(10)\n  readonly dimHeight = signal(6)\n  readonly requireSignature = signal(true)\n  readonly declaredValue = signal('300.00')\n  readonly includeInsurance = signal(true)\n\n  readonly isScaleSyncing = signal(false)\n  readonly copiedOrder = signal(false)\n  readonly copiedTracking = signal(false)\n  readonly copiedZpl = signal(false)\n  readonly isPrinted = signal(false)\n\n  readonly carrierList = Object.values(CARRIERS)\n  readonly activeCarrier = computed(() => CARRIERS[this.selectedCarrier()] ?? CARRIERS.fedex)\n  readonly signatureFee = computed(() => (this.requireSignature() ? 5.5 : 0))\n  readonly insuranceFee = computed(() => (this.includeInsurance() ? 3.2 : 0))\n  readonly totalShippingCost = computed(() => this.activeCarrier().rate + this.signatureFee() + this.insuranceFee())\n  readonly dimWeightLbs = computed(() => ((this.dimLength() * this.dimWidth() * this.dimHeight()) / 139).toFixed(2))\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  toNum(raw: string): number {\n    const n = Number(raw)\n    return Number.isNaN(n) ? 0 : n\n  }\n\n  setCarrier(v: string): void {\n    this.selectedCarrier.set(v as CarrierId)\n  }\n\n  generateZplCode(): string {\n    const c = this.activeCarrier()\n    return `^XA\n^FO50,30^A0N,40,40^FD${c.code}^FS\n^FO220,30^A0N,22,22^FDWT: ${this.weightLbs()} LBS ${this.weightOz()} OZ^FS\n^FO220,60^A0N,22,22^FDDIM: ${this.dimLength()}x${this.dimWidth()}x${this.dimHeight()} IN^FS\n^FO50,95^GB700,3,3^FS\n^FO50,110^A0N,26,26^FD${c.serviceBanner}^FS\n^FO50,150^GB700,3,3^FS\n^FO50,165^A0N,20,20^FDSHIP FROM:^FS\n^FO50,190^A0N,20,20^FDACME LOGISTICS FULFILLMENT DC #4^FS\n^FO50,215^A0N,20,20^FD100 ENTERPRISE WAY, SUITE 200^FS\n^FO50,240^A0N,20,20^FDNEWARK NJ 07102-4100^FS\n^FO50,270^GB700,3,3^FS\n^FO50,285^A0N,22,22^FDSHIP TO:^FS\n^FO50,315^A0N,26,26^FDALEXANDRA CHEN  (555) 019-2831^FS\n^FO50,345^A0N,26,26^FD742 EVERGREEN TERRACE, APT 4B^FS\n^FO50,375^A0N,26,26^FDPASADENA CA 91101-2104^FS\n^FO50,415^GB700,70,4^FS\n^FO70,435^A0N,40,40^FD${c.routingZip}^FS\n^FO50,500^GB700,3,3^FS\n${this.requireSignature() ? '^FO50,515^A0N,22,22^FD*** DIRECT SIGNATURE REQUIRED UPON DELIVERY ***^FS\\n^FO50,545^GB700,3,3^FS\\n' : ''}^FO100,570^BY3,3,90^BCN,90,Y,N,N^FD>${c.barcodeString}^FS\n^FO50,710^A0N,28,28^FDTRACKING: ${c.trackingNumber}^FS\n^FO50,760^GB700,2,2^FS\n^FO50,775^A0N,18,18^FDELECTRONIC POSTAGE PAID - ZPL II 203 DPI - 1 OF 1^FS\n^XZ`\n  }\n\n  handlePrint(): void {\n    this.print.emit()\n    this.isPrinted.set(true)\n    setTimeout(() => {\n      this.isPrinted.set(false)\n    }, 3000)\n    if (typeof window !== 'undefined' && typeof window.print === 'function') {\n      window.print()\n    }\n  }\n\n  handleDownloadZpl(): void {\n    const zpl = this.generateZplCode()\n    this.downloadZpl.emit(zpl)\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(zpl)\n    }\n    this.copiedZpl.set(true)\n    setTimeout(() => {\n      this.copiedZpl.set(false)\n    }, 2500)\n  }\n\n  handleSyncScale(): void {\n    this.isScaleSyncing.set(true)\n    setTimeout(() => {\n      this.weightLbs.set(4)\n      this.weightOz.set(8)\n      this.isScaleSyncing.set(false)\n    }, 600)\n  }\n\n  copyOrderRef(): void {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(this.orderRef())\n      this.copiedOrder.set(true)\n      setTimeout(() => {\n        this.copiedOrder.set(false)\n      }, 2000)\n    }\n  }\n\n  copyTracking(): void {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(this.activeCarrier().trackingNumber)\n      this.copiedTracking.set(true)\n      setTimeout(() => {\n        this.copiedTracking.set(false)\n      }, 2000)\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/shipping-label-printer/shipping-label-printer.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/shipping-label-printer/index.ts",
      "content": "export { UiShippingLabelPrinterComponent, type CarrierId, type CarrierOption } from './shipping-label-printer.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/shipping-label-printer/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/radio-group.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/switch.json"
  ],
  "description": "Multi-carrier shipping label creator and dispatch station (USPS, FedEx, UPS, DHL) with live digital scale sync, package dimensional weight calculator, delivery options, and realistic 4x6 high-contrast thermal printable label preview.",
  "categories": [
    "logistics",
    "app",
    "ecommerce"
  ]
}