{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "employee-org-chart-tree",
  "title": "Employee Org Chart Tree",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/employee-org-chart-tree/employee-org-chart-tree.component.ts",
      "content": "// Interactive organizational hierarchy tree with manager reporting lines, team counts, multi-level\n// expandable branches, department filter pills, employee search, and an employee profile quick info\n// drawer. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal } from '@angular/core'\nimport {\n  ArrowRight,\n  Briefcase,\n  Building2,\n  Calendar,\n  Check,\n  ChevronDown,\n  ChevronRight,\n  Copy,\n  Mail,\n  MapPin,\n  Minus,\n  Plus,\n  RotateCcw,\n  Search,\n  User,\n  Users,\n  X,\n  ZoomIn,\n  ZoomOut,\n  LucideAngularModule,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiAvatarComponent, UiAvatarFallbackComponent, UiAvatarImageComponent } from '@/ui/avatar/avatar.component'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { DEFAULT_ORG_DATA } from './org-chart-data'\nimport { getDeptBadgeClasses, getDeptTopStripClasses, type EmployeeNode } from './org-chart-types'\n\nexport type { EmployeeNode }\n\nfunction flatten(node: EmployeeNode): EmployeeNode[] {\n  const result: EmployeeNode[] = [node]\n  if (node.children) {\n    for (const child of node.children) result.push(...flatten(child))\n  }\n  return result\n}\n\nexport interface DepartmentCount {\n  label: string\n  value: string\n  count: number\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-org-chart-node-card',\n  standalone: true,\n  imports: [\n    LucideAngularModule,\n    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiAvatarImageComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n  ],\n  template: `\n    <div\n      [class]=\"cardClass\"\n      tabindex=\"0\"\n      role=\"button\"\n      [attr.aria-label]=\"'Select ' + node.name\"\n      (click)=\"select.emit(node)\"\n      (keydown.enter)=\"select.emit(node)\"\n      (keydown.space)=\"select.emit(node); $event.preventDefault()\"\n    >\n      <!-- Top department accent strip -->\n      <div [class]=\"cn('h-1 w-full rounded-t-xl', stripClass())\"></div>\n\n      <div class=\"space-y-3 p-4\">\n        <!-- Identity row -->\n        <div class=\"flex items-start justify-between gap-2.5\">\n          <div class=\"flex min-w-0 items-center gap-2.5\">\n            <div class=\"relative\">\n              <ui-avatar class=\"border-border ring-background size-10 border ring-1\">\n                <ui-avatar-image [src]=\"node.avatar\" [alt]=\"node.name\" />\n                <ui-avatar-fallback>{{ node.initials }}</ui-avatar-fallback>\n              </ui-avatar>\n              <span class=\"ring-background bg-success absolute right-0 bottom-0 size-2.5 rounded-full ring-2\"></span>\n            </div>\n            <div class=\"min-w-0\">\n              <h4 class=\"text-foreground truncate text-sm font-semibold\">{{ node.name }}</h4>\n              <p class=\"text-muted-foreground truncate text-xs\">{{ node.role }}</p>\n            </div>\n          </div>\n          <span ui-badge variant=\"outline\" [class]=\"cn('shrink-0 text-xs font-normal', badgeClass())\">\n            {{ node.department }}\n          </span>\n        </div>\n\n        <!-- Contact & Location info -->\n        <div class=\"text-muted-foreground space-y-1 text-xs\">\n          <div class=\"flex items-center gap-1.5\">\n            <lucide-icon [img]=\"MapPin\" class=\"size-3.5 shrink-0\" />\n            <span class=\"truncate\">{{ node.location }}</span>\n          </div>\n          <div class=\"flex items-center gap-1.5\">\n            <lucide-icon [img]=\"Mail\" class=\"size-3.5 shrink-0\" />\n            <span class=\"truncate\">{{ node.email }}</span>\n          </div>\n        </div>\n\n        <!-- Team Reports Count Pill -->\n        <div class=\"bg-muted/60 flex items-center justify-between rounded-lg px-2.5 py-1.5 text-xs\">\n          <div class=\"text-foreground flex items-center gap-1.5 font-medium\">\n            <lucide-icon [img]=\"Users\" class=\"text-muted-foreground size-3.5\" />\n            <span>{{ reportsLabel || 'Direct reports: ' + node.reportsCount }}</span>\n          </div>\n          <span class=\"text-muted-foreground text-xs\">{{ headcountLabel || node.teamHeadcount + ' staff' }}</span>\n        </div>\n\n        <!-- Expand/Collapse Button (if has children) -->\n        @if (node.children && node.children.length > 0 && toggleExpand.observed) {\n          <button\n            ui-button\n            variant=\"ghost\"\n            size=\"sm\"\n            class=\"text-muted-foreground hover:text-foreground h-7 w-full justify-between text-xs font-medium\"\n            (click)=\"onToggle($event)\"\n          >\n            <span class=\"flex items-center gap-1.5\">\n              @if (isExpanded) {\n                <lucide-icon [img]=\"ChevronDown\" class=\"size-3.5\" />\n              } @else {\n                <lucide-icon [img]=\"ChevronRight\" class=\"size-3.5\" />\n              }\n              <span>{{\n                isExpanded\n                  ? collapseLabel || 'Collapse Branch'\n                  : expandLabel || 'Expand (' + node.children!.length + ')'\n              }}</span>\n            </span>\n            <span class=\"bg-muted rounded px-1.5 py-0.5 text-xs\">{{ node.children!.length }}</span>\n          </button>\n        }\n      </div>\n    </div>\n  `,\n})\nexport class UiOrgChartNodeCardComponent {\n  protected readonly ChevronDown = ChevronDown\n  protected readonly ChevronRight = ChevronRight\n  protected readonly Mail = Mail\n  protected readonly MapPin = MapPin\n  protected readonly Users = Users\n  protected readonly cn = cn\n\n  @Input() node!: EmployeeNode\n  @Input() isSelected = false\n  @Input() isHighlighted = false\n  @Input() isDimmed = false\n  @Input() isExpanded = false\n  @Input() reportsLabel?: string\n  @Input() headcountLabel?: string\n  @Input() expandLabel?: string\n  @Input() collapseLabel?: string\n  @Output() select = new EventEmitter<EmployeeNode>()\n  @Output() toggleExpand = new EventEmitter<string>()\n\n  badgeClass(): string {\n    return getDeptBadgeClasses(this.node.department)\n  }\n\n  stripClass(): string {\n    return getDeptTopStripClasses(this.node.department)\n  }\n\n  get cardClass(): string {\n    return cn(\n      'bg-card border-border hover:border-primary/50 focus-visible:ring-ring relative w-72 cursor-pointer rounded-xl border text-left shadow-xs transition-colors duration-200 outline-none hover:shadow-md focus-visible:ring-2',\n      this.isSelected && 'ring-primary border-primary bg-primary/[0.02] ring-2',\n      this.isHighlighted && 'border-success bg-success/10/20 ring-success dark:bg-success/10 ring-2',\n      this.isDimmed && 'opacity-35 grayscale-[25%]',\n    )\n  }\n\n  onToggle(event: Event): void {\n    event.stopPropagation()\n    this.toggleExpand.emit(this.node.id)\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-org-chart-toolbar',\n  standalone: true,\n  imports: [LucideAngularModule, UiButtonComponent, UiInputComponent],\n  template: `\n    <div>\n      <!-- Header Section -->\n      <div class=\"border-border flex flex-col gap-4 border-b p-5 md:flex-row md:items-center md:justify-between\">\n        <div>\n          <div class=\"flex items-center gap-2\">\n            <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n              <lucide-icon [img]=\"Building2\" class=\"size-4\" />\n            </div>\n            <h2 class=\"text-foreground text-lg font-semibold tracking-tight\">{{ title }}</h2>\n          </div>\n          <p class=\"text-muted-foreground mt-1 text-xs\">{{ subtitle }}</p>\n        </div>\n\n        <!-- Header Action Controls -->\n        <div class=\"flex flex-wrap items-center gap-2\">\n          <div class=\"relative max-w-xs min-w-[220px]\">\n            <lucide-icon\n              [img]=\"Search\"\n              class=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\"\n            />\n            <ui-input\n              [value]=\"searchQuery\"\n              (valueChange)=\"searchChange.emit($event)\"\n              placeholder=\"Search employee, title, skill...\"\n              class=\"h-8 pr-7 pl-8 text-xs\"\n            />\n            @if (searchQuery) {\n              <button\n                type=\"button\"\n                class=\"text-muted-foreground hover:text-foreground focus-visible:ring-ring absolute top-1/2 right-2 -translate-y-1/2 rounded-sm outline-none focus-visible:ring-2\"\n                aria-label=\"Clear search\"\n                (click)=\"searchChange.emit('')\"\n              >\n                <lucide-icon [img]=\"X\" class=\"size-3.5\" />\n              </button>\n            }\n          </div>\n\n          <div class=\"bg-border hidden h-6 w-px md:block\"></div>\n\n          <button ui-button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" (click)=\"expandAll.emit()\">\n            <lucide-icon [img]=\"Plus\" class=\"size-3.5\" />\n            <span>Expand All</span>\n          </button>\n\n          <button ui-button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" (click)=\"collapseAll.emit()\">\n            <lucide-icon [img]=\"Minus\" class=\"size-3.5\" />\n            <span>Collapse All</span>\n          </button>\n\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            [class]=\"cn('h-8 gap-1.5 text-xs', isDrawerOpen && 'bg-accent text-accent-foreground')\"\n            (click)=\"toggleDrawer.emit()\"\n          >\n            <lucide-icon [img]=\"User\" class=\"size-3.5\" />\n            <span>{{ isDrawerOpen ? 'Hide Profile' : 'View Profile' }}</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- Filter & Toolbar Bar -->\n      <div class=\"border-border bg-muted/20 flex flex-wrap items-center justify-between gap-3 border-b px-5 py-3\">\n        <!-- Department Filter Pills -->\n        <div class=\"flex flex-wrap items-center gap-1.5\">\n          <span class=\"text-muted-foreground mr-1 text-xs font-medium\">Department:</span>\n          @for (dept of departmentCounts; track dept.value) {\n            <button type=\"button\" [class]=\"pillClass(dept.value)\" (click)=\"departmentSelect.emit(dept.value)\">\n              <span>{{ dept.label }}</span>\n              <span [class]=\"pillCountClass(dept.value)\">{{ dept.count }}</span>\n            </button>\n          }\n        </div>\n\n        <!-- Zoom and Search Banner -->\n        <div class=\"flex items-center gap-2\">\n          @if (searchQuery.trim()) {\n            <div class=\"text-success text-xs\">\n              Found {{ matchingCount }} matching member{{ matchingCount === 1 ? '' : 's' }}\n            </div>\n          }\n\n          <div class=\"bg-background border-border flex items-center rounded-lg border p-0.5 shadow-2xs\">\n            <button\n              ui-button\n              variant=\"ghost\"\n              size=\"icon\"\n              class=\"size-6 text-xs\"\n              [disabled]=\"zoomLevel <= 70\"\n              aria-label=\"Zoom out\"\n              (click)=\"adjustZoom.emit(-10)\"\n            >\n              <lucide-icon [img]=\"ZoomOut\" class=\"size-3\" />\n            </button>\n            <span class=\"text-muted-foreground w-10 text-center text-xs font-medium\">{{ zoomLevel }}%</span>\n            <button\n              ui-button\n              variant=\"ghost\"\n              size=\"icon\"\n              class=\"size-6 text-xs\"\n              [disabled]=\"zoomLevel >= 130\"\n              aria-label=\"Zoom in\"\n              (click)=\"adjustZoom.emit(10)\"\n            >\n              <lucide-icon [img]=\"ZoomIn\" class=\"size-3\" />\n            </button>\n            <div class=\"bg-border mx-0.5 h-3.5 w-px\"></div>\n            <button\n              ui-button\n              variant=\"ghost\"\n              size=\"icon\"\n              class=\"size-6 text-xs\"\n              aria-label=\"Reset zoom\"\n              (click)=\"resetZoom.emit()\"\n            >\n              <lucide-icon [img]=\"RotateCcw\" class=\"size-3\" />\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiOrgChartToolbarComponent {\n  protected readonly Building2 = Building2\n  protected readonly Minus = Minus\n  protected readonly Plus = Plus\n  protected readonly RotateCcw = RotateCcw\n  protected readonly Search = Search\n  protected readonly User = User\n  protected readonly X = X\n  protected readonly ZoomIn = ZoomIn\n  protected readonly ZoomOut = ZoomOut\n  protected readonly cn = cn\n\n  @Input() title = ''\n  @Input() subtitle = ''\n  @Input() searchQuery = ''\n  @Input() isDrawerOpen = false\n  @Input() departmentCounts: DepartmentCount[] = []\n  @Input() selectedDepartment = 'All'\n  @Input() matchingCount = 0\n  @Input() zoomLevel = 100\n  @Output() searchChange = new EventEmitter<string>()\n  @Output() toggleDrawer = new EventEmitter<void>()\n  @Output() departmentSelect = new EventEmitter<string>()\n  @Output() expandAll = new EventEmitter<void>()\n  @Output() collapseAll = new EventEmitter<void>()\n  @Output() adjustZoom = new EventEmitter<number>()\n  @Output() resetZoom = new EventEmitter<void>()\n\n  pillClass(value: string): string {\n    return cn(\n      'focus-visible:ring-ring inline-flex h-7 items-center gap-1.5 rounded-full px-2.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none',\n      this.selectedDepartment === value\n        ? 'bg-primary text-primary-foreground shadow-xs'\n        : 'bg-background hover:bg-muted text-muted-foreground border-border border',\n    )\n  }\n\n  pillCountClass(value: string): string {\n    return cn(\n      'py-0.2 rounded-full px-1.5 text-xs',\n      this.selectedDepartment === value\n        ? 'bg-primary-foreground/20 text-primary-foreground'\n        : 'bg-muted text-muted-foreground',\n    )\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-employee-profile-drawer',\n  standalone: true,\n  imports: [\n    LucideAngularModule,\n    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiAvatarImageComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n  ],\n  template: `\n    <div class=\"border-border bg-card flex w-full shrink-0 flex-col border-t lg:w-96 lg:border-t-0 lg:border-l\">\n      <!-- Drawer Header -->\n      <div class=\"border-border flex items-center justify-between border-b p-4\">\n        <div class=\"flex items-center gap-2\">\n          <lucide-icon [img]=\"User\" class=\"text-primary size-4\" />\n          <h3 class=\"text-foreground text-sm font-semibold\">Employee Profile</h3>\n        </div>\n        <button\n          ui-button\n          variant=\"ghost\"\n          size=\"icon\"\n          class=\"size-7\"\n          aria-label=\"Close profile drawer\"\n          (click)=\"close.emit()\"\n        >\n          <lucide-icon [img]=\"X\" class=\"size-4\" />\n        </button>\n      </div>\n\n      <!-- Drawer Body -->\n      <div class=\"max-h-[700px] flex-1 space-y-5 overflow-y-auto p-5\">\n        <!-- Profile Identity Header -->\n        <div class=\"flex items-start gap-3.5\">\n          <div class=\"relative\">\n            <ui-avatar class=\"border-border ring-background size-14 border ring-2\">\n              <ui-avatar-image [src]=\"employee.avatar\" [alt]=\"employee.name\" />\n              <ui-avatar-fallback>{{ employee.initials }}</ui-avatar-fallback>\n            </ui-avatar>\n            <span class=\"ring-background bg-success absolute right-0 bottom-0 size-3 rounded-full ring-2\"></span>\n          </div>\n          <div class=\"min-w-0 flex-1\">\n            <h4 class=\"text-foreground text-base font-semibold tracking-tight\">{{ employee.name }}</h4>\n            <p class=\"text-muted-foreground text-xs\">{{ employee.role }}</p>\n            <div class=\"mt-2 flex flex-wrap items-center gap-1.5\">\n              <span ui-badge variant=\"outline\" [class]=\"cn('text-xs font-medium', deptClass())\">{{\n                employee.department\n              }}</span>\n              <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">Active · Full-time</span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Quick Action Buttons -->\n        <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n          <a ui-button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs\" [href]=\"'mailto:' + employee.email\">\n            <lucide-icon [img]=\"Mail\" class=\"size-3.5\" />\n            <span>Send Email</span>\n          </a>\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-8 gap-1.5 text-xs\"\n            (click)=\"copyEmail.emit(employee.email)\"\n          >\n            @if (emailCopied) {\n              <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n            } @else {\n              <lucide-icon [img]=\"Copy\" class=\"size-3.5\" />\n            }\n            <span>{{ emailCopied ? 'Copied!' : 'Copy Email' }}</span>\n          </button>\n        </div>\n\n        <div class=\"bg-border h-px\"></div>\n\n        <!-- Bio -->\n        <div class=\"space-y-1.5\">\n          <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">About & Focus</h5>\n          <p class=\"text-muted-foreground text-xs leading-relaxed\">{{ employee.bio }}</p>\n        </div>\n\n        <!-- Key Details Grid -->\n        <div class=\"space-y-1.5\">\n          <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Overview Details</h5>\n          <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n            <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n              <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                <lucide-icon [img]=\"Users\" class=\"size-3\" />\n                <span>Team Scope</span>\n              </div>\n              <p class=\"text-foreground mt-1 text-xs font-semibold\">{{ employee.teamHeadcount }} Members</p>\n            </div>\n            <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n              <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                <lucide-icon [img]=\"MapPin\" class=\"size-3\" />\n                <span>Location</span>\n              </div>\n              <p class=\"text-foreground mt-1 truncate text-xs font-semibold\">{{ employee.location }}</p>\n            </div>\n            <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n              <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                <lucide-icon [img]=\"Calendar\" class=\"size-3\" />\n                <span>Tenure</span>\n              </div>\n              <p class=\"text-foreground mt-1 text-xs font-semibold\">{{ employee.tenure }}</p>\n            </div>\n            <div class=\"bg-muted/40 border-border/60 rounded-lg border p-2.5\">\n              <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                <lucide-icon [img]=\"Briefcase\" class=\"size-3\" />\n                <span>Phone</span>\n              </div>\n              <p class=\"text-foreground mt-1 truncate text-xs font-semibold\">{{ employee.phone }}</p>\n            </div>\n          </div>\n        </div>\n\n        <!-- Reporting Manager Context -->\n        @if (employee.managerName) {\n          <div class=\"space-y-1.5\">\n            <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Reports To</h5>\n            <div class=\"border-border/80 bg-muted/20 flex items-center justify-between rounded-lg border p-2.5\">\n              <div class=\"min-w-0\">\n                <p class=\"text-foreground text-xs font-medium\">{{ employee.managerName }}</p>\n                <p class=\"text-muted-foreground text-xs\">{{ employee.managerRole }}</p>\n              </div>\n              <button\n                ui-button\n                variant=\"ghost\"\n                size=\"sm\"\n                class=\"h-7 gap-1 text-xs\"\n                (click)=\"viewManager.emit(employee.managerId)\"\n              >\n                <span>View</span>\n                <lucide-icon [img]=\"ArrowRight\" class=\"size-3\" />\n              </button>\n            </div>\n          </div>\n        }\n\n        <!-- Direct Reports Roster -->\n        @if (employee.children && employee.children.length > 0) {\n          <div class=\"space-y-2\">\n            <div class=\"flex items-center justify-between\">\n              <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">\n                Direct Reports ({{ employee.children!.length }})\n              </h5>\n              <span class=\"text-muted-foreground text-xs font-medium\">{{ employee.reportsCount }} reporting teams</span>\n            </div>\n\n            <div class=\"space-y-1.5\">\n              @for (sub of employee.children; track sub.id) {\n                <div\n                  class=\"border-border/60 bg-muted/20 hover:bg-muted/40 flex cursor-pointer items-center justify-between rounded-lg border p-2 transition-colors\"\n                  (click)=\"selectEmployee.emit(sub)\"\n                >\n                  <div class=\"flex min-w-0 items-center gap-2\">\n                    <ui-avatar class=\"border-border size-7 border\">\n                      <ui-avatar-image [src]=\"sub.avatar\" [alt]=\"sub.name\" />\n                      <ui-avatar-fallback>{{ sub.initials }}</ui-avatar-fallback>\n                    </ui-avatar>\n                    <div class=\"min-w-0\">\n                      <p class=\"text-foreground truncate text-xs font-medium\">{{ sub.name }}</p>\n                      <p class=\"text-muted-foreground truncate text-xs\">{{ sub.role }}</p>\n                    </div>\n                  </div>\n                  <span\n                    ui-badge\n                    variant=\"outline\"\n                    [class]=\"cn('shrink-0 px-1.5 py-0 text-xs', deptClassFor(sub.department))\"\n                  >\n                    {{ sub.teamHeadcount }} staff\n                  </span>\n                </div>\n              }\n            </div>\n          </div>\n        }\n\n        <!-- Skills & Competencies -->\n        <div class=\"space-y-1.5\">\n          <h5 class=\"text-foreground text-xs font-semibold tracking-wide uppercase\">Core Competencies</h5>\n          <div class=\"flex flex-wrap gap-1.5\">\n            @for (skill of employee.skills; track skill) {\n              <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">{{ skill }}</span>\n            }\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiEmployeeProfileDrawerComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Briefcase = Briefcase\n  protected readonly Calendar = Calendar\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Mail = Mail\n  protected readonly MapPin = MapPin\n  protected readonly User = User\n  protected readonly Users = Users\n  protected readonly X = X\n  protected readonly cn = cn\n\n  @Input() employee!: EmployeeNode\n  @Input() emailCopied = false\n  @Output() copyEmail = new EventEmitter<string>()\n  @Output() close = new EventEmitter<void>()\n  @Output() selectEmployee = new EventEmitter<EmployeeNode>()\n  @Output() viewManager = new EventEmitter<string | undefined>()\n\n  deptClass(): string {\n    return getDeptBadgeClasses(this.employee.department)\n  }\n\n  deptClassFor(dept: string): string {\n    return getDeptBadgeClasses(dept)\n  }\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-employee-org-chart-tree, [ui-employee-org-chart-tree]',\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: [UiOrgChartNodeCardComponent, UiOrgChartToolbarComponent, UiEmployeeProfileDrawerComponent],\n  template: `\n    <div data-slot=\"employee-org-chart-tree\" [class]=\"rootClass\">\n      <!-- Header & Toolbar Controls -->\n      <ui-org-chart-toolbar\n        [title]=\"titleState()\"\n        [subtitle]=\"subtitleState()\"\n        [searchQuery]=\"searchQuery()\"\n        [isDrawerOpen]=\"isDrawerOpen()\"\n        [departmentCounts]=\"departmentCounts()\"\n        [selectedDepartment]=\"selectedDepartment()\"\n        [matchingCount]=\"matchingIds().length\"\n        [zoomLevel]=\"zoomLevel()\"\n        (searchChange)=\"onSearchChange($event)\"\n        (toggleDrawer)=\"isDrawerOpen.set(!isDrawerOpen())\"\n        (departmentSelect)=\"selectedDepartment.set($event)\"\n        (expandAll)=\"expandAll()\"\n        (collapseAll)=\"expandedIds.set([])\"\n        (adjustZoom)=\"adjustZoom($event)\"\n        (resetZoom)=\"zoomLevel.set(100)\"\n      />\n\n      <!-- Main Content: Canvas & Quick Info Drawer -->\n      <div class=\"relative flex flex-1 flex-col lg:flex-row\">\n        <!-- Tree Hierarchy Node Canvas -->\n        <div class=\"bg-muted/10 relative flex-1 overflow-x-auto overflow-y-visible p-6 md:p-10\">\n          <div\n            class=\"flex min-w-max flex-col items-center transition-transform duration-200\"\n            [style.transform]=\"'scale(' + zoomLevel() / 100 + ')'\"\n            style=\"transform-origin: top center\"\n          >\n            <!-- LEVEL 0: CEO Node -->\n            <div class=\"flex flex-col items-center\">\n              <ui-org-chart-node-card\n                [node]=\"org()\"\n                [isSelected]=\"selectedEmployeeId() === org().id\"\n                [isHighlighted]=\"isHighlighted(org())\"\n                [isDimmed]=\"isDimmed(org())\"\n                [isExpanded]=\"isExpanded(org().id)\"\n                reportsLabel=\"Direct reports: 3 VPs\"\n                [headcountLabel]=\"org().teamHeadcount + ' total org'\"\n                expandLabel=\"Expand Executive Team\"\n                collapseLabel=\"Collapse Executive Team\"\n                (select)=\"selectEmployee($event)\"\n                (toggleExpand)=\"toggleExpand($event)\"\n              />\n\n              @if (isExpanded(org().id) && org().children?.length) {\n                <div class=\"bg-border h-8 w-px\"></div>\n\n                <!-- LEVEL 1: VPs and Directors -->\n                <div class=\"relative flex items-start gap-10 pt-0\">\n                  @if ((org().children?.length ?? 0) > 1) {\n                    <div class=\"bg-border absolute top-0 right-[16.666%] left-[16.666%] h-px\"></div>\n                  }\n\n                  @for (vp of org().children; track vp.id) {\n                    <div class=\"flex flex-col items-center\">\n                      <div class=\"bg-border h-8 w-px\"></div>\n\n                      <ui-org-chart-node-card\n                        [node]=\"vp\"\n                        [isSelected]=\"selectedEmployeeId() === vp.id\"\n                        [isHighlighted]=\"isHighlighted(vp)\"\n                        [isDimmed]=\"isDimmed(vp)\"\n                        [isExpanded]=\"isExpanded(vp.id)\"\n                        [reportsLabel]=\"'Direct reports: ' + vp.reportsCount + ' teams'\"\n                        [headcountLabel]=\"vp.teamHeadcount + ' staff'\"\n                        [expandLabel]=\"'Expand (' + (vp.children?.length || 0) + ' Leads)'\"\n                        collapseLabel=\"Collapse Branch\"\n                        (select)=\"selectEmployee($event)\"\n                        (toggleExpand)=\"toggleExpand($event)\"\n                      />\n\n                      @if (isExpanded(vp.id) && vp.children?.length) {\n                        <div class=\"bg-border h-8 w-px\"></div>\n\n                        <!-- LEVEL 2: Staff Leads & Managers -->\n                        <div class=\"relative flex items-start gap-6 pt-0\">\n                          @if (vp.children?.length === 3) {\n                            <div class=\"bg-border absolute top-0 right-[16.666%] left-[16.666%] h-px\"></div>\n                          }\n                          @if (vp.children?.length === 2) {\n                            <div class=\"bg-border absolute top-0 right-[25%] left-[25%] h-px\"></div>\n                          }\n\n                          @for (lead of vp.children; track lead.id) {\n                            <div class=\"flex flex-col items-center\">\n                              <div class=\"bg-border h-8 w-px\"></div>\n\n                              <ui-org-chart-node-card\n                                [node]=\"lead\"\n                                [isSelected]=\"selectedEmployeeId() === lead.id\"\n                                [isHighlighted]=\"isHighlighted(lead)\"\n                                [isDimmed]=\"isDimmed(lead)\"\n                                [isExpanded]=\"isExpanded(lead.id)\"\n                                [reportsLabel]=\"lead.reportsCount + ' reports'\"\n                                [headcountLabel]=\"lead.teamHeadcount + ' members'\"\n                                [expandLabel]=\"'Team (' + (lead.children?.length || 0) + ')'\"\n                                collapseLabel=\"Collapse\"\n                                (select)=\"selectEmployee($event)\"\n                                (toggleExpand)=\"toggleExpand($event)\"\n                              />\n\n                              @if (isExpanded(lead.id) && lead.children?.length) {\n                                <div class=\"bg-border h-8 w-px\"></div>\n\n                                <!-- LEVEL 3: Team ICs -->\n                                <div class=\"relative flex items-start gap-4 pt-0\">\n                                  @if (lead.children?.length === 2) {\n                                    <div class=\"bg-border absolute top-0 right-[25%] left-[25%] h-px\"></div>\n                                  }\n\n                                  @for (ic of lead.children; track ic.id) {\n                                    <div class=\"flex flex-col items-center\">\n                                      <div class=\"bg-border h-8 w-px\"></div>\n\n                                      <ui-org-chart-node-card\n                                        [node]=\"ic\"\n                                        [isSelected]=\"selectedEmployeeId() === ic.id\"\n                                        [isHighlighted]=\"isHighlighted(ic)\"\n                                        [isDimmed]=\"isDimmed(ic)\"\n                                        [reportsLabel]=\"ic.reportsCount + ' direct'\"\n                                        [headcountLabel]=\"ic.teamHeadcount + ' member'\"\n                                        (select)=\"selectEmployee($event)\"\n                                      />\n                                    </div>\n                                  }\n                                </div>\n                              }\n                            </div>\n                          }\n                        </div>\n                      }\n                    </div>\n                  }\n                </div>\n              }\n            </div>\n          </div>\n        </div>\n\n        <!-- Quick Info Side Profile Drawer -->\n        @if (isDrawerOpen()) {\n          <ui-employee-profile-drawer\n            [employee]=\"selectedEmployee()\"\n            [emailCopied]=\"emailCopied()\"\n            (copyEmail)=\"copyEmail($event)\"\n            (close)=\"isDrawerOpen.set(false)\"\n            (selectEmployee)=\"selectEmployee($event)\"\n            (viewManager)=\"viewManager($event)\"\n          />\n        }\n      </div>\n    </div>\n  `,\n})\nexport class UiEmployeeOrgChartTreeComponent {\n  @Input() set title(v: string | undefined) {\n    if (v !== undefined) this.titleState.set(v)\n  }\n  @Input() set subtitle(v: string | undefined) {\n    if (v !== undefined) this.subtitleState.set(v)\n  }\n  @Input() set orgData(v: EmployeeNode | undefined) {\n    if (v) this.orgState.set(v)\n  }\n  @Input() set initialSelectedId(v: string | undefined) {\n    if (v !== undefined) this.selectedEmployeeId.set(v)\n  }\n  @Input() set initialDepartment(v: string | undefined) {\n    if (v !== undefined) this.selectedDepartment.set(v)\n  }\n  @Input() set initialSearch(v: string | undefined) {\n    if (v !== undefined) this.searchQuery.set(v)\n  }\n  @Input() set initialExpandedIds(v: string[] | undefined) {\n    if (v) this.expandedIds.set([...v])\n  }\n  @Input() set initialDrawerOpen(v: boolean | undefined) {\n    if (v !== undefined) this.isDrawerOpen.set(v)\n  }\n  @Input('class') className?: string\n\n  readonly titleState = signal('Company Organizational Chart')\n  readonly subtitleState = signal('148 Employees across 5 Departments')\n  readonly orgState = signal<EmployeeNode>(DEFAULT_ORG_DATA)\n\n  readonly selectedEmployeeId = signal('emp-ceo')\n  readonly selectedDepartment = signal('All')\n  readonly searchQuery = signal('')\n  readonly isDrawerOpen = signal(true)\n  readonly zoomLevel = signal(100)\n  readonly emailCopied = signal(false)\n  readonly expandedIds = signal<string[]>(['emp-ceo', 'emp-eng-vp', 'emp-prod-vp', 'emp-ops-vp'])\n\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  org(): EmployeeNode {\n    return this.orgState()\n  }\n\n  readonly allEmployees = computed(() => flatten(this.orgState()))\n\n  readonly departmentCounts = computed<DepartmentCount[]>(() => {\n    const all = this.allEmployees()\n    const count = (dept: string) => all.filter((e) => e.department === dept).length\n    return [\n      { label: 'All', value: 'All', count: all.length },\n      { label: 'Executive', value: 'Executive', count: count('Executive') },\n      { label: 'Engineering', value: 'Engineering', count: count('Engineering') },\n      { label: 'Design', value: 'Design', count: count('Design') },\n      { label: 'Product', value: 'Product', count: count('Product') },\n      { label: 'Operations', value: 'Operations', count: count('Operations') },\n    ]\n  })\n\n  readonly selectedEmployee = computed<EmployeeNode>(() => {\n    return this.allEmployees().find((e) => e.id === this.selectedEmployeeId()) ?? this.orgState()\n  })\n\n  readonly matchingIds = computed<string[]>(() => {\n    const q = this.searchQuery().trim().toLowerCase()\n    if (!q) return []\n    return this.allEmployees()\n      .filter(\n        (emp) =>\n          emp.name.toLowerCase().includes(q) ||\n          emp.role.toLowerCase().includes(q) ||\n          emp.department.toLowerCase().includes(q) ||\n          emp.location.toLowerCase().includes(q) ||\n          emp.skills.some((s) => s.toLowerCase().includes(q)),\n      )\n      .map((e) => e.id)\n  })\n\n  get rootClass(): string {\n    return cn('bg-background border-border flex flex-col rounded-xl border shadow-xs', this.className)\n  }\n\n  isExpanded(id: string): boolean {\n    return this.expandedIds().includes(id)\n  }\n\n  toggleExpand(id: string): void {\n    this.expandedIds.update((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]))\n  }\n\n  expandAll(): void {\n    this.expandedIds.set(\n      this.allEmployees()\n        .filter((e) => e.children?.length)\n        .map((e) => e.id),\n    )\n  }\n\n  onSearchChange(value: string): void {\n    this.searchQuery.set(value)\n    if (value.trim()) this.expandAll()\n  }\n\n  selectEmployee(emp: EmployeeNode): void {\n    this.selectedEmployeeId.set(emp.id)\n    this.isDrawerOpen.set(true)\n  }\n\n  viewManager(managerId: string | undefined): void {\n    if (!managerId) return\n    const manager = this.allEmployees().find((e) => e.id === managerId)\n    if (manager) this.selectEmployee(manager)\n  }\n\n  copyEmail(email: string): void {\n    try {\n      void navigator.clipboard?.writeText(email)\n    } catch {\n      // Clipboard fallback\n    }\n    this.emailCopied.set(true)\n    clearTimeout(this.copyTimer)\n    this.copyTimer = setTimeout(() => this.emailCopied.set(false), 2000)\n  }\n\n  adjustZoom(delta: number): void {\n    this.zoomLevel.update((prev) => Math.min(130, Math.max(70, prev + delta)))\n  }\n\n  isDimmed(node: EmployeeNode): boolean {\n    const dept = this.selectedDepartment()\n    if (dept !== 'All') {\n      if (dept === 'Executive' && node.department !== 'Executive') return true\n      if (dept === 'Engineering' && node.department !== 'Engineering' && node.department !== 'Executive') return true\n      if (dept === 'Design' && node.department !== 'Design' && node.department !== 'Executive') return true\n      if (dept === 'Product' && node.department !== 'Product' && node.department !== 'Executive') return true\n      if (dept === 'Operations' && node.department !== 'Operations' && node.department !== 'Executive') return true\n    }\n    if (this.searchQuery().trim().length > 0) {\n      const matches = new Set(this.matchingIds())\n      const isDirectMatch = matches.has(node.id)\n      const hasMatchingDescendant = flatten(node).some((n) => matches.has(n.id))\n      return !isDirectMatch && !hasMatchingDescendant\n    }\n    return false\n  }\n\n  isHighlighted(node: EmployeeNode): boolean {\n    if (this.searchQuery().trim().length > 0) return this.matchingIds().includes(node.id)\n    return false\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/employee-org-chart-tree/employee-org-chart-tree.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/employee-org-chart-tree/org-chart-types.ts",
      "content": "export interface EmployeeNode {\n  id: string\n  name: string\n  role: string\n  department: 'Executive' | 'Engineering' | 'Design' | 'Product' | 'Operations'\n  email: string\n  phone: string\n  location: string\n  avatar: string\n  initials: string\n  reportsCount: number\n  teamHeadcount: number\n  managerId?: string\n  managerName?: string\n  managerRole?: string\n  startDate: string\n  tenure: string\n  bio: string\n  skills: string[]\n  status: 'active' | 'on-leave'\n  children?: EmployeeNode[]\n}\n\nexport function getDeptBadgeClasses(dept: string): string {\n  switch (dept) {\n    case 'Executive':\n      return 'border-chart-1/30 bg-chart-1/10 text-chart-1'\n    case 'Engineering':\n      return 'border-chart-2/30 bg-chart-2/10 text-chart-2'\n    case 'Design':\n      return 'border-chart-3/30 bg-chart-3/10 text-chart-3'\n    case 'Product':\n      return 'border-chart-4/30 bg-chart-4/10 text-chart-4'\n    case 'Operations':\n      return 'border-chart-5/30 bg-chart-5/10 text-chart-5'\n    default:\n      return 'border-border bg-muted text-muted-foreground'\n  }\n}\n\nexport function getDeptTopStripClasses(dept: string): string {\n  switch (dept) {\n    case 'Executive':\n      return 'bg-chart-1'\n    case 'Engineering':\n      return 'bg-chart-2'\n    case 'Design':\n      return 'bg-chart-3'\n    case 'Product':\n      return 'bg-chart-4'\n    case 'Operations':\n      return 'bg-chart-5'\n    default:\n      return 'bg-muted-foreground'\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/employee-org-chart-tree/org-chart-types.ts"
    },
    {
      "path": "packages/registry-angular/blocks/employee-org-chart-tree/org-chart-data.ts",
      "content": "import type { EmployeeNode } from './org-chart-types'\n\nexport const DEFAULT_ORG_DATA: EmployeeNode = {\n  id: 'emp-ceo',\n  name: 'Sarah Jenkins',\n  role: 'Chief Executive Officer',\n  department: 'Executive',\n  email: 'sarah.jenkins@acme.corp',\n  phone: '+1 (415) 890-1200',\n  location: 'San Francisco, CA (HQ)',\n  avatar: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=160&auto=format&fit=crop&q=80',\n  initials: 'SJ',\n  reportsCount: 3,\n  teamHeadcount: 148,\n  startDate: 'January 2019',\n  tenure: '5 yrs 8 mos',\n  bio: 'Directs company-wide vision, long-range enterprise roadmap, capital allocation, and executive leadership across 5 global divisions.',\n  skills: ['Executive Leadership', 'Corporate Strategy', 'Enterprise SaaS', 'M&A', 'Culture'],\n  status: 'active',\n  children: [\n    {\n      id: 'emp-eng-vp',\n      name: 'Marcus Vance',\n      role: 'VP of Engineering',\n      department: 'Engineering',\n      email: 'marcus.vance@acme.corp',\n      phone: '+1 (212) 745-9921',\n      location: 'New York, NY',\n      avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n      initials: 'MV',\n      reportsCount: 3,\n      teamHeadcount: 64,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'March 2020',\n      tenure: '4 yrs 6 mos',\n      bio: 'Leads 64 engineers across platform architecture, frontend infrastructure, and Site Reliability Engineering with 99.99% uptime SLA.',\n      skills: ['Distributed Systems', 'Cloud Architecture', 'Tech Strategy', 'Kubernetes', 'Scalability'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-eng-lead-1',\n          name: 'Alex Rivera',\n          role: 'Principal Architect',\n          department: 'Engineering',\n          email: 'alex.rivera@acme.corp',\n          phone: '+1 (512) 634-1109',\n          location: 'Austin, TX',\n          avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=160&auto=format&fit=crop&q=80',\n          initials: 'AR',\n          reportsCount: 2,\n          teamHeadcount: 18,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'September 2020',\n          tenure: '4 yrs',\n          bio: 'Designs core distributed event pipelines, data mesh architecture, and multi-tenant database infrastructure.',\n          skills: ['Go', 'Kafka', 'PostgreSQL', 'System Architecture', 'Event Streaming'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-1',\n              name: 'Kai Zhang',\n              role: 'Senior Backend Engineer',\n              department: 'Engineering',\n              email: 'kai.zhang@acme.corp',\n              phone: '+1 (512) 634-1188',\n              location: 'Austin, TX',\n              avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n              initials: 'KZ',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-1',\n              managerName: 'Alex Rivera',\n              managerRole: 'Principal Architect',\n              startDate: 'January 2022',\n              tenure: '2 yrs 8 mos',\n              bio: 'Builds low-latency gRPC services, consensus layers, and distributed caching protocols.',\n              skills: ['Rust', 'gRPC', 'Raft', 'Redis', 'High Throughput'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-2',\n              name: 'Hannah Schmidt',\n              role: 'Staff Database Architect',\n              department: 'Engineering',\n              email: 'hannah.schmidt@acme.corp',\n              phone: '+1 (512) 634-1192',\n              location: 'Remote, US',\n              avatar: 'https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=160&auto=format&fit=crop&q=80',\n              initials: 'HS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-1',\n              managerName: 'Alex Rivera',\n              managerRole: 'Principal Architect',\n              startDate: 'May 2021',\n              tenure: '3 yrs 4 mos',\n              bio: 'Specializes in multi-master replication, query optimization, and automated sharding migrations.',\n              skills: ['PostgreSQL', 'CockroachDB', 'Data Warehousing', 'Query Tuning'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-eng-lead-2',\n          name: 'Sofia Rossi',\n          role: 'Staff Frontend Lead',\n          department: 'Engineering',\n          email: 'sofia.rossi@acme.corp',\n          phone: '+49 30 2219 4481',\n          location: 'Berlin, Germany',\n          avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n          initials: 'SR',\n          reportsCount: 2,\n          teamHeadcount: 24,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'November 2020',\n          tenure: '3 yrs 10 mos',\n          bio: 'Leads the unified component design system, micro-frontend architecture, and web accessibility standards.',\n          skills: ['Vue 3', 'React', 'Design Systems', 'Web Performance', 'WCAG AA'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-3',\n              name: 'Leo Garcia',\n              role: 'Senior UI Engineer',\n              department: 'Engineering',\n              email: 'leo.garcia@acme.corp',\n              phone: '+49 30 2219 4490',\n              location: 'Berlin, Germany',\n              avatar: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=160&auto=format&fit=crop&q=80',\n              initials: 'LG',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-2',\n              managerName: 'Sofia Rossi',\n              managerRole: 'Staff Frontend Lead',\n              startDate: 'February 2022',\n              tenure: '2 yrs 7 mos',\n              bio: 'Focuses on complex interactive data visualization canvases, charts, and keyboard shortcuts engine.',\n              skills: ['TypeScript', 'Tailwind CSS', 'D3.js', 'Canvas API'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-4',\n              name: 'Nina Patel',\n              role: 'Frontend Platform Engineer',\n              department: 'Engineering',\n              email: 'nina.patel@acme.corp',\n              phone: '+44 20 8123 9940',\n              location: 'London, UK',\n              avatar: 'https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=160&auto=format&fit=crop&q=80',\n              initials: 'NP',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-2',\n              managerName: 'Sofia Rossi',\n              managerRole: 'Staff Frontend Lead',\n              startDate: 'October 2022',\n              tenure: '1 yr 11 mos',\n              bio: 'Manages automated bundle size budgets, CI build plugins, and island rendering hydration pipelines.',\n              skills: ['Vite', 'Turborepo', 'Playwright', 'ESBuild'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-eng-lead-3',\n          name: 'Tariq Mansour',\n          role: 'DevOps & SRE Lead',\n          department: 'Engineering',\n          email: 'tariq.mansour@acme.corp',\n          phone: '+1 (415) 555-8910',\n          location: 'San Francisco, CA',\n          avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=160&auto=format&fit=crop&q=80',\n          initials: 'TM',\n          reportsCount: 2,\n          teamHeadcount: 22,\n          managerId: 'emp-eng-vp',\n          managerName: 'Marcus Vance',\n          managerRole: 'VP of Engineering',\n          startDate: 'January 2021',\n          tenure: '3 yrs 8 mos',\n          bio: 'Directs cloud infrastructure resilience, multi-region Kubernetes clusters, and automated zero-downtime rollouts.',\n          skills: ['AWS', 'Terraform', 'Kubernetes', 'CI/CD', 'Observability'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-eng-ic-5',\n              name: 'Kiran Rao',\n              role: 'Senior SRE Engineer',\n              department: 'Engineering',\n              email: 'kiran.rao@acme.corp',\n              phone: '+1 (415) 555-8933',\n              location: 'San Francisco, CA',\n              avatar: 'https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?w=160&auto=format&fit=crop&q=80',\n              initials: 'KR',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-3',\n              managerName: 'Tariq Mansour',\n              managerRole: 'DevOps & SRE Lead',\n              startDate: 'August 2022',\n              tenure: '2 yrs 1 mo',\n              bio: 'Maintains Prometheus/Grafana telemetry stacks, SLO/SLI tracking dashboards, and disaster drills.',\n              skills: ['Prometheus', 'Grafana', 'OpenTelemetry', 'Chaos Engineering'],\n              status: 'active',\n            },\n            {\n              id: 'emp-eng-ic-6',\n              name: 'Elena Dubois',\n              role: 'Cloud Security Specialist',\n              department: 'Engineering',\n              email: 'elena.dubois@acme.corp',\n              phone: '+33 1 42 68 55 00',\n              location: 'Paris, France',\n              avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n              initials: 'ED',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-eng-lead-3',\n              managerName: 'Tariq Mansour',\n              managerRole: 'DevOps & SRE Lead',\n              startDate: 'March 2023',\n              tenure: '1 yr 6 mos',\n              bio: 'Owns zero-trust cloud network topology, HashiCorp Vault key rotation, and automated CVE vulnerability audits.',\n              skills: ['Vault', 'OIDC', 'IAM Hardening', 'SOC 2 Type II'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 'emp-prod-vp',\n      name: 'Elena Rostova',\n      role: 'VP of Product & Design',\n      department: 'Product',\n      email: 'elena.rostova@acme.corp',\n      phone: '+44 20 7946 0912',\n      location: 'London, UK',\n      avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=160&auto=format&fit=crop&q=80',\n      initials: 'ER',\n      reportsCount: 2,\n      teamHeadcount: 40,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'June 2020',\n      tenure: '4 yrs 3 mos',\n      bio: 'Guides end-to-end product vision, quarterly roadmap discovery cycles, and customer experience excellence across enterprise tools.',\n      skills: ['Product Strategy', 'Design Leadership', 'User Research', 'PLG', 'Enterprise UX'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-prod-lead-1',\n          name: 'Maya Patel',\n          role: 'Head of Product Design',\n          department: 'Design',\n          email: 'maya.patel@acme.corp',\n          phone: '+44 20 7946 0988',\n          location: 'London, UK',\n          avatar: 'https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?w=160&auto=format&fit=crop&q=80',\n          initials: 'MP',\n          reportsCount: 2,\n          teamHeadcount: 18,\n          managerId: 'emp-prod-vp',\n          managerName: 'Elena Rostova',\n          managerRole: 'VP of Product & Design',\n          startDate: 'February 2021',\n          tenure: '3 yrs 7 mos',\n          bio: 'Leads our 18-member UI/UX and design research studio, creating intuitive interfaces for data-intensive enterprise users.',\n          skills: ['Figma', 'UX Research', 'Design Systems', 'Design Operations'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-des-ic-1',\n              name: 'Aria Thorne',\n              role: 'Lead UX Researcher',\n              department: 'Design',\n              email: 'aria.thorne@acme.corp',\n              phone: '+1 (415) 321-7789',\n              location: 'San Francisco, CA',\n              avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=160&auto=format&fit=crop&q=80',\n              initials: 'AT',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-1',\n              managerName: 'Maya Patel',\n              managerRole: 'Head of Product Design',\n              startDate: 'July 2022',\n              tenure: '2 yrs 2 mos',\n              bio: 'Conducts qualitative enterprise customer interview loops, card sorting, and workflow pain-point mapping.',\n              skills: ['Qualitative Analysis', 'Usability Testing', 'Personas', 'Journey Mapping'],\n              status: 'active',\n            },\n            {\n              id: 'emp-des-ic-2',\n              name: 'Lucas Silva',\n              role: 'Senior Interaction Designer',\n              department: 'Design',\n              email: 'lucas.silva@acme.corp',\n              phone: '+351 21 098 7654',\n              location: 'Lisbon, Portugal',\n              avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=160&auto=format&fit=crop&q=80',\n              initials: 'LS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-1',\n              managerName: 'Maya Patel',\n              managerRole: 'Head of Product Design',\n              startDate: 'November 2022',\n              tenure: '1 yr 10 mos',\n              bio: 'Architects micro-interactions, spring animation specs, and tactile feedback patterns across web and desktop.',\n              skills: ['Framer', 'Prototyping', 'Micro-interactions', 'Token Systems'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-prod-lead-2',\n          name: 'Liam Tanaka',\n          role: 'Principal Product Manager',\n          department: 'Product',\n          email: 'liam.tanaka@acme.corp',\n          phone: '+81 3 5555 0142',\n          location: 'Tokyo, Japan',\n          avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n          initials: 'LT',\n          reportsCount: 2,\n          teamHeadcount: 22,\n          managerId: 'emp-prod-vp',\n          managerName: 'Elena Rostova',\n          managerRole: 'VP of Product & Design',\n          startDate: 'August 2021',\n          tenure: '3 yrs 1 mo',\n          bio: 'Spearheads core enterprise workflow automation, AI copilots, and monetization experiments across global markets.',\n          skills: ['Product Roadmapping', 'AI Integration', 'Data Analytics', 'Enterprise Growth'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-prod-ic-1',\n              name: 'Devon Vance',\n              role: 'Senior Technical PM',\n              department: 'Product',\n              email: 'devon.vance@acme.corp',\n              phone: '+1 (212) 745-3390',\n              location: 'New York, NY',\n              avatar: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=160&auto=format&fit=crop&q=80',\n              initials: 'DV',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-2',\n              managerName: 'Liam Tanaka',\n              managerRole: 'Principal Product Manager',\n              startDate: 'April 2023',\n              tenure: '1 yr 5 mos',\n              bio: 'Defines developer API contracts, webhook architectures, and 3rd party integration partner specifications.',\n              skills: ['API Specs', 'OpenAPI', 'Webhooks', 'Partner Integrations'],\n              status: 'active',\n            },\n            {\n              id: 'emp-prod-ic-2',\n              name: 'Sarah Lin',\n              role: 'Product Analytics Lead',\n              department: 'Product',\n              email: 'sarah.lin@acme.corp',\n              phone: '+81 3 5555 0199',\n              location: 'Tokyo, Japan',\n              avatar: 'https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=160&auto=format&fit=crop&q=80',\n              initials: 'SL',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-prod-lead-2',\n              managerName: 'Liam Tanaka',\n              managerRole: 'Principal Product Manager',\n              startDate: 'January 2023',\n              tenure: '1 yr 8 mos',\n              bio: 'Models customer retention cohorts, feature usage drop-off rates, and self-service conversion funnels.',\n              skills: ['SQL', 'Mixpanel', 'Cohort Retention', 'A/B Testing'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      id: 'emp-ops-vp',\n      name: 'David Chen',\n      role: 'VP of Operations & Finance',\n      department: 'Operations',\n      email: 'david.chen@acme.corp',\n      phone: '+65 6789 0123',\n      location: 'Singapore',\n      avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=160&auto=format&fit=crop&q=80',\n      initials: 'DC',\n      reportsCount: 2,\n      teamHeadcount: 44,\n      managerId: 'emp-ceo',\n      managerName: 'Sarah Jenkins',\n      managerRole: 'Chief Executive Officer',\n      startDate: 'August 2021',\n      tenure: '3 yrs 1 mo',\n      bio: 'Manages worldwide financial planning, global entity setup, real estate facilities, and international compliance operations.',\n      skills: ['Financial Modeling', 'Corporate Finance', 'Global Compliance', 'Treasury', 'Operations'],\n      status: 'active',\n      children: [\n        {\n          id: 'emp-ops-lead-1',\n          name: 'Chloe Dupont',\n          role: 'Director of Finance',\n          department: 'Operations',\n          email: 'chloe.dupont@acme.corp',\n          phone: '+33 1 42 68 90 12',\n          location: 'Paris, France',\n          avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=160&auto=format&fit=crop&q=80',\n          initials: 'CD',\n          reportsCount: 2,\n          teamHeadcount: 20,\n          managerId: 'emp-ops-vp',\n          managerName: 'David Chen',\n          managerRole: 'VP of Operations & Finance',\n          startDate: 'March 2022',\n          tenure: '2 yrs 6 mos',\n          bio: 'Leads FP&A, annual budgeting models, GAAP audits, and international cross-border tax compliance.',\n          skills: ['FP&A', 'GAAP Audits', 'Treasury Management', 'Tax Modeling'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-ops-ic-1',\n              name: 'Arthur Leclerc',\n              role: 'Senior Financial Analyst',\n              department: 'Operations',\n              email: 'arthur.leclerc@acme.corp',\n              phone: '+33 1 42 68 90 33',\n              location: 'Paris, France',\n              avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=160&auto=format&fit=crop&q=80',\n              initials: 'AL',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-1',\n              managerName: 'Chloe Dupont',\n              managerRole: 'Director of Finance',\n              startDate: 'November 2022',\n              tenure: '1 yr 10 mos',\n              bio: 'Analyzes recurring SaaS revenue trends, customer lifetime values, and department OPEX burn rates.',\n              skills: ['Financial Forecasting', 'Excel Modeling', 'ARR Accounting'],\n              status: 'active',\n            },\n            {\n              id: 'emp-ops-ic-2',\n              name: 'Zoe Martinez',\n              role: 'Global Payroll & Benefits Lead',\n              department: 'Operations',\n              email: 'zoe.martinez@acme.corp',\n              phone: '+34 91 555 0177',\n              location: 'Madrid, Spain',\n              avatar: 'https://images.unsplash.com/photo-1544005313-94ddf0286df2?w=160&auto=format&fit=crop&q=80',\n              initials: 'ZM',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-1',\n              managerName: 'Chloe Dupont',\n              managerRole: 'Director of Finance',\n              startDate: 'June 2023',\n              tenure: '1 yr 3 mos',\n              bio: 'Oversees payroll runs across 12 countries, international equity plans, and local pension schemes.',\n              skills: ['Global Payroll', 'Equity Schemes', 'Statutory Benefits'],\n              status: 'active',\n            },\n          ],\n        },\n        {\n          id: 'emp-ops-lead-2',\n          name: 'James Wilson',\n          role: 'Director of Global Operations',\n          department: 'Operations',\n          email: 'james.wilson@acme.corp',\n          phone: '+1 (212) 745-8812',\n          location: 'New York, NY',\n          avatar: 'https://images.unsplash.com/photo-1522075469751-3a6694fb2f61?w=160&auto=format&fit=crop&q=80',\n          initials: 'JW',\n          reportsCount: 2,\n          teamHeadcount: 24,\n          managerId: 'emp-ops-vp',\n          managerName: 'David Chen',\n          managerRole: 'VP of Operations & Finance',\n          startDate: 'May 2022',\n          tenure: '2 yrs 4 mos',\n          bio: 'Oversees global facilities, vendor procurement relationships, workplace experience, and corporate IT hardware fleets.',\n          skills: ['Vendor Negotiations', 'Facilities Management', 'Asset Tracking', 'Workplace Ops'],\n          status: 'active',\n          children: [\n            {\n              id: 'emp-ops-ic-3',\n              name: 'Rachel Green',\n              role: 'Workplace Experience Manager',\n              department: 'Operations',\n              email: 'rachel.green@acme.corp',\n              phone: '+1 (212) 745-8833',\n              location: 'New York, NY',\n              avatar: 'https://images.unsplash.com/photo-1567532939604-b6b5b0db2604?w=160&auto=format&fit=crop&q=80',\n              initials: 'RG',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-2',\n              managerName: 'James Wilson',\n              managerRole: 'Director of Global Operations',\n              startDate: 'January 2023',\n              tenure: '1 yr 8 mos',\n              bio: 'Coordinates global office events, collaborative space design, catering vendors, and team onsites.',\n              skills: ['Event Planning', 'Space Management', 'Culture Initiatives'],\n              status: 'active',\n            },\n            {\n              id: 'emp-ops-ic-4',\n              name: 'Vikram Seth',\n              role: 'IT Systems & Security Lead',\n              department: 'Operations',\n              email: 'vikram.seth@acme.corp',\n              phone: '+65 6789 0188',\n              location: 'Singapore',\n              avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=160&auto=format&fit=crop&q=80',\n              initials: 'VS',\n              reportsCount: 0,\n              teamHeadcount: 1,\n              managerId: 'emp-ops-lead-2',\n              managerName: 'James Wilson',\n              managerRole: 'Director of Global Operations',\n              startDate: 'October 2022',\n              tenure: '1 yr 11 mos',\n              bio: 'Manages enterprise MDM configurations, Okta SSO provisioning, and hardware lifecycle deployment.',\n              skills: ['Okta SSO', 'Jamf MDM', 'Endpoint Security', 'Hardware Logistics'],\n              status: 'active',\n            },\n          ],\n        },\n      ],\n    },\n  ],\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/employee-org-chart-tree/org-chart-data.ts"
    },
    {
      "path": "packages/registry-angular/blocks/employee-org-chart-tree/index.ts",
      "content": "export {\n  UiEmployeeOrgChartTreeComponent,\n  UiEmployeeProfileDrawerComponent,\n  UiOrgChartNodeCardComponent,\n  UiOrgChartToolbarComponent,\n  type DepartmentCount,\n  type EmployeeNode,\n} from './employee-org-chart-tree.component'\nexport { getDeptBadgeClasses, getDeptTopStripClasses } from './org-chart-types'\nexport { DEFAULT_ORG_DATA } from './org-chart-data'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/employee-org-chart-tree/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/avatar.json",
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/input.json"
  ],
  "description": "Interactive organizational hierarchy tree with manager reporting lines, team counts, multi-level expandable branches, department filter pills, employee search, and an employee profile quick info drawer.",
  "categories": [
    "hr",
    "app"
  ]
}