@forgeroute/ui 0.4.68 → 0.4.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7900,6 +7900,9 @@ var ToastService = class ToastService {
7900
7900
  show(msg, duration = 3e3) {
7901
7901
  this._display("success", msg, duration);
7902
7902
  }
7903
+ success(msg, duration = 3e3) {
7904
+ this._display("success", msg, duration);
7905
+ }
7903
7906
  info(msg, duration = 3e3) {
7904
7907
  this._display("info", msg, duration);
7905
7908
  }
@@ -11260,7 +11263,7 @@ i0.ɵɵngDeclareClassMetadata({
11260
11263
  }
11261
11264
  });
11262
11265
  let reorderHelpSeq = 0;
11263
- function formatPhone$1(raw) {
11266
+ function formatPhone$2(raw) {
11264
11267
  if (!raw) return "—";
11265
11268
  const digits = raw.replace(/\D/g, "");
11266
11269
  if (digits.length === 10) return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
@@ -12629,7 +12632,7 @@ var DataTableComponent = class DataTableComponent {
12629
12632
  this._failedImages.update((s) => new Set(s).add(url));
12630
12633
  }
12631
12634
  phoneCell(value) {
12632
- return formatPhone$1(value);
12635
+ return formatPhone$2(value);
12633
12636
  }
12634
12637
  _safeHref(raw) {
12635
12638
  if (typeof raw !== "string") return null;
@@ -12718,7 +12721,7 @@ var DataTableComponent = class DataTableComponent {
12718
12721
  const v = item[col.key];
12719
12722
  return v ? this._datePipe.transform(v, col.dateFormat ?? "MMM d, y") ?? "—" : "—";
12720
12723
  }
12721
- case "phone": return formatPhone$1(item[col.key]);
12724
+ case "phone": return formatPhone$2(item[col.key]);
12722
12725
  case "link": return this.linkView(col, item).text;
12723
12726
  case "days-ago": {
12724
12727
  const days = item[col.daysKey ?? col.key];
@@ -20004,7 +20007,7 @@ i0.ɵɵngDeclareClassMetadata({
20004
20007
  }
20005
20008
  });
20006
20009
  let nextPickerId = 0;
20007
- function formatPhone(raw) {
20010
+ function formatPhone$1(raw) {
20008
20011
  if (!raw) return "";
20009
20012
  const normalized = raw.startsWith("+1") && raw.replace(/\D/g, "").length === 11 ? raw.slice(2) : raw;
20010
20013
  if (normalized.startsWith("+")) return normalized;
@@ -20019,7 +20022,7 @@ var ContactPickerComponent = class ContactPickerComponent {
20019
20022
  return `${this.uid}-opt-${i}`;
20020
20023
  }
20021
20024
  constructor() {
20022
- this.formatPhone = formatPhone;
20025
+ this.formatPhone = formatPhone$1;
20023
20026
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
20024
20027
  this.placeholder = input("Search by name...", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
20025
20028
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
@@ -22367,6 +22370,45 @@ i0.ɵɵngDeclareClassMetadata({
22367
22370
  }]
22368
22371
  }
22369
22372
  });
22373
+ const PASSWORD_MAX_LENGTH = 128;
22374
+ const BASE_RULES = [
22375
+ {
22376
+ id: "length",
22377
+ label: "At least 8 characters",
22378
+ test: (p) => p.length >= 8
22379
+ },
22380
+ {
22381
+ id: "upper",
22382
+ label: "One uppercase letter",
22383
+ test: (p) => /[A-Z]/.test(p)
22384
+ },
22385
+ {
22386
+ id: "lower",
22387
+ label: "One lowercase letter",
22388
+ test: (p) => /[a-z]/.test(p)
22389
+ },
22390
+ {
22391
+ id: "digit",
22392
+ label: "One digit (0-9)",
22393
+ test: (p) => /\d/.test(p)
22394
+ }
22395
+ ];
22396
+ const LISTED_SPECIAL_PASSWORD_RULES = [...BASE_RULES, {
22397
+ id: "special",
22398
+ label: "One special character (@ $ ! % * ? & #)",
22399
+ test: (p) => /[@$!%*?&#]/.test(p)
22400
+ }];
22401
+ const ASCII_SPECIAL_PASSWORD_RULES = [...BASE_RULES, {
22402
+ id: "special",
22403
+ label: "One special character (e.g. ! @ # $ %)",
22404
+ test: (p) => /[!-\/:-@[-`{-~]/.test(p)
22405
+ }];
22406
+ function createPasswordPolicyValidator(rules, maxLength = 128) {
22407
+ return (c) => {
22408
+ const p = String(c.value ?? "");
22409
+ return p.length <= maxLength && passwordMeetsRules(p, rules) ? null : { passwordRules: true };
22410
+ };
22411
+ }
22370
22412
  const KEYS = [
22371
22413
  "1",
22372
22414
  "2",
@@ -32264,6 +32306,662 @@ const US_STATES = [
32264
32306
  label: "District of Columbia"
32265
32307
  }
32266
32308
  ];
32309
+ const US_LOCATIONS = {
32310
+ AL: [
32311
+ "Anniston",
32312
+ "Auburn",
32313
+ "Birmingham",
32314
+ "Decatur",
32315
+ "Dothan",
32316
+ "Florence",
32317
+ "Gadsden",
32318
+ "Hoover",
32319
+ "Huntsville",
32320
+ "Mobile",
32321
+ "Montgomery",
32322
+ "Tuscaloosa"
32323
+ ],
32324
+ AK: [
32325
+ "Anchorage",
32326
+ "Badger",
32327
+ "Fairbanks",
32328
+ "Juneau",
32329
+ "Ketchikan",
32330
+ "Sitka",
32331
+ "Wasilla"
32332
+ ],
32333
+ AZ: [
32334
+ "Avondale",
32335
+ "Buckeye",
32336
+ "Casa Grande",
32337
+ "Chandler",
32338
+ "Flagstaff",
32339
+ "Gilbert",
32340
+ "Glendale",
32341
+ "Goodyear",
32342
+ "Lake Havasu City",
32343
+ "Maricopa",
32344
+ "Mesa",
32345
+ "Peoria",
32346
+ "Phoenix",
32347
+ "Prescott",
32348
+ "Queen Creek",
32349
+ "Scottsdale",
32350
+ "Surprise",
32351
+ "Tempe",
32352
+ "Tucson",
32353
+ "Yuma"
32354
+ ],
32355
+ AR: [
32356
+ "Bentonville",
32357
+ "Conway",
32358
+ "Fayetteville",
32359
+ "Fort Smith",
32360
+ "Jonesboro",
32361
+ "Little Rock",
32362
+ "North Little Rock",
32363
+ "Pine Bluff",
32364
+ "Rogers",
32365
+ "Springdale"
32366
+ ],
32367
+ CA: [
32368
+ "Anaheim",
32369
+ "Antioch",
32370
+ "Bakersfield",
32371
+ "Berkeley",
32372
+ "Burbank",
32373
+ "Chula Vista",
32374
+ "Concord",
32375
+ "Corona",
32376
+ "El Monte",
32377
+ "Elk Grove",
32378
+ "Escondido",
32379
+ "Fontana",
32380
+ "Fremont",
32381
+ "Fresno",
32382
+ "Fullerton",
32383
+ "Garden Grove",
32384
+ "Glendale",
32385
+ "Hayward",
32386
+ "Huntington Beach",
32387
+ "Inglewood",
32388
+ "Irvine",
32389
+ "Lancaster",
32390
+ "Long Beach",
32391
+ "Los Angeles",
32392
+ "Modesto",
32393
+ "Moreno Valley",
32394
+ "Murrieta",
32395
+ "Ontario",
32396
+ "Oxnard",
32397
+ "Palmdale",
32398
+ "Pasadena",
32399
+ "Pomona",
32400
+ "Rancho Cucamonga",
32401
+ "Riverside",
32402
+ "Sacramento",
32403
+ "Salinas",
32404
+ "San Bernardino",
32405
+ "San Diego",
32406
+ "San Francisco",
32407
+ "San Jose",
32408
+ "Santa Ana",
32409
+ "Santa Clarita",
32410
+ "Santa Rosa",
32411
+ "Simi Valley",
32412
+ "Stockton",
32413
+ "Sunnyvale",
32414
+ "Thousand Oaks",
32415
+ "Torrance",
32416
+ "Vallejo",
32417
+ "Victorville",
32418
+ "Visalia"
32419
+ ],
32420
+ CO: [
32421
+ "Arvada",
32422
+ "Aurora",
32423
+ "Boulder",
32424
+ "Brighton",
32425
+ "Broomfield",
32426
+ "Castle Rock",
32427
+ "Colorado Springs",
32428
+ "Commerce City",
32429
+ "Denver",
32430
+ "Fort Collins",
32431
+ "Greeley",
32432
+ "Highlands Ranch",
32433
+ "Lakewood",
32434
+ "Longmont",
32435
+ "Loveland",
32436
+ "Parker",
32437
+ "Pueblo",
32438
+ "Thornton",
32439
+ "Westminster"
32440
+ ],
32441
+ CT: [
32442
+ "Bridgeport",
32443
+ "Bristol",
32444
+ "Danbury",
32445
+ "Greenwich",
32446
+ "Hartford",
32447
+ "Meriden",
32448
+ "New Britain",
32449
+ "New Haven",
32450
+ "Norwalk",
32451
+ "Stamford",
32452
+ "Waterbury"
32453
+ ],
32454
+ DE: [
32455
+ "Dover",
32456
+ "Middletown",
32457
+ "Newark",
32458
+ "Wilmington"
32459
+ ],
32460
+ FL: [
32461
+ "Boca Raton",
32462
+ "Bonita Springs",
32463
+ "Boynton Beach",
32464
+ "Bradenton",
32465
+ "Cape Coral",
32466
+ "Clearwater",
32467
+ "Coral Springs",
32468
+ "Davie",
32469
+ "Daytona Beach",
32470
+ "Deerfield Beach",
32471
+ "Deltona",
32472
+ "Fort Lauderdale",
32473
+ "Fort Myers",
32474
+ "Gainesville",
32475
+ "Hialeah",
32476
+ "Hollywood",
32477
+ "Homestead",
32478
+ "Jacksonville",
32479
+ "Jupiter",
32480
+ "Kissimmee",
32481
+ "Lakeland",
32482
+ "Lauderhill",
32483
+ "Margate",
32484
+ "Melbourne",
32485
+ "Miami",
32486
+ "Miami Gardens",
32487
+ "Miramar",
32488
+ "Naples",
32489
+ "Orlando",
32490
+ "Palm Bay",
32491
+ "Palm Beach Gardens",
32492
+ "Pembroke Pines",
32493
+ "Pensacola",
32494
+ "Pompano Beach",
32495
+ "Port St. Lucie",
32496
+ "St. Petersburg",
32497
+ "Sarasota",
32498
+ "Sunrise",
32499
+ "Tallahassee",
32500
+ "Tampa",
32501
+ "Temecula",
32502
+ "West Palm Beach"
32503
+ ],
32504
+ GA: [
32505
+ "Albany",
32506
+ "Alpharetta",
32507
+ "Athens",
32508
+ "Atlanta",
32509
+ "Augusta",
32510
+ "Columbus",
32511
+ "Gainesville",
32512
+ "Johns Creek",
32513
+ "Macon",
32514
+ "Marietta",
32515
+ "Roswell",
32516
+ "Sandy Springs",
32517
+ "Savannah",
32518
+ "South Fulton",
32519
+ "Valdosta",
32520
+ "Warner Robins"
32521
+ ],
32522
+ HI: [
32523
+ "Hilo",
32524
+ "Honolulu",
32525
+ "Kailua",
32526
+ "Kaneohe",
32527
+ "Mililani Town",
32528
+ "Pearl City"
32529
+ ],
32530
+ ID: [
32531
+ "Boise",
32532
+ "Caldwell",
32533
+ "Idaho Falls",
32534
+ "Meridian",
32535
+ "Nampa",
32536
+ "Pocatello",
32537
+ "Twin Falls"
32538
+ ],
32539
+ IL: [
32540
+ "Aurora",
32541
+ "Bloomington",
32542
+ "Champaign",
32543
+ "Chicago",
32544
+ "Cicero",
32545
+ "Elgin",
32546
+ "Evanston",
32547
+ "Joliet",
32548
+ "Naperville",
32549
+ "Peoria",
32550
+ "Rockford",
32551
+ "Springfield",
32552
+ "Waukegan"
32553
+ ],
32554
+ IN: [
32555
+ "Anderson",
32556
+ "Bloomington",
32557
+ "Carmel",
32558
+ "Evansville",
32559
+ "Fishers",
32560
+ "Fort Wayne",
32561
+ "Hammond",
32562
+ "Indianapolis",
32563
+ "Muncie",
32564
+ "South Bend",
32565
+ "Terre Haute"
32566
+ ],
32567
+ IA: [
32568
+ "Ames",
32569
+ "Cedar Rapids",
32570
+ "Council Bluffs",
32571
+ "Davenport",
32572
+ "Des Moines",
32573
+ "Dubuque",
32574
+ "Iowa City",
32575
+ "Sioux City",
32576
+ "Waterloo"
32577
+ ],
32578
+ KS: [
32579
+ "Kansas City",
32580
+ "Lawrence",
32581
+ "Olathe",
32582
+ "Overland Park",
32583
+ "Salina",
32584
+ "Topeka",
32585
+ "Wichita"
32586
+ ],
32587
+ KY: [
32588
+ "Bowling Green",
32589
+ "Covington",
32590
+ "Frankfort",
32591
+ "Lexington",
32592
+ "Louisville",
32593
+ "Owensboro",
32594
+ "Richmond"
32595
+ ],
32596
+ LA: [
32597
+ "Baton Rouge",
32598
+ "Bossier City",
32599
+ "Kenner",
32600
+ "Lafayette",
32601
+ "Lake Charles",
32602
+ "Metairie",
32603
+ "Monroe",
32604
+ "New Orleans",
32605
+ "Shreveport"
32606
+ ],
32607
+ ME: [
32608
+ "Auburn",
32609
+ "Augusta",
32610
+ "Bangor",
32611
+ "Lewiston",
32612
+ "Portland",
32613
+ "South Portland"
32614
+ ],
32615
+ MD: [
32616
+ "Annapolis",
32617
+ "Baltimore",
32618
+ "Bowie",
32619
+ "Columbia",
32620
+ "Frederick",
32621
+ "Gaithersburg",
32622
+ "Germantown",
32623
+ "Hagerstown",
32624
+ "Rockville",
32625
+ "Silver Spring",
32626
+ "Waldorf"
32627
+ ],
32628
+ MA: [
32629
+ "Boston",
32630
+ "Brockton",
32631
+ "Cambridge",
32632
+ "Fall River",
32633
+ "Lowell",
32634
+ "Lynn",
32635
+ "New Bedford",
32636
+ "Newton",
32637
+ "Quincy",
32638
+ "Springfield",
32639
+ "Worcester"
32640
+ ],
32641
+ MI: [
32642
+ "Ann Arbor",
32643
+ "Dearborn",
32644
+ "Detroit",
32645
+ "Flint",
32646
+ "Grand Rapids",
32647
+ "Kalamazoo",
32648
+ "Lansing",
32649
+ "Livonia",
32650
+ "Sterling Heights",
32651
+ "Warren"
32652
+ ],
32653
+ MN: [
32654
+ "Bloomington",
32655
+ "Brooklyn Park",
32656
+ "Burnsville",
32657
+ "Duluth",
32658
+ "Eden Prairie",
32659
+ "Minneapolis",
32660
+ "Plymouth",
32661
+ "Rochester",
32662
+ "St. Cloud",
32663
+ "St. Paul"
32664
+ ],
32665
+ MS: [
32666
+ "Biloxi",
32667
+ "Gulfport",
32668
+ "Hattiesburg",
32669
+ "Jackson",
32670
+ "Meridian",
32671
+ "Southaven",
32672
+ "Tupelo"
32673
+ ],
32674
+ MO: [
32675
+ "Columbia",
32676
+ "Independence",
32677
+ "Kansas City",
32678
+ "Lee's Summit",
32679
+ "O'Fallon",
32680
+ "Springfield",
32681
+ "St. Joseph",
32682
+ "St. Louis"
32683
+ ],
32684
+ MT: [
32685
+ "Billings",
32686
+ "Bozeman",
32687
+ "Butte",
32688
+ "Great Falls",
32689
+ "Helena",
32690
+ "Missoula"
32691
+ ],
32692
+ NE: [
32693
+ "Bellevue",
32694
+ "Grand Island",
32695
+ "Kearney",
32696
+ "Lincoln",
32697
+ "Omaha"
32698
+ ],
32699
+ NV: [
32700
+ "Carson City",
32701
+ "Henderson",
32702
+ "Las Vegas",
32703
+ "North Las Vegas",
32704
+ "Reno",
32705
+ "Sparks",
32706
+ "Sunrise Manor"
32707
+ ],
32708
+ NH: [
32709
+ "Concord",
32710
+ "Dover",
32711
+ "Manchester",
32712
+ "Nashua",
32713
+ "Portsmouth"
32714
+ ],
32715
+ NJ: [
32716
+ "Camden",
32717
+ "Edison",
32718
+ "Elizabeth",
32719
+ "Jersey City",
32720
+ "Newark",
32721
+ "Paterson",
32722
+ "Toms River",
32723
+ "Trenton"
32724
+ ],
32725
+ NM: [
32726
+ "Albuquerque",
32727
+ "Las Cruces",
32728
+ "Rio Rancho",
32729
+ "Roswell",
32730
+ "Santa Fe"
32731
+ ],
32732
+ NY: [
32733
+ "Albany",
32734
+ "Amherst",
32735
+ "Bronx",
32736
+ "Brooklyn",
32737
+ "Buffalo",
32738
+ "Cheektowaga",
32739
+ "Manhattan",
32740
+ "New Rochelle",
32741
+ "New York",
32742
+ "Niagara Falls",
32743
+ "Queens",
32744
+ "Rochester",
32745
+ "Staten Island",
32746
+ "Syracuse",
32747
+ "Utica",
32748
+ "Yonkers"
32749
+ ],
32750
+ NC: [
32751
+ "Asheville",
32752
+ "Cary",
32753
+ "Chapel Hill",
32754
+ "Charlotte",
32755
+ "Concord",
32756
+ "Durham",
32757
+ "Fayetteville",
32758
+ "Gastonia",
32759
+ "Greensboro",
32760
+ "High Point",
32761
+ "Raleigh",
32762
+ "Wilmington",
32763
+ "Winston-Salem"
32764
+ ],
32765
+ ND: [
32766
+ "Bismarck",
32767
+ "Fargo",
32768
+ "Grand Forks",
32769
+ "Minot"
32770
+ ],
32771
+ OH: [
32772
+ "Akron",
32773
+ "Canton",
32774
+ "Cincinnati",
32775
+ "Cleveland",
32776
+ "Columbus",
32777
+ "Dayton",
32778
+ "Lorain",
32779
+ "Parma",
32780
+ "Toledo",
32781
+ "Youngstown"
32782
+ ],
32783
+ OK: [
32784
+ "Broken Arrow",
32785
+ "Edmond",
32786
+ "Lawton",
32787
+ "Moore",
32788
+ "Norman",
32789
+ "Oklahoma City",
32790
+ "Tulsa"
32791
+ ],
32792
+ OR: [
32793
+ "Beaverton",
32794
+ "Bend",
32795
+ "Eugene",
32796
+ "Gresham",
32797
+ "Hillsboro",
32798
+ "Medford",
32799
+ "Portland",
32800
+ "Salem"
32801
+ ],
32802
+ PA: [
32803
+ "Allentown",
32804
+ "Bethlehem",
32805
+ "Erie",
32806
+ "Philadelphia",
32807
+ "Pittsburgh",
32808
+ "Reading",
32809
+ "Scranton"
32810
+ ],
32811
+ RI: [
32812
+ "Cranston",
32813
+ "Pawtucket",
32814
+ "Providence",
32815
+ "Warwick",
32816
+ "Woonsocket"
32817
+ ],
32818
+ SC: [
32819
+ "Charleston",
32820
+ "Columbia",
32821
+ "Florence",
32822
+ "Greenville",
32823
+ "Mount Pleasant",
32824
+ "North Charleston",
32825
+ "Rock Hill",
32826
+ "Spartanburg"
32827
+ ],
32828
+ SD: [
32829
+ "Aberdeen",
32830
+ "Rapid City",
32831
+ "Sioux Falls"
32832
+ ],
32833
+ TN: [
32834
+ "Chattanooga",
32835
+ "Clarksville",
32836
+ "Jackson",
32837
+ "Johnson City",
32838
+ "Kingsport",
32839
+ "Knoxville",
32840
+ "Memphis",
32841
+ "Murfreesboro",
32842
+ "Nashville"
32843
+ ],
32844
+ TX: [
32845
+ "Abilene",
32846
+ "Allen",
32847
+ "Amarillo",
32848
+ "Arlington",
32849
+ "Austin",
32850
+ "Beaumont",
32851
+ "Brownsville",
32852
+ "Carrollton",
32853
+ "Cedar Park",
32854
+ "College Station",
32855
+ "Corpus Christi",
32856
+ "Dallas",
32857
+ "Denton",
32858
+ "El Paso",
32859
+ "Fort Worth",
32860
+ "Frisco",
32861
+ "Garland",
32862
+ "Georgetown",
32863
+ "Grand Prairie",
32864
+ "Houston",
32865
+ "Irving",
32866
+ "Killeen",
32867
+ "Laredo",
32868
+ "League City",
32869
+ "Lewisville",
32870
+ "Lubbock",
32871
+ "Mcallen",
32872
+ "McKinney",
32873
+ "Mesquite",
32874
+ "Midland",
32875
+ "Missouri City",
32876
+ "New Braunfels",
32877
+ "Odessa",
32878
+ "Pasadena",
32879
+ "Pearland",
32880
+ "Plano",
32881
+ "Richardson",
32882
+ "Round Rock",
32883
+ "San Antonio",
32884
+ "Sugar Land",
32885
+ "Tyler",
32886
+ "Waco",
32887
+ "Wichita Falls"
32888
+ ],
32889
+ UT: [
32890
+ "Ogden",
32891
+ "Orem",
32892
+ "Provo",
32893
+ "Salt Lake City",
32894
+ "Sandy",
32895
+ "St. George",
32896
+ "West Jordan",
32897
+ "West Valley City"
32898
+ ],
32899
+ VT: [
32900
+ "Burlington",
32901
+ "Essex Junction",
32902
+ "Montpelier",
32903
+ "Rutland"
32904
+ ],
32905
+ VA: [
32906
+ "Alexandria",
32907
+ "Arlington",
32908
+ "Chesapeake",
32909
+ "Hampton",
32910
+ "Newport News",
32911
+ "Norfolk",
32912
+ "Portsmouth",
32913
+ "Richmond",
32914
+ "Roanoke",
32915
+ "Virginia Beach"
32916
+ ],
32917
+ WA: [
32918
+ "Bellevue",
32919
+ "Bellingham",
32920
+ "Everett",
32921
+ "Kent",
32922
+ "Kirkland",
32923
+ "Renton",
32924
+ "Seattle",
32925
+ "Spokane",
32926
+ "Tacoma",
32927
+ "Vancouver"
32928
+ ],
32929
+ WV: [
32930
+ "Charleston",
32931
+ "Huntington",
32932
+ "Morgantown",
32933
+ "Parkersburg"
32934
+ ],
32935
+ WI: [
32936
+ "Appleton",
32937
+ "Green Bay",
32938
+ "Kenosha",
32939
+ "Madison",
32940
+ "Milwaukee",
32941
+ "Oshkosh",
32942
+ "Racine"
32943
+ ],
32944
+ WY: [
32945
+ "Casper",
32946
+ "Cheyenne",
32947
+ "Gillette",
32948
+ "Laramie"
32949
+ ]
32950
+ };
32951
+ const COMMON_DETAIL_GROUP_STYLES = {
32952
+ activity: {
32953
+ title: "Activity",
32954
+ icon: "message",
32955
+ background: "#eff6ff"
32956
+ },
32957
+ notes: {
32958
+ title: "Notes",
32959
+ icon: "add-note",
32960
+ background: "#f1f5f9"
32961
+ }
32962
+ };
32963
+ const DETAIL_CARD_HEADER_BG = "#f8fafc";
32964
+ const DETAIL_GROUP_HEADER_BG = "#eaf3ff";
32267
32965
  var ShellProjectedStylesComponent = class ShellProjectedStylesComponent {
32268
32966
  static {
32269
32967
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -41724,6 +42422,44 @@ function layoutLanes(boxes) {
41724
42422
  flush();
41725
42423
  return result;
41726
42424
  }
42425
+ function periodGroup(todayStr) {
42426
+ if (!isValidDateStr(todayStr)) return () => null;
42427
+ const today = fromDateStr(todayStr);
42428
+ const tomorrow = toDateStr(new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1));
42429
+ const weekEnd = toDateStr(new Date(today.getFullYear(), today.getMonth(), today.getDate() + (6 - today.getDay())));
42430
+ return (dateStr) => {
42431
+ if (!isValidDateStr(dateStr)) return null;
42432
+ if (dateStr < todayStr) return {
42433
+ key: "overdue",
42434
+ label: "Overdue"
42435
+ };
42436
+ if (dateStr === todayStr) return {
42437
+ key: "today",
42438
+ label: "Today"
42439
+ };
42440
+ if (dateStr === tomorrow) return {
42441
+ key: "tomorrow",
42442
+ label: "Tomorrow"
42443
+ };
42444
+ if (dateStr <= weekEnd) return {
42445
+ key: "this-week",
42446
+ label: "This Week"
42447
+ };
42448
+ return {
42449
+ key: "later",
42450
+ label: "Later"
42451
+ };
42452
+ };
42453
+ }
42454
+ const DAY_LEVEL_TEXT = {
42455
+ low: "low activity",
42456
+ medium: "medium activity",
42457
+ high: "high activity",
42458
+ critical: "critical activity"
42459
+ };
42460
+ function isDayLevel(level) {
42461
+ return level === "low" || level === "medium" || level === "high" || level === "critical";
42462
+ }
41727
42463
  const PENDING_FOCUS_MS = 1e3;
41728
42464
  var CalendarComponent = class CalendarComponent {
41729
42465
  clickable(dateStr) {
@@ -41758,11 +42494,15 @@ var CalendarComponent = class CalendarComponent {
41758
42494
  this.endHour = input(21, ...ngDevMode ? [{ debugName: "endHour" }] : /* istanbul ignore next */ []);
41759
42495
  this.emptyMessage = input("No events in this period.", ...ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []);
41760
42496
  this.dayLabelFn = input(null, ...ngDevMode ? [{ debugName: "dayLabelFn" }] : /* istanbul ignore next */ []);
42497
+ this.dayDecorationFn = input(null, ...ngDevMode ? [{ debugName: "dayDecorationFn" }] : /* istanbul ignore next */ []);
42498
+ this.itemActionsFn = input(null, ...ngDevMode ? [{ debugName: "itemActionsFn" }] : /* istanbul ignore next */ []);
42499
+ this.agendaGroupFn = input(null, ...ngDevMode ? [{ debugName: "agendaGroupFn" }] : /* istanbul ignore next */ []);
41761
42500
  this.rangeChange = output();
41762
42501
  this.itemClick = output();
41763
42502
  this.dateClick = output();
41764
42503
  this.slotClick = output();
41765
42504
  this.moreClick = output();
42505
+ this.itemAction = output();
41766
42506
  this.host = inject(ElementRef);
41767
42507
  this.weekDayLabels = WEEK_DAY_LABELS;
41768
42508
  this.weekDayNames = [
@@ -41854,13 +42594,16 @@ var CalendarComponent = class CalendarComponent {
41854
42594
  const max = this.maxVisible();
41855
42595
  const cells = this.monthCells().map((day) => {
41856
42596
  const items = this.byDate()[day.dateStr] ?? [];
42597
+ const deco = this.decoration(day.dateStr, items);
41857
42598
  return {
41858
42599
  day,
41859
42600
  items,
41860
42601
  visible: items.slice(0, max),
41861
42602
  overflow: Math.max(0, items.length - max),
41862
42603
  clickable: this.clickable(day.dateStr),
41863
- label: this.dayAriaLabel(day.dateStr, items)
42604
+ label: this.dayAriaLabel(day.dateStr, items, deco.level),
42605
+ level: deco.level,
42606
+ tooltip: deco.tooltip
41864
42607
  };
41865
42608
  });
41866
42609
  return Array.from({ length: 6 }, (_, r) => ({
@@ -41881,10 +42624,13 @@ var CalendarComponent = class CalendarComponent {
41881
42624
  top: b.top,
41882
42625
  height: b.height
41883
42626
  })));
42627
+ const deco = this.decoration(day.dateStr, items);
41884
42628
  return {
41885
42629
  day,
41886
42630
  label: formatDayLabel(day.dateStr),
41887
42631
  clickable: this.clickable(day.dateStr),
42632
+ level: deco.level,
42633
+ tooltip: deco.tooltip,
41888
42634
  allDay: items.filter((e) => e.allDay || !e.startTime),
41889
42635
  timed: boxes.map((b) => ({
41890
42636
  ...b,
@@ -41901,6 +42647,41 @@ var CalendarComponent = class CalendarComponent {
41901
42647
  }, ...ngDevMode ? [{ debugName: "focusDate" }] : /* istanbul ignore next */ []);
41902
42648
  this.pendingFocus = null;
41903
42649
  this.pendingSawLoading = false;
42650
+ this.actionsById = computed(() => {
42651
+ const map = /* @__PURE__ */ new Map();
42652
+ const fn = this.itemActionsFn();
42653
+ if (!fn) return map;
42654
+ for (const e of this.items()) {
42655
+ const acts = fn(e);
42656
+ const seen = /* @__PURE__ */ new Set();
42657
+ const valid = Array.isArray(acts) ? acts.filter((a) => {
42658
+ if (!a || !a.id || !a.label || seen.has(a.id)) return false;
42659
+ seen.add(a.id);
42660
+ return true;
42661
+ }) : [];
42662
+ if (valid.length) map.set(e.id, valid);
42663
+ }
42664
+ return map;
42665
+ }, ...ngDevMode ? [{ debugName: "actionsById" }] : /* istanbul ignore next */ []);
42666
+ this.uid = `ui-cal-${CalendarComponent.nextUid++}`;
42667
+ this.agendaSections = computed(() => {
42668
+ const fn = this.agendaGroupFn();
42669
+ if (!fn) return null;
42670
+ const sections = [];
42671
+ for (const g of this.agendaGroups()) {
42672
+ const grp = fn(g.dateStr);
42673
+ const key = grp?.key ?? "";
42674
+ const last = sections.at(-1);
42675
+ if (last && last.key === key) last.groups.push(g);
42676
+ else sections.push({
42677
+ key,
42678
+ label: grp?.label ?? "",
42679
+ id: `${this.uid}-agenda-${sections.length}`,
42680
+ groups: [g]
42681
+ });
42682
+ }
42683
+ return sections;
42684
+ }, ...ngDevMode ? [{ debugName: "agendaSections" }] : /* istanbul ignore next */ []);
41904
42685
  this.host.nativeElement.addEventListener("pointerdown", () => {
41905
42686
  this.pendingFocus = null;
41906
42687
  });
@@ -42007,11 +42788,46 @@ var CalendarComponent = class CalendarComponent {
42007
42788
  agendaMeta(e) {
42008
42789
  return [e.timeLabel ?? (!e.allDay && e.startTime ? this.timeRange(e) : ""), ...e.meta ?? []].filter(Boolean);
42009
42790
  }
42010
- dayAriaLabel(dateStr, items) {
42791
+ dayAriaLabel(dateStr, items, level = null) {
42011
42792
  const fn = this.dayLabelFn();
42012
42793
  if (fn) return fn(dateStr, items);
42013
42794
  const label = formatDayLabel(dateStr);
42014
- return items.length ? `${label}, ${items.length} ${items.length === 1 ? "event" : "events"}` : label;
42795
+ const base = items.length ? `${label}, ${items.length} ${items.length === 1 ? "event" : "events"}` : label;
42796
+ return level ? `${base}, ${DAY_LEVEL_TEXT[level]}` : base;
42797
+ }
42798
+ decoration(dateStr, items) {
42799
+ const d = this.dayDecorationFn()?.(dateStr, items);
42800
+ return {
42801
+ level: d && isDayLevel(d.level) ? d.level : null,
42802
+ tooltip: d?.tooltip ?? ""
42803
+ };
42804
+ }
42805
+ levelText(level) {
42806
+ return DAY_LEVEL_TEXT[level];
42807
+ }
42808
+ static {
42809
+ this.NO_ACTIONS = [];
42810
+ }
42811
+ actionsFor(item) {
42812
+ return this.actionsById().get(item.id) ?? CalendarComponent.NO_ACTIONS;
42813
+ }
42814
+ actionIconD(a) {
42815
+ return a.icon ? iconPath(a.icon) ?? null : null;
42816
+ }
42817
+ onActionClick(item, action, event) {
42818
+ event.stopPropagation();
42819
+ if (action.disabled) return;
42820
+ this.itemAction.emit({
42821
+ item,
42822
+ actionId: action.id
42823
+ });
42824
+ }
42825
+ onActionsEscape(event) {
42826
+ event.stopPropagation();
42827
+ event.currentTarget.parentElement?.querySelector(":scope > .event-chip, :scope > .allday-chip, :scope > .timed-event, :scope > .agenda-event")?.focus();
42828
+ }
42829
+ static {
42830
+ this.nextUid = 0;
42015
42831
  }
42016
42832
  onDateClick(dateStr) {
42017
42833
  if (this.clickable(dateStr)) this.dateClick.emit(dateStr);
@@ -42256,6 +43072,27 @@ var CalendarComponent = class CalendarComponent {
42256
43072
  isSignal: true,
42257
43073
  isRequired: false,
42258
43074
  transformFunction: null
43075
+ },
43076
+ dayDecorationFn: {
43077
+ classPropertyName: "dayDecorationFn",
43078
+ publicName: "dayDecorationFn",
43079
+ isSignal: true,
43080
+ isRequired: false,
43081
+ transformFunction: null
43082
+ },
43083
+ itemActionsFn: {
43084
+ classPropertyName: "itemActionsFn",
43085
+ publicName: "itemActionsFn",
43086
+ isSignal: true,
43087
+ isRequired: false,
43088
+ transformFunction: null
43089
+ },
43090
+ agendaGroupFn: {
43091
+ classPropertyName: "agendaGroupFn",
43092
+ publicName: "agendaGroupFn",
43093
+ isSignal: true,
43094
+ isRequired: false,
43095
+ transformFunction: null
42259
43096
  }
42260
43097
  },
42261
43098
  outputs: {
@@ -42266,7 +43103,8 @@ var CalendarComponent = class CalendarComponent {
42266
43103
  itemClick: "itemClick",
42267
43104
  dateClick: "dateClick",
42268
43105
  slotClick: "slotClick",
42269
- moreClick: "moreClick"
43106
+ moreClick: "moreClick",
43107
+ itemAction: "itemAction"
42270
43108
  },
42271
43109
  ngImport: i0,
42272
43110
  template: `
@@ -42374,6 +43212,90 @@ var CalendarComponent = class CalendarComponent {
42374
43212
  </div>
42375
43213
  </ng-template>
42376
43214
 
43215
+ <!-- Shared item markup: the same button is drawn on its own or, when itemActionsFn offers actions, inside a wrapper next to the action buttons
43216
+ (a button can never contain buttons). -->
43217
+ <ng-template #monthChip let-e>
43218
+ <button type="button" class="event-chip" [class.stacked]="chipLayout() === 'stacked'" [class.has-head]="!!(e.iconPath || chipTime(e))" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
43219
+ [attr.aria-label]="itemLabel(e)" [title]="e.tooltip || e.title"
43220
+ (click)="onItemClick(e, $event)">
43221
+ <span class="chip-head">
43222
+ @if (e.iconPath) {
43223
+ <svg class="chip-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path [attr.d]="e.iconPath"/></svg>
43224
+ }
43225
+ @if (chipTime(e); as t) { <span class="chip-time">{{ t }}</span> }
43226
+ </span>
43227
+ <span class="chip-title" [class.strike]="e.strike">{{ e.title }}</span>
43228
+ @if (e.tag) { <span class="chip-src">{{ e.tag }}</span> }
43229
+ </button>
43230
+ </ng-template>
43231
+ <ng-template #allDayChip let-e>
43232
+ <button type="button" class="allday-chip" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
43233
+ [attr.aria-label]="itemLabel(e)" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">{{ e.title }}</button>
43234
+ </ng-template>
43235
+ <ng-template #timedEvent let-t let-wrapped="wrapped">
43236
+ <button type="button" class="timed-event"
43237
+ [class.in-wrap]="wrapped" [style.top.px]="wrapped ? null : t.top" [style.height.px]="wrapped ? null : t.height"
43238
+ [style.left]="wrapped ? null : 'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
43239
+ [style.width]="wrapped ? null : 'calc(' + (100 / t.lane.lanes) + '% - 4px)'"
43240
+ [style.background]="t.item.bgColor" [style.borderLeftColor]="t.item.color"
43241
+ [attr.aria-label]="itemLabel(t.item)" [attr.title]="t.item.tooltip || null" (click)="onItemClick(t.item, $event)">
43242
+ <span class="te-title" [class.strike]="t.item.strike">{{ t.item.title }}</span>
43243
+ @if (t.item.startTime) { <span class="te-time">{{ t.item.timeLabel || timeRange(t.item) }}</span> }
43244
+ </button>
43245
+ </ng-template>
43246
+ <ng-template #agendaRow let-e>
43247
+ <button type="button" class="agenda-event" [attr.aria-label]="e.ariaLabel || null" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">
43248
+ <span class="ae-color-bar" [style.background]="e.color"></span>
43249
+ <span class="ae-body">
43250
+ <span class="ae-top">
43251
+ <span class="ae-title" [class.strike]="e.strike">{{ e.title }}</span>
43252
+ @for (b of e.badges ?? []; track b.label) { <ui-badge [label]="b.label" [variant]="b.variant" /> }
43253
+ </span>
43254
+ @if (agendaMeta(e).length) {
43255
+ <span class="ae-meta">
43256
+ @for (m of agendaMeta(e); track $index) { <span class="ae-meta-item">{{ m }}</span> }
43257
+ </span>
43258
+ }
43259
+ </span>
43260
+ </button>
43261
+ </ng-template>
43262
+ <ng-template #agendaGroupTpl let-group>
43263
+ <div class="agenda-group">
43264
+ <div class="agenda-date-hdr">
43265
+ <span class="ag-dow">{{ agendaDow(group.dateStr) }}</span>
43266
+ <span class="ag-date">{{ agendaDate(group.dateStr) }}</span>
43267
+ @if (group.dateStr === todayStr()) { <ui-badge label="Today" variant="blue" /> }
43268
+ </div>
43269
+ <div class="agenda-events">
43270
+ @for (e of group.items; track e.id) {
43271
+ @if (actionsFor(e).length) {
43272
+ <div class="item-wrap agenda-wrap">
43273
+ <ng-container *ngTemplateOutlet="agendaRow; context: { $implicit: e }" />
43274
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43275
+ </div>
43276
+ } @else {
43277
+ <ng-container *ngTemplateOutlet="agendaRow; context: { $implicit: e }" />
43278
+ }
43279
+ }
43280
+ </div>
43281
+ </div>
43282
+
43283
+ </ng-template>
43284
+ <ng-template #itemActionsTpl let-e>
43285
+ <span class="item-actions" role="group" [attr.aria-label]="'Actions for ' + e.title" (keydown.escape)="onActionsEscape($event)">
43286
+ @for (a of actionsFor(e); track a.id) {
43287
+ <button type="button" class="item-action" [class.item-action--danger]="a.variant === 'danger'" [disabled]="!!a.disabled"
43288
+ [attr.aria-label]="a.label + ': ' + e.title" [attr.title]="a.label" (click)="onActionClick(e, a, $event)">
43289
+ @if (actionIconD(a); as d) {
43290
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="d" /></svg>
43291
+ } @else {
43292
+ <span class="item-action-text">{{ a.label }}</span>
43293
+ }
43294
+ </button>
43295
+ }
43296
+ </span>
43297
+ </ng-template>
43298
+
42377
43299
  <div class="cal-header">
42378
43300
  <div class="cal-toolbar">
42379
43301
  <div class="toolbar-left">
@@ -42457,6 +43379,8 @@ var CalendarComponent = class CalendarComponent {
42457
43379
  [class.clickable]="c.clickable"
42458
43380
  [attr.tabindex]="c.day.dateStr === focusDate() ? 0 : -1"
42459
43381
  [attr.aria-label]="c.label"
43382
+ [attr.data-level]="c.level"
43383
+ [uiTooltip]="c.tooltip"
42460
43384
  [attr.aria-current]="c.day.isToday ? 'date' : null"
42461
43385
  (click)="onDateClick(c.day.dateStr)"
42462
43386
  (focus)="focusedDate.set(c.day.dateStr)"
@@ -42464,18 +43388,14 @@ var CalendarComponent = class CalendarComponent {
42464
43388
  <span class="day-num" [class.today-badge]="c.day.isToday">{{ c.day.dayNum }}</span>
42465
43389
  <div class="cell-events">
42466
43390
  @for (e of c.visible; track e.id) {
42467
- <button type="button" class="event-chip" [class.stacked]="chipLayout() === 'stacked'" [class.has-head]="!!(e.iconPath || chipTime(e))" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
42468
- [attr.aria-label]="itemLabel(e)" [title]="e.tooltip || e.title"
42469
- (click)="onItemClick(e, $event)">
42470
- <span class="chip-head">
42471
- @if (e.iconPath) {
42472
- <svg class="chip-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path [attr.d]="e.iconPath"/></svg>
42473
- }
42474
- @if (chipTime(e); as t) { <span class="chip-time">{{ t }}</span> }
42475
- </span>
42476
- <span class="chip-title" [class.strike]="e.strike">{{ e.title }}</span>
42477
- @if (e.tag) { <span class="chip-src">{{ e.tag }}</span> }
42478
- </button>
43391
+ @if (actionsFor(e).length) {
43392
+ <div class="item-wrap">
43393
+ <ng-container *ngTemplateOutlet="monthChip; context: { $implicit: e }" />
43394
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43395
+ </div>
43396
+ } @else {
43397
+ <ng-container *ngTemplateOutlet="monthChip; context: { $implicit: e }" />
43398
+ }
42479
43399
  }
42480
43400
  @if (c.overflow > 0) {
42481
43401
  <button type="button" class="more-events" (click)="onMoreClick(c.day.dateStr, c.items, $event)">+{{ c.overflow }} more</button>
@@ -42493,9 +43413,10 @@ var CalendarComponent = class CalendarComponent {
42493
43413
  <div class="week-header">
42494
43414
  <div class="time-gutter"></div>
42495
43415
  @for (col of weekColumns(); track col.day.dateStr) {
42496
- <div class="week-day-hdr" [class.today]="col.day.isToday">
43416
+ <div class="week-day-hdr" [class.today]="col.day.isToday" [attr.data-level]="col.level" [uiTooltip]="col.tooltip">
42497
43417
  <span class="wdh-dow">{{ dowLabel(col.day.dateStr) }}</span>
42498
43418
  <span class="wdh-num" [class.today-badge]="col.day.isToday">{{ col.day.dayNum }}</span>
43419
+ @if (col.level) { <span class="deco-sr">{{ levelText(col.level) }}</span> }
42499
43420
  </div>
42500
43421
  }
42501
43422
  </div>
@@ -42507,8 +43428,14 @@ var CalendarComponent = class CalendarComponent {
42507
43428
  <button type="button" class="slot-add" [attr.aria-label]="'Add all-day event on ' + col.label" (click)="onAddAllDay(col.day.dateStr, $event)">+ Add</button>
42508
43429
  }
42509
43430
  @for (e of col.allDay; track e.id) {
42510
- <button type="button" class="allday-chip" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
42511
- [attr.aria-label]="itemLabel(e)" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">{{ e.title }}</button>
43431
+ @if (actionsFor(e).length) {
43432
+ <div class="item-wrap">
43433
+ <ng-container *ngTemplateOutlet="allDayChip; context: { $implicit: e }" />
43434
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43435
+ </div>
43436
+ } @else {
43437
+ <ng-container *ngTemplateOutlet="allDayChip; context: { $implicit: e }" />
43438
+ }
42512
43439
  }
42513
43440
  </div>
42514
43441
  }
@@ -42524,15 +43451,16 @@ var CalendarComponent = class CalendarComponent {
42524
43451
  }
42525
43452
  @for (h of hours(); track h) { <div class="time-slot"></div> }
42526
43453
  @for (t of col.timed; track t.item.id) {
42527
- <button type="button" class="timed-event"
42528
- [style.top.px]="t.top" [style.height.px]="t.height"
42529
- [style.left]="'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
42530
- [style.width]="'calc(' + (100 / t.lane.lanes) + '% - 4px)'"
42531
- [style.background]="t.item.bgColor" [style.borderLeftColor]="t.item.color"
42532
- [attr.aria-label]="itemLabel(t.item)" [attr.title]="t.item.tooltip || null" (click)="onItemClick(t.item, $event)">
42533
- <span class="te-title" [class.strike]="t.item.strike">{{ t.item.title }}</span>
42534
- @if (t.item.startTime) { <span class="te-time">{{ t.item.timeLabel || timeRange(t.item) }}</span> }
42535
- </button>
43454
+ @if (actionsFor(t.item).length) {
43455
+ <div class="item-wrap timed-wrap" [style.top.px]="t.top" [style.height.px]="t.height"
43456
+ [style.left]="'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
43457
+ [style.width]="'calc(' + (100 / t.lane.lanes) + '% - 4px)'">
43458
+ <ng-container *ngTemplateOutlet="timedEvent; context: { $implicit: t, wrapped: true }" />
43459
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: t.item }" />
43460
+ </div>
43461
+ } @else {
43462
+ <ng-container *ngTemplateOutlet="timedEvent; context: { $implicit: t, wrapped: false }" />
43463
+ }
42536
43464
  }
42537
43465
  </div>
42538
43466
  }
@@ -42544,32 +43472,25 @@ var CalendarComponent = class CalendarComponent {
42544
43472
  @if (agendaGroups().length === 0) {
42545
43473
  <ui-empty-state iconType="task" [message]="emptyMessage()" />
42546
43474
  }
42547
- @for (group of agendaGroups(); track group.dateStr) {
42548
- <div class="agenda-group">
42549
- <div class="agenda-date-hdr">
42550
- <span class="ag-dow">{{ agendaDow(group.dateStr) }}</span>
42551
- <span class="ag-date">{{ agendaDate(group.dateStr) }}</span>
42552
- @if (group.dateStr === todayStr()) { <ui-badge label="Today" variant="blue" /> }
42553
- </div>
42554
- <div class="agenda-events">
42555
- @for (e of group.items; track e.id) {
42556
- <button type="button" class="agenda-event" [attr.aria-label]="e.ariaLabel || null" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">
42557
- <span class="ae-color-bar" [style.background]="e.color"></span>
42558
- <span class="ae-body">
42559
- <span class="ae-top">
42560
- <span class="ae-title" [class.strike]="e.strike">{{ e.title }}</span>
42561
- @for (b of e.badges ?? []; track b.label) { <ui-badge [label]="b.label" [variant]="b.variant" /> }
42562
- </span>
42563
- @if (agendaMeta(e).length) {
42564
- <span class="ae-meta">
42565
- @for (m of agendaMeta(e); track $index) { <span class="ae-meta-item">{{ m }}</span> }
42566
- </span>
42567
- }
42568
- </span>
42569
- </button>
43475
+ @if (agendaSections(); as sections) {
43476
+ @for (s of sections; track $index) {
43477
+ @if (s.label) {
43478
+ <section class="agenda-section" [attr.aria-labelledby]="s.id">
43479
+ <h3 class="agenda-period-hdr" [id]="s.id">{{ s.label }}</h3>
43480
+ @for (group of s.groups; track group.dateStr) {
43481
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
43482
+ }
43483
+ </section>
43484
+ } @else {
43485
+ @for (group of s.groups; track group.dateStr) {
43486
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
42570
43487
  }
42571
- </div>
42572
- </div>
43488
+ }
43489
+ }
43490
+ } @else {
43491
+ @for (group of agendaGroups(); track group.dateStr) {
43492
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
43493
+ }
42573
43494
  }
42574
43495
  </div>
42575
43496
  }
@@ -42579,7 +43500,7 @@ var CalendarComponent = class CalendarComponent {
42579
43500
  <ui-toast />
42580
43501
  `,
42581
43502
  isInline: true,
42582
- styles: [":host{display:flex;flex-direction:column;gap:0;height:100%;min-height:0}.cal-header{background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 1px 2px #0f172a0a;margin-bottom:12px;flex-shrink:0}.cal-toolbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:18px 20px;gap:16px;flex-shrink:0}.toolbar-left{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;column-gap:20px;row-gap:8px;min-width:0}.toolbar-center{display:flex;align-items:center;justify-content:center;gap:10px}.toolbar-right{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}.toolbar-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:nowrap}.toolbar-actions:empty{display:none}ui-pill-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}@media(max-width:480px){.toolbar-actions{flex-wrap:wrap}}.period-label{font-size:2.5rem;font-weight:800;line-height:1.15;letter-spacing:-.025em;color:#0f172a;margin:0;min-width:0}.pl-sub{font-weight:600;color:#64748b}.nav-controls{display:inline-flex;align-items:center}.nav-controls>*+*{margin-left:-1px}.btn-nav{width:38px;height:38px;border:1px solid #cbd5e1;background:#fff;font-family:inherit;position:relative;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#475569;transition:background .12s,color .12s}.nav-controls>.btn-nav:first-child{border-radius:10px 0 0 10px}.nav-controls>.btn-nav:last-child{border-radius:0 10px 10px 0}.btn-today{padding:0 18px;height:38px;border:1px solid #cbd5e1;background:#fff;border-radius:0;font-family:inherit;position:relative;font-size:.9375rem;font-weight:600;color:#1d4ed8;cursor:pointer;transition:background .12s}.btn-nav:hover,.btn-today:hover{background:#eff6ff;color:#1d4ed8;z-index:1}.btn-nav:active,.btn-today:active{background:#dbeafe}.btn-nav:focus-visible,.btn-today:focus-visible,.filter-chip:focus-visible,.event-chip:focus-visible,.more-events:focus-visible,.allday-chip:focus-visible,.timed-event:focus-visible,.agenda-event:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.month-cell:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.slot-add:focus,.slot-add:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.mobile-summary{display:none}.filter-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 16px;padding:12px 20px 14px;border-top:1px solid #eef2f7;background:#f8fafc;border-radius:0 0 12px 12px;flex-shrink:0}.filter-main{display:flex;flex-direction:column;gap:8px;flex:1 1 auto;min-width:0}.filter-nav{margin-left:auto;flex-shrink:0}.filter-bar-label{font-size:.6875rem;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em}.filter-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.filter-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:20px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#475569;cursor:pointer;transition:all .12s;white-space:nowrap;font-family:inherit}.filter-chip:hover{border-color:#cbd5e1;background:#f8fafc}.filter-chip.active-all{background:#1e293b;color:#fff;border-color:#1e293b}.filter-chip.active-all .chip-count{background:#fff3;color:#fff}.filter-chip.active-type{background:var(--chip-bg, #f1f5f9);color:#1e293b;border-color:var(--chip-color);font-weight:600}.filter-chip.active-type .chip-count{background:var(--chip-color);color:#fff}.chip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.chip-count{font-size:.6875rem;font-weight:700;background:#f1f5f9;background:color-mix(in srgb,var(--chip-color, #64748b) 14%,#fff);color:#475569;padding:1px 8px;border-radius:999px;min-width:18px;text-align:center;box-sizing:border-box}.cal-skeleton,.outline-grid,.month-view,.week-view,.agenda-view{flex:1;display:flex;flex-direction:column;min-height:0;background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.skel-dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;padding:12px 10px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.skel-dow{display:flex;justify-content:center}.skel-month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,minmax(80px,1fr));flex:1}.skel-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:8px 6px;display:flex;flex-direction:column;gap:6px}.skel-cell:nth-child(7n){border-right:none}.cal-outline{flex:1;display:flex;flex-direction:column;min-height:0}.cal-outline ui-skeleton{display:block;flex-shrink:0}.skel-period-wrap{width:240px;max-width:100%;min-width:0}.skel-nav-controls{gap:2px}.skel-nav-controls>*+*{margin-left:0}.skel-tabs{display:flex;align-items:center;gap:6px}.skel-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}.skel-week-grid{display:grid;grid-template-columns:repeat(7,1fr);flex:1;min-height:360px}.skel-agenda{display:flex;flex-direction:column;flex:1}.skel-row{display:flex;align-items:center;gap:16px;padding:16px 12px;border-bottom:1px solid #f1f5f9}.skel-row-body{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0}.month-grid{display:flex;flex-direction:column;flex:1;min-height:0;overflow:auto}.month-header{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;position:sticky;top:0;z-index:1}.month-dow{padding:10px 8px;font-size:.75rem;font-weight:600;color:#6b7280;text-align:center;text-transform:uppercase;letter-spacing:.04em}.dow-short{display:none}.month-row{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));flex:1 0 120px}.month-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:6px 6px 4px;min-height:120px;transition:background .1s;min-width:0;box-sizing:border-box}.month-cell.clickable{cursor:pointer}.month-cell.clickable:hover{background:#f8fafc}.month-cell:nth-child(7n){border-right:none}.month-cell.other-month{background:#fafafa}.month-cell.other-month .day-num{color:#64748b}.month-cell.today{background:#eff6ff}.day-num{display:inline-block;width:26px;height:26px;line-height:26px;text-align:center;border-radius:50%;font-size:.8125rem;font-weight:500;color:#374151;margin-bottom:4px}.today-badge{background:#2563eb;color:#fff;font-weight:700}.cell-events{display:flex;flex-direction:column;gap:2px}.event-chip{display:flex;align-items:center;gap:3px;padding:2px 6px;width:100%;box-sizing:border-box;text-align:left;font-family:inherit;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;cursor:pointer;overflow:hidden}.event-chip:hover{opacity:.85}.event-chip.stacked{flex-direction:column;align-items:flex-start;gap:0}.chip-head{display:inline-flex;align-items:center;gap:3px;flex-shrink:0}.chip-icon{flex-shrink:0}.chip-time{font-weight:700;flex-shrink:0;color:#1e293b}.chip-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#1e293b;min-width:0;max-width:100%}.strike{text-decoration:line-through}.chip-src{font-size:.625rem;font-weight:700;margin-left:auto;flex-shrink:0;color:#1e293b}.more-events{font-size:.6875rem;color:#2563eb;font-weight:600;cursor:pointer;padding:1px 6px;border:0;background:none;text-align:left;font-family:inherit}.more-events:hover{text-decoration:underline}.week-view{overflow:auto}.week-header{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;overflow-y:scroll}.time-gutter{border-right:1px solid #e2e8f0}.week-day-hdr{display:flex;flex-direction:column;align-items:center;padding:10px 4px;border-right:1px solid #f1f5f9}.week-day-hdr.today{background:#eff6ff}.week-day-hdr:last-child{border-right:none}.wdh-dow{font-size:.6875rem;font-weight:600;color:#6b7280;text-transform:uppercase}.wdh-num{width:28px;height:28px;line-height:28px;text-align:center;border-radius:50%;font-size:.9375rem;font-weight:600;color:#374151;margin-top:2px}.wdh-num.today-badge{background:#2563eb;color:#fff;font-weight:700}.allday-row{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;min-height:32px;flex-shrink:0;overflow-y:scroll}.allday-label{font-size:.625rem;color:#64748b;font-weight:600;text-transform:uppercase;display:flex;align-items:center;justify-content:center}.slot-add{position:absolute;top:2px;left:2px;z-index:3;width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap;font-family:inherit}.slot-add:focus,.slot-add:focus-visible{width:auto;height:auto;padding:2px 8px;clip-path:none;background:#1e293b;color:#fff;border-radius:4px;font-size:.75rem;font-weight:600}.allday-cell{position:relative;border-right:1px solid #f1f5f9;padding:3px 4px;display:flex;flex-direction:column;gap:2px;min-width:0}.allday-cell.clickable{cursor:pointer}.allday-cell:last-child{border-right:none}.allday-chip{padding:2px 6px;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;color:#1e293b;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left;font-family:inherit}.allday-chip:hover{opacity:.85}.week-body{display:grid;grid-template-columns:60px repeat(7,1fr);flex:1;overflow-y:scroll}.time-col{display:flex;flex-direction:column;border-right:1px solid #e2e8f0;flex-shrink:0}.time-slot-label{height:60px;display:flex;align-items:flex-start;justify-content:flex-end;padding:4px 8px 0 0;font-size:.6875rem;color:#64748b;font-weight:500;border-bottom:1px solid #f1f5f9;flex-shrink:0;box-sizing:border-box}.day-col{position:relative;border-right:1px solid #f1f5f9;min-width:0}.day-col.clickable{cursor:pointer}.day-col:last-child{border-right:none}.day-col.today{background:#fafbff}.time-slot{height:60px;border-bottom:1px solid #f1f5f9;box-sizing:border-box}.day-col.clickable .time-slot:hover{background:#f8fafc}.timed-event{position:absolute;min-height:20px;border:0;border-radius:6px;padding:3px 6px;overflow:hidden;cursor:pointer;box-sizing:border-box;border-left:3px solid transparent;display:flex;flex-direction:column;align-items:flex-start;gap:1px;box-shadow:0 1px 3px #00000014;text-align:left;font-family:inherit}.timed-event:hover{opacity:.85}.te-title{font-size:.6875rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.te-time{font-size:.625rem;color:#475569}.agenda-view{overflow-y:auto}.agenda-group{display:flex;border-bottom:1px solid #f1f5f9}.agenda-date-hdr{width:100px;flex-shrink:0;padding:16px 12px;display:flex;flex-direction:column;gap:4px;background:#f8fafc;border-right:2px solid #e2e8f0}.ag-dow{font-size:.6875rem;font-weight:700;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.ag-date{font-size:.8125rem;font-weight:600;color:#374151}.agenda-events{flex:1;display:flex;flex-direction:column;min-width:0}.agenda-event{display:flex;align-items:stretch;padding:10px 12px;cursor:pointer;border:0;border-bottom:1px solid #f8fafc;background:none;text-align:left;width:100%;font-family:inherit;transition:background .1s}.agenda-event:hover{background:#f8fafc}.agenda-event:last-child{border-bottom:none}.ae-color-bar{display:block;width:4px;border-radius:4px;flex-shrink:0;margin-right:12px}.ae-body{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.ae-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.ae-title{font-size:.9375rem;font-weight:600;color:#111827}.ae-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.ae-meta-item{font-size:.8125rem;color:#6b7280}@media(prefers-reduced-motion:reduce){.btn-nav,.btn-today,.filter-chip,.month-cell,.agenda-event{transition:none}}@media(pointer:coarse),(max-width:480px){.btn-nav,.btn-today,.filter-chip,.event-chip,.more-events,.allday-chip,.agenda-event{min-height:44px}.btn-nav{min-width:44px}}@media(max-width:768px){.cal-toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 12px}.toolbar-left{flex:1 1 auto}.toolbar-right{flex:0 1 auto;min-width:0;max-width:100%}.toolbar-center{display:none}.period-label{font-size:1.875rem}.toolbar-right{justify-content:flex-end}.mobile-summary{display:block;margin-bottom:4px;flex-shrink:0}.mobile-summary:empty{display:none}.filter-chips{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}.filter-main{flex-basis:100%}.month-view,.cal-skeleton,.outline-grid,.week-view{overflow-x:auto;-webkit-overflow-scrolling:touch}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:560px}.month-row{flex-basis:80px}.month-cell{min-height:80px}.week-header,.allday-row,.week-body{min-width:640px}.agenda-date-hdr{width:76px;padding:12px 8px}.ae-title{font-size:.875rem}}@media(max-width:640px){.event-chip.stacked.has-head .chip-title{display:none}}@media(max-width:640px){.cal-toolbar{padding:14px}.period-label{font-size:1.625rem}.filter-bar{padding:10px 14px 12px}.filter-nav{width:100%;margin-left:0}.filter-nav .nav-controls{display:flex;width:100%}.filter-nav .btn-today{flex:1 1 auto}.chip-head{flex-wrap:wrap;row-gap:0;flex-shrink:1;min-width:0}.chip-time{white-space:normal;line-height:1.1;flex-shrink:1;min-width:0;overflow-wrap:anywhere}.event-chip.stacked{flex-wrap:nowrap}.month-view,.cal-skeleton,.outline-grid{overflow-x:hidden}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:0}.month-dow{padding:8px 2px;font-size:.6875rem;letter-spacing:0}.month-row{flex-basis:72px}.month-cell{min-height:72px;padding:3px 2px 2px}.day-num{width:22px;height:22px;line-height:22px;font-size:.75rem;margin-bottom:2px}.cell-events{gap:1px}.event-chip{min-height:24px;padding:1px 3px;font-size:.625rem;gap:2px}.more-events{min-height:24px;padding:1px 3px;font-size:.625rem;white-space:normal;line-height:1.1;max-width:100%}}@media(max-width:480px){.dow-full{display:none}.dow-short{display:inline}}\n"],
43503
+ styles: [":host{display:flex;flex-direction:column;gap:0;height:100%;min-height:0}.cal-header{background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 1px 2px #0f172a0a;margin-bottom:12px;flex-shrink:0}.cal-toolbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:18px 20px;gap:16px;flex-shrink:0}.toolbar-left{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;column-gap:20px;row-gap:8px;min-width:0}.toolbar-center{display:flex;align-items:center;justify-content:center;gap:10px}.toolbar-right{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}.toolbar-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:nowrap}.toolbar-actions:empty{display:none}ui-pill-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}@media(max-width:480px){.toolbar-actions{flex-wrap:wrap}}.period-label{font-size:2.5rem;font-weight:800;line-height:1.15;letter-spacing:-.025em;color:#0f172a;margin:0;min-width:0}.pl-sub{font-weight:600;color:#64748b}.nav-controls{display:inline-flex;align-items:center}.nav-controls>*+*{margin-left:-1px}.btn-nav{width:38px;height:38px;border:1px solid #cbd5e1;background:#fff;font-family:inherit;position:relative;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#475569;transition:background .12s,color .12s}.nav-controls>.btn-nav:first-child{border-radius:10px 0 0 10px}.nav-controls>.btn-nav:last-child{border-radius:0 10px 10px 0}.btn-today{padding:0 18px;height:38px;border:1px solid #cbd5e1;background:#fff;border-radius:0;font-family:inherit;position:relative;font-size:.9375rem;font-weight:600;color:#1d4ed8;cursor:pointer;transition:background .12s}.btn-nav:hover,.btn-today:hover{background:#eff6ff;color:#1d4ed8;z-index:1}.btn-nav:active,.btn-today:active{background:#dbeafe}.btn-nav:focus-visible,.btn-today:focus-visible,.filter-chip:focus-visible,.event-chip:focus-visible,.more-events:focus-visible,.allday-chip:focus-visible,.timed-event:focus-visible,.agenda-event:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.month-cell:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.slot-add:focus,.slot-add:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.mobile-summary{display:none}.filter-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 16px;padding:12px 20px 14px;border-top:1px solid #eef2f7;background:#f8fafc;border-radius:0 0 12px 12px;flex-shrink:0}.filter-main{display:flex;flex-direction:column;gap:8px;flex:1 1 auto;min-width:0}.filter-nav{margin-left:auto;flex-shrink:0}.filter-bar-label{font-size:.6875rem;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em}.filter-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.filter-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:20px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#475569;cursor:pointer;transition:all .12s;white-space:nowrap;font-family:inherit}.filter-chip:hover{border-color:#cbd5e1;background:#f8fafc}.filter-chip.active-all{background:#1e293b;color:#fff;border-color:#1e293b}.filter-chip.active-all .chip-count{background:#fff3;color:#fff}.filter-chip.active-type{background:var(--chip-bg, #f1f5f9);color:#1e293b;border-color:var(--chip-color);font-weight:600}.filter-chip.active-type .chip-count{background:var(--chip-color);color:#fff}.chip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.chip-count{font-size:.6875rem;font-weight:700;background:#f1f5f9;background:color-mix(in srgb,var(--chip-color, #64748b) 14%,#fff);color:#475569;padding:1px 8px;border-radius:999px;min-width:18px;text-align:center;box-sizing:border-box}.cal-skeleton,.outline-grid,.month-view,.week-view,.agenda-view{flex:1;display:flex;flex-direction:column;min-height:0;background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.skel-dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;padding:12px 10px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.skel-dow{display:flex;justify-content:center}.skel-month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,minmax(80px,1fr));flex:1}.skel-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:8px 6px;display:flex;flex-direction:column;gap:6px}.skel-cell:nth-child(7n){border-right:none}.cal-outline{flex:1;display:flex;flex-direction:column;min-height:0}.cal-outline ui-skeleton{display:block;flex-shrink:0}.skel-period-wrap{width:240px;max-width:100%;min-width:0}.skel-nav-controls{gap:2px}.skel-nav-controls>*+*{margin-left:0}.skel-tabs{display:flex;align-items:center;gap:6px}.skel-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}.skel-week-grid{display:grid;grid-template-columns:repeat(7,1fr);flex:1;min-height:360px}.skel-agenda{display:flex;flex-direction:column;flex:1}.skel-row{display:flex;align-items:center;gap:16px;padding:16px 12px;border-bottom:1px solid #f1f5f9}.skel-row-body{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0}.month-grid{display:flex;flex-direction:column;flex:1;min-height:0;overflow:auto}.month-header{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;position:sticky;top:0;z-index:1}.month-dow{padding:10px 8px;font-size:.75rem;font-weight:600;color:#6b7280;text-align:center;text-transform:uppercase;letter-spacing:.04em}.dow-short{display:none}.month-row{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));flex:1 0 120px}.month-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:6px 6px 4px;min-height:120px;transition:background .1s;min-width:0;box-sizing:border-box}.month-cell.clickable{cursor:pointer}.month-cell.clickable:hover{background:#f8fafc}.month-cell:nth-child(7n){border-right:none}.month-cell.other-month{background:#fafafa}.month-cell.other-month .day-num{color:#64748b}.month-cell[data-level=low]{background:#f0fdf4;box-shadow:inset 0 3px #86efac}.month-cell[data-level=medium]{background:#fefce8;box-shadow:inset 0 3px #facc15}.month-cell[data-level=high]{background:#fff7ed;box-shadow:inset 0 3px #fb923c}.month-cell[data-level=critical]{background:#fef2f2;box-shadow:inset 0 3px #ef4444}.month-cell.other-month[data-level] .day-num{color:#475569}.month-cell.today{background:#eff6ff}.day-num{display:inline-block;width:26px;height:26px;line-height:26px;text-align:center;border-radius:50%;font-size:.8125rem;font-weight:500;color:#374151;margin-bottom:4px}.today-badge{background:#2563eb;color:#fff;font-weight:700}.cell-events{display:flex;flex-direction:column;gap:2px}.event-chip{display:flex;align-items:center;gap:3px;padding:2px 6px;width:100%;box-sizing:border-box;text-align:left;font-family:inherit;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;cursor:pointer;overflow:hidden}.event-chip:hover{opacity:.85}.event-chip.stacked{flex-direction:column;align-items:flex-start;gap:0}.chip-head{display:inline-flex;align-items:center;gap:3px;flex-shrink:0}.chip-icon{flex-shrink:0}.chip-time{font-weight:700;flex-shrink:0;color:#1e293b}.chip-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#1e293b;min-width:0;max-width:100%}.strike{text-decoration:line-through}.chip-src{font-size:.625rem;font-weight:700;margin-left:auto;flex-shrink:0;color:#1e293b}.more-events{font-size:.6875rem;color:#2563eb;font-weight:600;cursor:pointer;padding:1px 6px;border:0;background:none;text-align:left;font-family:inherit}.more-events:hover{text-decoration:underline}.week-view{overflow:auto}.week-header{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;overflow-y:scroll}.time-gutter{border-right:1px solid #e2e8f0}.week-day-hdr{display:flex;flex-direction:column;align-items:center;padding:10px 4px;border-right:1px solid #f1f5f9}.week-day-hdr[data-level=low]{background:#f0fdf4;box-shadow:inset 0 3px #86efac}.week-day-hdr[data-level=medium]{background:#fefce8;box-shadow:inset 0 3px #facc15}.week-day-hdr[data-level=high]{background:#fff7ed;box-shadow:inset 0 3px #fb923c}.week-day-hdr[data-level=critical]{background:#fef2f2;box-shadow:inset 0 3px #ef4444}.week-day-hdr.today{background:#eff6ff}.deco-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);border:0;white-space:nowrap}.week-day-hdr:last-child{border-right:none}.wdh-dow{font-size:.6875rem;font-weight:600;color:#6b7280;text-transform:uppercase}.wdh-num{width:28px;height:28px;line-height:28px;text-align:center;border-radius:50%;font-size:.9375rem;font-weight:600;color:#374151;margin-top:2px}.wdh-num.today-badge{background:#2563eb;color:#fff;font-weight:700}.allday-row{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;min-height:32px;flex-shrink:0;overflow-y:scroll}.allday-label{font-size:.625rem;color:#64748b;font-weight:600;text-transform:uppercase;display:flex;align-items:center;justify-content:center}.slot-add{position:absolute;top:2px;left:2px;z-index:3;width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap;font-family:inherit}.slot-add:focus,.slot-add:focus-visible{width:auto;height:auto;padding:2px 8px;clip-path:none;background:#1e293b;color:#fff;border-radius:4px;font-size:.75rem;font-weight:600}.allday-cell{position:relative;border-right:1px solid #f1f5f9;padding:3px 4px;display:flex;flex-direction:column;gap:2px;min-width:0}.allday-cell.clickable{cursor:pointer}.allday-cell:last-child{border-right:none}.allday-chip{padding:2px 6px;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;color:#1e293b;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left;font-family:inherit}.allday-chip:hover{opacity:.85}.week-body{display:grid;grid-template-columns:60px repeat(7,1fr);flex:1;overflow-y:scroll}.time-col{display:flex;flex-direction:column;border-right:1px solid #e2e8f0;flex-shrink:0}.time-slot-label{height:60px;display:flex;align-items:flex-start;justify-content:flex-end;padding:4px 8px 0 0;font-size:.6875rem;color:#64748b;font-weight:500;border-bottom:1px solid #f1f5f9;flex-shrink:0;box-sizing:border-box}.day-col{position:relative;border-right:1px solid #f1f5f9;min-width:0}.day-col.clickable{cursor:pointer}.day-col:last-child{border-right:none}.day-col.today{background:#fafbff}.time-slot{height:60px;border-bottom:1px solid #f1f5f9;box-sizing:border-box}.day-col.clickable .time-slot:hover{background:#f8fafc}.timed-event{position:absolute;min-height:20px;border:0;border-radius:6px;padding:3px 6px;overflow:hidden;cursor:pointer;box-sizing:border-box;border-left:3px solid transparent;display:flex;flex-direction:column;align-items:flex-start;gap:1px;box-shadow:0 1px 3px #00000014;text-align:left;font-family:inherit}.timed-event:hover{opacity:.85}.te-title{font-size:.6875rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.te-time{font-size:.625rem;color:#475569}.agenda-view{overflow-y:auto}.agenda-section{display:block}.agenda-period-hdr{margin:0;padding:8px 12px;font-size:.75rem;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:.06em;background:#f1f5f9;border-bottom:1px solid #e2e8f0;position:-webkit-sticky;position:sticky;top:0;z-index:1}.agenda-group{display:flex;border-bottom:1px solid #f1f5f9}.agenda-date-hdr{width:100px;flex-shrink:0;padding:16px 12px;display:flex;flex-direction:column;gap:4px;background:#f8fafc;border-right:2px solid #e2e8f0}.ag-dow{font-size:.6875rem;font-weight:700;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.ag-date{font-size:.8125rem;font-weight:600;color:#374151}.agenda-events{flex:1;display:flex;flex-direction:column;min-width:0}.agenda-event{display:flex;align-items:stretch;padding:10px 12px;cursor:pointer;border:0;border-bottom:1px solid #f8fafc;background:none;text-align:left;width:100%;font-family:inherit;transition:background .1s}.agenda-event:hover{background:#f8fafc}.agenda-event:last-child{border-bottom:none}.ae-color-bar{display:block;width:4px;border-radius:4px;flex-shrink:0;margin-right:12px}.ae-body{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.ae-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.ae-title{font-size:.9375rem;font-weight:600;color:#111827}.ae-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.ae-meta-item{font-size:.8125rem;color:#6b7280}.item-wrap{position:relative;display:block;min-width:0}.item-wrap.timed-wrap{position:absolute;min-height:20px}.timed-event.in-wrap{position:static;width:100%;height:100%}.item-actions{position:absolute;top:50%;right:2px;transform:translateY(-50%);display:inline-flex;gap:2px;opacity:0;pointer-events:none;z-index:2}.item-wrap:hover>.item-actions,.item-wrap:focus-within>.item-actions{opacity:1;pointer-events:auto}.agenda-wrap>.item-actions{right:12px}.item-action{min-width:20px;height:20px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:.6875rem;font-weight:600;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer}.item-action:hover:not(:disabled){background:#eff6ff;color:#1d4ed8}.item-action--danger{color:#b91c1c;border-color:#fecaca}.item-action--danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.item-action:disabled{opacity:.5;cursor:not-allowed}.item-action:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}@media(hover:none){.agenda-wrap>.item-actions{opacity:1;pointer-events:auto}}@media(pointer:coarse),(max-width:480px){.item-action{min-width:44px;min-height:44px}}@media(prefers-reduced-motion:reduce){.btn-nav,.btn-today,.filter-chip,.month-cell,.agenda-event{transition:none}}@media(pointer:coarse),(max-width:480px){.btn-nav,.btn-today,.filter-chip,.event-chip,.more-events,.allday-chip,.agenda-event{min-height:44px}.btn-nav{min-width:44px}}@media(max-width:768px){.cal-toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 12px}.toolbar-left{flex:1 1 auto}.toolbar-right{flex:0 1 auto;min-width:0;max-width:100%}.toolbar-center{display:none}.period-label{font-size:1.875rem}.toolbar-right{justify-content:flex-end}.mobile-summary{display:block;margin-bottom:4px;flex-shrink:0}.mobile-summary:empty{display:none}.filter-chips{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}.filter-main{flex-basis:100%}.month-view,.cal-skeleton,.outline-grid,.week-view{overflow-x:auto;-webkit-overflow-scrolling:touch}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:560px}.month-row{flex-basis:80px}.month-cell{min-height:80px}.week-header,.allday-row,.week-body{min-width:640px}.agenda-date-hdr{width:76px;padding:12px 8px}.ae-title{font-size:.875rem}}@media(max-width:640px){.event-chip.stacked.has-head .chip-title{display:none}}@media(max-width:640px){.cal-toolbar{padding:14px}.period-label{font-size:1.625rem}.filter-bar{padding:10px 14px 12px}.filter-nav{width:100%;margin-left:0}.filter-nav .nav-controls{display:flex;width:100%}.filter-nav .btn-today{flex:1 1 auto}.chip-head{flex-wrap:wrap;row-gap:0;flex-shrink:1;min-width:0}.chip-time{white-space:normal;line-height:1.1;flex-shrink:1;min-width:0;overflow-wrap:anywhere}.event-chip.stacked{flex-wrap:nowrap}.month-view,.cal-skeleton,.outline-grid{overflow-x:hidden}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:0}.month-dow{padding:8px 2px;font-size:.6875rem;letter-spacing:0}.month-row{flex-basis:72px}.month-cell{min-height:72px;padding:3px 2px 2px}.day-num{width:22px;height:22px;line-height:22px;font-size:.75rem;margin-bottom:2px}.cell-events{gap:1px}.event-chip{min-height:24px;padding:1px 3px;font-size:.625rem;gap:2px}.more-events{min-height:24px;padding:1px 3px;font-size:.625rem;white-space:normal;line-height:1.1;max-width:100%}}@media(max-width:480px){.dow-full{display:none}.dow-short{display:inline}}\n"],
42583
43504
  dependencies: [
42584
43505
  {
42585
43506
  kind: "component",
@@ -42638,6 +43559,12 @@ var CalendarComponent = class CalendarComponent {
42638
43559
  type: ToastComponent,
42639
43560
  selector: "ui-toast",
42640
43561
  inputs: ["dismissible", "persistentLiveRegion"]
43562
+ },
43563
+ {
43564
+ kind: "directive",
43565
+ type: TooltipDirective,
43566
+ selector: "[uiTooltip]",
43567
+ inputs: ["uiTooltip", "tooltipPosition"]
42641
43568
  }
42642
43569
  ],
42643
43570
  changeDetection: i0.ChangeDetectionStrategy.OnPush
@@ -42661,7 +43588,8 @@ i0.ɵɵngDeclareClassMetadata({
42661
43588
  NgTemplateOutlet,
42662
43589
  PillTabsComponent,
42663
43590
  SkeletonComponent,
42664
- ToastComponent
43591
+ ToastComponent,
43592
+ TooltipDirective
42665
43593
  ],
42666
43594
  template: `
42667
43595
  @if (showOutline()) {
@@ -42768,6 +43696,90 @@ i0.ɵɵngDeclareClassMetadata({
42768
43696
  </div>
42769
43697
  </ng-template>
42770
43698
 
43699
+ <!-- Shared item markup: the same button is drawn on its own or, when itemActionsFn offers actions, inside a wrapper next to the action buttons
43700
+ (a button can never contain buttons). -->
43701
+ <ng-template #monthChip let-e>
43702
+ <button type="button" class="event-chip" [class.stacked]="chipLayout() === 'stacked'" [class.has-head]="!!(e.iconPath || chipTime(e))" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
43703
+ [attr.aria-label]="itemLabel(e)" [title]="e.tooltip || e.title"
43704
+ (click)="onItemClick(e, $event)">
43705
+ <span class="chip-head">
43706
+ @if (e.iconPath) {
43707
+ <svg class="chip-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path [attr.d]="e.iconPath"/></svg>
43708
+ }
43709
+ @if (chipTime(e); as t) { <span class="chip-time">{{ t }}</span> }
43710
+ </span>
43711
+ <span class="chip-title" [class.strike]="e.strike">{{ e.title }}</span>
43712
+ @if (e.tag) { <span class="chip-src">{{ e.tag }}</span> }
43713
+ </button>
43714
+ </ng-template>
43715
+ <ng-template #allDayChip let-e>
43716
+ <button type="button" class="allday-chip" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
43717
+ [attr.aria-label]="itemLabel(e)" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">{{ e.title }}</button>
43718
+ </ng-template>
43719
+ <ng-template #timedEvent let-t let-wrapped="wrapped">
43720
+ <button type="button" class="timed-event"
43721
+ [class.in-wrap]="wrapped" [style.top.px]="wrapped ? null : t.top" [style.height.px]="wrapped ? null : t.height"
43722
+ [style.left]="wrapped ? null : 'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
43723
+ [style.width]="wrapped ? null : 'calc(' + (100 / t.lane.lanes) + '% - 4px)'"
43724
+ [style.background]="t.item.bgColor" [style.borderLeftColor]="t.item.color"
43725
+ [attr.aria-label]="itemLabel(t.item)" [attr.title]="t.item.tooltip || null" (click)="onItemClick(t.item, $event)">
43726
+ <span class="te-title" [class.strike]="t.item.strike">{{ t.item.title }}</span>
43727
+ @if (t.item.startTime) { <span class="te-time">{{ t.item.timeLabel || timeRange(t.item) }}</span> }
43728
+ </button>
43729
+ </ng-template>
43730
+ <ng-template #agendaRow let-e>
43731
+ <button type="button" class="agenda-event" [attr.aria-label]="e.ariaLabel || null" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">
43732
+ <span class="ae-color-bar" [style.background]="e.color"></span>
43733
+ <span class="ae-body">
43734
+ <span class="ae-top">
43735
+ <span class="ae-title" [class.strike]="e.strike">{{ e.title }}</span>
43736
+ @for (b of e.badges ?? []; track b.label) { <ui-badge [label]="b.label" [variant]="b.variant" /> }
43737
+ </span>
43738
+ @if (agendaMeta(e).length) {
43739
+ <span class="ae-meta">
43740
+ @for (m of agendaMeta(e); track $index) { <span class="ae-meta-item">{{ m }}</span> }
43741
+ </span>
43742
+ }
43743
+ </span>
43744
+ </button>
43745
+ </ng-template>
43746
+ <ng-template #agendaGroupTpl let-group>
43747
+ <div class="agenda-group">
43748
+ <div class="agenda-date-hdr">
43749
+ <span class="ag-dow">{{ agendaDow(group.dateStr) }}</span>
43750
+ <span class="ag-date">{{ agendaDate(group.dateStr) }}</span>
43751
+ @if (group.dateStr === todayStr()) { <ui-badge label="Today" variant="blue" /> }
43752
+ </div>
43753
+ <div class="agenda-events">
43754
+ @for (e of group.items; track e.id) {
43755
+ @if (actionsFor(e).length) {
43756
+ <div class="item-wrap agenda-wrap">
43757
+ <ng-container *ngTemplateOutlet="agendaRow; context: { $implicit: e }" />
43758
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43759
+ </div>
43760
+ } @else {
43761
+ <ng-container *ngTemplateOutlet="agendaRow; context: { $implicit: e }" />
43762
+ }
43763
+ }
43764
+ </div>
43765
+ </div>
43766
+
43767
+ </ng-template>
43768
+ <ng-template #itemActionsTpl let-e>
43769
+ <span class="item-actions" role="group" [attr.aria-label]="'Actions for ' + e.title" (keydown.escape)="onActionsEscape($event)">
43770
+ @for (a of actionsFor(e); track a.id) {
43771
+ <button type="button" class="item-action" [class.item-action--danger]="a.variant === 'danger'" [disabled]="!!a.disabled"
43772
+ [attr.aria-label]="a.label + ': ' + e.title" [attr.title]="a.label" (click)="onActionClick(e, a, $event)">
43773
+ @if (actionIconD(a); as d) {
43774
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="d" /></svg>
43775
+ } @else {
43776
+ <span class="item-action-text">{{ a.label }}</span>
43777
+ }
43778
+ </button>
43779
+ }
43780
+ </span>
43781
+ </ng-template>
43782
+
42771
43783
  <div class="cal-header">
42772
43784
  <div class="cal-toolbar">
42773
43785
  <div class="toolbar-left">
@@ -42851,6 +43863,8 @@ i0.ɵɵngDeclareClassMetadata({
42851
43863
  [class.clickable]="c.clickable"
42852
43864
  [attr.tabindex]="c.day.dateStr === focusDate() ? 0 : -1"
42853
43865
  [attr.aria-label]="c.label"
43866
+ [attr.data-level]="c.level"
43867
+ [uiTooltip]="c.tooltip"
42854
43868
  [attr.aria-current]="c.day.isToday ? 'date' : null"
42855
43869
  (click)="onDateClick(c.day.dateStr)"
42856
43870
  (focus)="focusedDate.set(c.day.dateStr)"
@@ -42858,18 +43872,14 @@ i0.ɵɵngDeclareClassMetadata({
42858
43872
  <span class="day-num" [class.today-badge]="c.day.isToday">{{ c.day.dayNum }}</span>
42859
43873
  <div class="cell-events">
42860
43874
  @for (e of c.visible; track e.id) {
42861
- <button type="button" class="event-chip" [class.stacked]="chipLayout() === 'stacked'" [class.has-head]="!!(e.iconPath || chipTime(e))" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
42862
- [attr.aria-label]="itemLabel(e)" [title]="e.tooltip || e.title"
42863
- (click)="onItemClick(e, $event)">
42864
- <span class="chip-head">
42865
- @if (e.iconPath) {
42866
- <svg class="chip-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path [attr.d]="e.iconPath"/></svg>
42867
- }
42868
- @if (chipTime(e); as t) { <span class="chip-time">{{ t }}</span> }
42869
- </span>
42870
- <span class="chip-title" [class.strike]="e.strike">{{ e.title }}</span>
42871
- @if (e.tag) { <span class="chip-src">{{ e.tag }}</span> }
42872
- </button>
43875
+ @if (actionsFor(e).length) {
43876
+ <div class="item-wrap">
43877
+ <ng-container *ngTemplateOutlet="monthChip; context: { $implicit: e }" />
43878
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43879
+ </div>
43880
+ } @else {
43881
+ <ng-container *ngTemplateOutlet="monthChip; context: { $implicit: e }" />
43882
+ }
42873
43883
  }
42874
43884
  @if (c.overflow > 0) {
42875
43885
  <button type="button" class="more-events" (click)="onMoreClick(c.day.dateStr, c.items, $event)">+{{ c.overflow }} more</button>
@@ -42887,9 +43897,10 @@ i0.ɵɵngDeclareClassMetadata({
42887
43897
  <div class="week-header">
42888
43898
  <div class="time-gutter"></div>
42889
43899
  @for (col of weekColumns(); track col.day.dateStr) {
42890
- <div class="week-day-hdr" [class.today]="col.day.isToday">
43900
+ <div class="week-day-hdr" [class.today]="col.day.isToday" [attr.data-level]="col.level" [uiTooltip]="col.tooltip">
42891
43901
  <span class="wdh-dow">{{ dowLabel(col.day.dateStr) }}</span>
42892
43902
  <span class="wdh-num" [class.today-badge]="col.day.isToday">{{ col.day.dayNum }}</span>
43903
+ @if (col.level) { <span class="deco-sr">{{ levelText(col.level) }}</span> }
42893
43904
  </div>
42894
43905
  }
42895
43906
  </div>
@@ -42901,8 +43912,14 @@ i0.ɵɵngDeclareClassMetadata({
42901
43912
  <button type="button" class="slot-add" [attr.aria-label]="'Add all-day event on ' + col.label" (click)="onAddAllDay(col.day.dateStr, $event)">+ Add</button>
42902
43913
  }
42903
43914
  @for (e of col.allDay; track e.id) {
42904
- <button type="button" class="allday-chip" [style.background]="e.bgColor" [style.borderLeftColor]="e.color"
42905
- [attr.aria-label]="itemLabel(e)" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">{{ e.title }}</button>
43915
+ @if (actionsFor(e).length) {
43916
+ <div class="item-wrap">
43917
+ <ng-container *ngTemplateOutlet="allDayChip; context: { $implicit: e }" />
43918
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: e }" />
43919
+ </div>
43920
+ } @else {
43921
+ <ng-container *ngTemplateOutlet="allDayChip; context: { $implicit: e }" />
43922
+ }
42906
43923
  }
42907
43924
  </div>
42908
43925
  }
@@ -42918,15 +43935,16 @@ i0.ɵɵngDeclareClassMetadata({
42918
43935
  }
42919
43936
  @for (h of hours(); track h) { <div class="time-slot"></div> }
42920
43937
  @for (t of col.timed; track t.item.id) {
42921
- <button type="button" class="timed-event"
42922
- [style.top.px]="t.top" [style.height.px]="t.height"
42923
- [style.left]="'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
42924
- [style.width]="'calc(' + (100 / t.lane.lanes) + '% - 4px)'"
42925
- [style.background]="t.item.bgColor" [style.borderLeftColor]="t.item.color"
42926
- [attr.aria-label]="itemLabel(t.item)" [attr.title]="t.item.tooltip || null" (click)="onItemClick(t.item, $event)">
42927
- <span class="te-title" [class.strike]="t.item.strike">{{ t.item.title }}</span>
42928
- @if (t.item.startTime) { <span class="te-time">{{ t.item.timeLabel || timeRange(t.item) }}</span> }
42929
- </button>
43938
+ @if (actionsFor(t.item).length) {
43939
+ <div class="item-wrap timed-wrap" [style.top.px]="t.top" [style.height.px]="t.height"
43940
+ [style.left]="'calc(' + (t.lane.lane / t.lane.lanes * 100) + '% + 2px)'"
43941
+ [style.width]="'calc(' + (100 / t.lane.lanes) + '% - 4px)'">
43942
+ <ng-container *ngTemplateOutlet="timedEvent; context: { $implicit: t, wrapped: true }" />
43943
+ <ng-container *ngTemplateOutlet="itemActionsTpl; context: { $implicit: t.item }" />
43944
+ </div>
43945
+ } @else {
43946
+ <ng-container *ngTemplateOutlet="timedEvent; context: { $implicit: t, wrapped: false }" />
43947
+ }
42930
43948
  }
42931
43949
  </div>
42932
43950
  }
@@ -42938,32 +43956,25 @@ i0.ɵɵngDeclareClassMetadata({
42938
43956
  @if (agendaGroups().length === 0) {
42939
43957
  <ui-empty-state iconType="task" [message]="emptyMessage()" />
42940
43958
  }
42941
- @for (group of agendaGroups(); track group.dateStr) {
42942
- <div class="agenda-group">
42943
- <div class="agenda-date-hdr">
42944
- <span class="ag-dow">{{ agendaDow(group.dateStr) }}</span>
42945
- <span class="ag-date">{{ agendaDate(group.dateStr) }}</span>
42946
- @if (group.dateStr === todayStr()) { <ui-badge label="Today" variant="blue" /> }
42947
- </div>
42948
- <div class="agenda-events">
42949
- @for (e of group.items; track e.id) {
42950
- <button type="button" class="agenda-event" [attr.aria-label]="e.ariaLabel || null" [attr.title]="e.tooltip || null" (click)="onItemClick(e, $event)">
42951
- <span class="ae-color-bar" [style.background]="e.color"></span>
42952
- <span class="ae-body">
42953
- <span class="ae-top">
42954
- <span class="ae-title" [class.strike]="e.strike">{{ e.title }}</span>
42955
- @for (b of e.badges ?? []; track b.label) { <ui-badge [label]="b.label" [variant]="b.variant" /> }
42956
- </span>
42957
- @if (agendaMeta(e).length) {
42958
- <span class="ae-meta">
42959
- @for (m of agendaMeta(e); track $index) { <span class="ae-meta-item">{{ m }}</span> }
42960
- </span>
42961
- }
42962
- </span>
42963
- </button>
43959
+ @if (agendaSections(); as sections) {
43960
+ @for (s of sections; track $index) {
43961
+ @if (s.label) {
43962
+ <section class="agenda-section" [attr.aria-labelledby]="s.id">
43963
+ <h3 class="agenda-period-hdr" [id]="s.id">{{ s.label }}</h3>
43964
+ @for (group of s.groups; track group.dateStr) {
43965
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
43966
+ }
43967
+ </section>
43968
+ } @else {
43969
+ @for (group of s.groups; track group.dateStr) {
43970
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
42964
43971
  }
42965
- </div>
42966
- </div>
43972
+ }
43973
+ }
43974
+ } @else {
43975
+ @for (group of agendaGroups(); track group.dateStr) {
43976
+ <ng-container *ngTemplateOutlet="agendaGroupTpl; context: { $implicit: group }" />
43977
+ }
42967
43978
  }
42968
43979
  </div>
42969
43980
  }
@@ -42972,7 +43983,7 @@ i0.ɵɵngDeclareClassMetadata({
42972
43983
  }
42973
43984
  <ui-toast />
42974
43985
  `,
42975
- styles: [":host{display:flex;flex-direction:column;gap:0;height:100%;min-height:0}.cal-header{background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 1px 2px #0f172a0a;margin-bottom:12px;flex-shrink:0}.cal-toolbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:18px 20px;gap:16px;flex-shrink:0}.toolbar-left{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;column-gap:20px;row-gap:8px;min-width:0}.toolbar-center{display:flex;align-items:center;justify-content:center;gap:10px}.toolbar-right{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}.toolbar-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:nowrap}.toolbar-actions:empty{display:none}ui-pill-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}@media(max-width:480px){.toolbar-actions{flex-wrap:wrap}}.period-label{font-size:2.5rem;font-weight:800;line-height:1.15;letter-spacing:-.025em;color:#0f172a;margin:0;min-width:0}.pl-sub{font-weight:600;color:#64748b}.nav-controls{display:inline-flex;align-items:center}.nav-controls>*+*{margin-left:-1px}.btn-nav{width:38px;height:38px;border:1px solid #cbd5e1;background:#fff;font-family:inherit;position:relative;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#475569;transition:background .12s,color .12s}.nav-controls>.btn-nav:first-child{border-radius:10px 0 0 10px}.nav-controls>.btn-nav:last-child{border-radius:0 10px 10px 0}.btn-today{padding:0 18px;height:38px;border:1px solid #cbd5e1;background:#fff;border-radius:0;font-family:inherit;position:relative;font-size:.9375rem;font-weight:600;color:#1d4ed8;cursor:pointer;transition:background .12s}.btn-nav:hover,.btn-today:hover{background:#eff6ff;color:#1d4ed8;z-index:1}.btn-nav:active,.btn-today:active{background:#dbeafe}.btn-nav:focus-visible,.btn-today:focus-visible,.filter-chip:focus-visible,.event-chip:focus-visible,.more-events:focus-visible,.allday-chip:focus-visible,.timed-event:focus-visible,.agenda-event:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.month-cell:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.slot-add:focus,.slot-add:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.mobile-summary{display:none}.filter-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 16px;padding:12px 20px 14px;border-top:1px solid #eef2f7;background:#f8fafc;border-radius:0 0 12px 12px;flex-shrink:0}.filter-main{display:flex;flex-direction:column;gap:8px;flex:1 1 auto;min-width:0}.filter-nav{margin-left:auto;flex-shrink:0}.filter-bar-label{font-size:.6875rem;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em}.filter-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.filter-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:20px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#475569;cursor:pointer;transition:all .12s;white-space:nowrap;font-family:inherit}.filter-chip:hover{border-color:#cbd5e1;background:#f8fafc}.filter-chip.active-all{background:#1e293b;color:#fff;border-color:#1e293b}.filter-chip.active-all .chip-count{background:#fff3;color:#fff}.filter-chip.active-type{background:var(--chip-bg, #f1f5f9);color:#1e293b;border-color:var(--chip-color);font-weight:600}.filter-chip.active-type .chip-count{background:var(--chip-color);color:#fff}.chip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.chip-count{font-size:.6875rem;font-weight:700;background:#f1f5f9;background:color-mix(in srgb,var(--chip-color, #64748b) 14%,#fff);color:#475569;padding:1px 8px;border-radius:999px;min-width:18px;text-align:center;box-sizing:border-box}.cal-skeleton,.outline-grid,.month-view,.week-view,.agenda-view{flex:1;display:flex;flex-direction:column;min-height:0;background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.skel-dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;padding:12px 10px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.skel-dow{display:flex;justify-content:center}.skel-month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,minmax(80px,1fr));flex:1}.skel-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:8px 6px;display:flex;flex-direction:column;gap:6px}.skel-cell:nth-child(7n){border-right:none}.cal-outline{flex:1;display:flex;flex-direction:column;min-height:0}.cal-outline ui-skeleton{display:block;flex-shrink:0}.skel-period-wrap{width:240px;max-width:100%;min-width:0}.skel-nav-controls{gap:2px}.skel-nav-controls>*+*{margin-left:0}.skel-tabs{display:flex;align-items:center;gap:6px}.skel-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}.skel-week-grid{display:grid;grid-template-columns:repeat(7,1fr);flex:1;min-height:360px}.skel-agenda{display:flex;flex-direction:column;flex:1}.skel-row{display:flex;align-items:center;gap:16px;padding:16px 12px;border-bottom:1px solid #f1f5f9}.skel-row-body{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0}.month-grid{display:flex;flex-direction:column;flex:1;min-height:0;overflow:auto}.month-header{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;position:sticky;top:0;z-index:1}.month-dow{padding:10px 8px;font-size:.75rem;font-weight:600;color:#6b7280;text-align:center;text-transform:uppercase;letter-spacing:.04em}.dow-short{display:none}.month-row{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));flex:1 0 120px}.month-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:6px 6px 4px;min-height:120px;transition:background .1s;min-width:0;box-sizing:border-box}.month-cell.clickable{cursor:pointer}.month-cell.clickable:hover{background:#f8fafc}.month-cell:nth-child(7n){border-right:none}.month-cell.other-month{background:#fafafa}.month-cell.other-month .day-num{color:#64748b}.month-cell.today{background:#eff6ff}.day-num{display:inline-block;width:26px;height:26px;line-height:26px;text-align:center;border-radius:50%;font-size:.8125rem;font-weight:500;color:#374151;margin-bottom:4px}.today-badge{background:#2563eb;color:#fff;font-weight:700}.cell-events{display:flex;flex-direction:column;gap:2px}.event-chip{display:flex;align-items:center;gap:3px;padding:2px 6px;width:100%;box-sizing:border-box;text-align:left;font-family:inherit;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;cursor:pointer;overflow:hidden}.event-chip:hover{opacity:.85}.event-chip.stacked{flex-direction:column;align-items:flex-start;gap:0}.chip-head{display:inline-flex;align-items:center;gap:3px;flex-shrink:0}.chip-icon{flex-shrink:0}.chip-time{font-weight:700;flex-shrink:0;color:#1e293b}.chip-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#1e293b;min-width:0;max-width:100%}.strike{text-decoration:line-through}.chip-src{font-size:.625rem;font-weight:700;margin-left:auto;flex-shrink:0;color:#1e293b}.more-events{font-size:.6875rem;color:#2563eb;font-weight:600;cursor:pointer;padding:1px 6px;border:0;background:none;text-align:left;font-family:inherit}.more-events:hover{text-decoration:underline}.week-view{overflow:auto}.week-header{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;overflow-y:scroll}.time-gutter{border-right:1px solid #e2e8f0}.week-day-hdr{display:flex;flex-direction:column;align-items:center;padding:10px 4px;border-right:1px solid #f1f5f9}.week-day-hdr.today{background:#eff6ff}.week-day-hdr:last-child{border-right:none}.wdh-dow{font-size:.6875rem;font-weight:600;color:#6b7280;text-transform:uppercase}.wdh-num{width:28px;height:28px;line-height:28px;text-align:center;border-radius:50%;font-size:.9375rem;font-weight:600;color:#374151;margin-top:2px}.wdh-num.today-badge{background:#2563eb;color:#fff;font-weight:700}.allday-row{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;min-height:32px;flex-shrink:0;overflow-y:scroll}.allday-label{font-size:.625rem;color:#64748b;font-weight:600;text-transform:uppercase;display:flex;align-items:center;justify-content:center}.slot-add{position:absolute;top:2px;left:2px;z-index:3;width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap;font-family:inherit}.slot-add:focus,.slot-add:focus-visible{width:auto;height:auto;padding:2px 8px;clip-path:none;background:#1e293b;color:#fff;border-radius:4px;font-size:.75rem;font-weight:600}.allday-cell{position:relative;border-right:1px solid #f1f5f9;padding:3px 4px;display:flex;flex-direction:column;gap:2px;min-width:0}.allday-cell.clickable{cursor:pointer}.allday-cell:last-child{border-right:none}.allday-chip{padding:2px 6px;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;color:#1e293b;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left;font-family:inherit}.allday-chip:hover{opacity:.85}.week-body{display:grid;grid-template-columns:60px repeat(7,1fr);flex:1;overflow-y:scroll}.time-col{display:flex;flex-direction:column;border-right:1px solid #e2e8f0;flex-shrink:0}.time-slot-label{height:60px;display:flex;align-items:flex-start;justify-content:flex-end;padding:4px 8px 0 0;font-size:.6875rem;color:#64748b;font-weight:500;border-bottom:1px solid #f1f5f9;flex-shrink:0;box-sizing:border-box}.day-col{position:relative;border-right:1px solid #f1f5f9;min-width:0}.day-col.clickable{cursor:pointer}.day-col:last-child{border-right:none}.day-col.today{background:#fafbff}.time-slot{height:60px;border-bottom:1px solid #f1f5f9;box-sizing:border-box}.day-col.clickable .time-slot:hover{background:#f8fafc}.timed-event{position:absolute;min-height:20px;border:0;border-radius:6px;padding:3px 6px;overflow:hidden;cursor:pointer;box-sizing:border-box;border-left:3px solid transparent;display:flex;flex-direction:column;align-items:flex-start;gap:1px;box-shadow:0 1px 3px #00000014;text-align:left;font-family:inherit}.timed-event:hover{opacity:.85}.te-title{font-size:.6875rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.te-time{font-size:.625rem;color:#475569}.agenda-view{overflow-y:auto}.agenda-group{display:flex;border-bottom:1px solid #f1f5f9}.agenda-date-hdr{width:100px;flex-shrink:0;padding:16px 12px;display:flex;flex-direction:column;gap:4px;background:#f8fafc;border-right:2px solid #e2e8f0}.ag-dow{font-size:.6875rem;font-weight:700;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.ag-date{font-size:.8125rem;font-weight:600;color:#374151}.agenda-events{flex:1;display:flex;flex-direction:column;min-width:0}.agenda-event{display:flex;align-items:stretch;padding:10px 12px;cursor:pointer;border:0;border-bottom:1px solid #f8fafc;background:none;text-align:left;width:100%;font-family:inherit;transition:background .1s}.agenda-event:hover{background:#f8fafc}.agenda-event:last-child{border-bottom:none}.ae-color-bar{display:block;width:4px;border-radius:4px;flex-shrink:0;margin-right:12px}.ae-body{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.ae-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.ae-title{font-size:.9375rem;font-weight:600;color:#111827}.ae-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.ae-meta-item{font-size:.8125rem;color:#6b7280}@media(prefers-reduced-motion:reduce){.btn-nav,.btn-today,.filter-chip,.month-cell,.agenda-event{transition:none}}@media(pointer:coarse),(max-width:480px){.btn-nav,.btn-today,.filter-chip,.event-chip,.more-events,.allday-chip,.agenda-event{min-height:44px}.btn-nav{min-width:44px}}@media(max-width:768px){.cal-toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 12px}.toolbar-left{flex:1 1 auto}.toolbar-right{flex:0 1 auto;min-width:0;max-width:100%}.toolbar-center{display:none}.period-label{font-size:1.875rem}.toolbar-right{justify-content:flex-end}.mobile-summary{display:block;margin-bottom:4px;flex-shrink:0}.mobile-summary:empty{display:none}.filter-chips{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}.filter-main{flex-basis:100%}.month-view,.cal-skeleton,.outline-grid,.week-view{overflow-x:auto;-webkit-overflow-scrolling:touch}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:560px}.month-row{flex-basis:80px}.month-cell{min-height:80px}.week-header,.allday-row,.week-body{min-width:640px}.agenda-date-hdr{width:76px;padding:12px 8px}.ae-title{font-size:.875rem}}@media(max-width:640px){.event-chip.stacked.has-head .chip-title{display:none}}@media(max-width:640px){.cal-toolbar{padding:14px}.period-label{font-size:1.625rem}.filter-bar{padding:10px 14px 12px}.filter-nav{width:100%;margin-left:0}.filter-nav .nav-controls{display:flex;width:100%}.filter-nav .btn-today{flex:1 1 auto}.chip-head{flex-wrap:wrap;row-gap:0;flex-shrink:1;min-width:0}.chip-time{white-space:normal;line-height:1.1;flex-shrink:1;min-width:0;overflow-wrap:anywhere}.event-chip.stacked{flex-wrap:nowrap}.month-view,.cal-skeleton,.outline-grid{overflow-x:hidden}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:0}.month-dow{padding:8px 2px;font-size:.6875rem;letter-spacing:0}.month-row{flex-basis:72px}.month-cell{min-height:72px;padding:3px 2px 2px}.day-num{width:22px;height:22px;line-height:22px;font-size:.75rem;margin-bottom:2px}.cell-events{gap:1px}.event-chip{min-height:24px;padding:1px 3px;font-size:.625rem;gap:2px}.more-events{min-height:24px;padding:1px 3px;font-size:.625rem;white-space:normal;line-height:1.1;max-width:100%}}@media(max-width:480px){.dow-full{display:none}.dow-short{display:inline}}\n"]
43986
+ styles: [":host{display:flex;flex-direction:column;gap:0;height:100%;min-height:0}.cal-header{background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 1px 2px #0f172a0a;margin-bottom:12px;flex-shrink:0}.cal-toolbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:18px 20px;gap:16px;flex-shrink:0}.toolbar-left{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;column-gap:20px;row-gap:8px;min-width:0}.toolbar-center{display:flex;align-items:center;justify-content:center;gap:10px}.toolbar-right{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}.toolbar-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:nowrap}.toolbar-actions:empty{display:none}ui-pill-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}@media(max-width:480px){.toolbar-actions{flex-wrap:wrap}}.period-label{font-size:2.5rem;font-weight:800;line-height:1.15;letter-spacing:-.025em;color:#0f172a;margin:0;min-width:0}.pl-sub{font-weight:600;color:#64748b}.nav-controls{display:inline-flex;align-items:center}.nav-controls>*+*{margin-left:-1px}.btn-nav{width:38px;height:38px;border:1px solid #cbd5e1;background:#fff;font-family:inherit;position:relative;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#475569;transition:background .12s,color .12s}.nav-controls>.btn-nav:first-child{border-radius:10px 0 0 10px}.nav-controls>.btn-nav:last-child{border-radius:0 10px 10px 0}.btn-today{padding:0 18px;height:38px;border:1px solid #cbd5e1;background:#fff;border-radius:0;font-family:inherit;position:relative;font-size:.9375rem;font-weight:600;color:#1d4ed8;cursor:pointer;transition:background .12s}.btn-nav:hover,.btn-today:hover{background:#eff6ff;color:#1d4ed8;z-index:1}.btn-nav:active,.btn-today:active{background:#dbeafe}.btn-nav:focus-visible,.btn-today:focus-visible,.filter-chip:focus-visible,.event-chip:focus-visible,.more-events:focus-visible,.allday-chip:focus-visible,.timed-event:focus-visible,.agenda-event:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.month-cell:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.slot-add:focus,.slot-add:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}.mobile-summary{display:none}.filter-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 16px;padding:12px 20px 14px;border-top:1px solid #eef2f7;background:#f8fafc;border-radius:0 0 12px 12px;flex-shrink:0}.filter-main{display:flex;flex-direction:column;gap:8px;flex:1 1 auto;min-width:0}.filter-nav{margin-left:auto;flex-shrink:0}.filter-bar-label{font-size:.6875rem;font-weight:700;color:#64748b;text-transform:uppercase;letter-spacing:.06em}.filter-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.filter-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 12px;border-radius:20px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#475569;cursor:pointer;transition:all .12s;white-space:nowrap;font-family:inherit}.filter-chip:hover{border-color:#cbd5e1;background:#f8fafc}.filter-chip.active-all{background:#1e293b;color:#fff;border-color:#1e293b}.filter-chip.active-all .chip-count{background:#fff3;color:#fff}.filter-chip.active-type{background:var(--chip-bg, #f1f5f9);color:#1e293b;border-color:var(--chip-color);font-weight:600}.filter-chip.active-type .chip-count{background:var(--chip-color);color:#fff}.chip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.chip-count{font-size:.6875rem;font-weight:700;background:#f1f5f9;background:color-mix(in srgb,var(--chip-color, #64748b) 14%,#fff);color:#475569;padding:1px 8px;border-radius:999px;min-width:18px;text-align:center;box-sizing:border-box}.cal-skeleton,.outline-grid,.month-view,.week-view,.agenda-view{flex:1;display:flex;flex-direction:column;min-height:0;background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.skel-dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;padding:12px 10px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.skel-dow{display:flex;justify-content:center}.skel-month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:repeat(6,minmax(80px,1fr));flex:1}.skel-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:8px 6px;display:flex;flex-direction:column;gap:6px}.skel-cell:nth-child(7n){border-right:none}.cal-outline{flex:1;display:flex;flex-direction:column;min-height:0}.cal-outline ui-skeleton{display:block;flex-shrink:0}.skel-period-wrap{width:240px;max-width:100%;min-width:0}.skel-nav-controls{gap:2px}.skel-nav-controls>*+*{margin-left:0}.skel-tabs{display:flex;align-items:center;gap:6px}.skel-tabs+.toolbar-actions:not(:empty){margin-left:4px;padding-left:12px;border-left:1px solid #e2e8f0;align-self:stretch}.skel-week-grid{display:grid;grid-template-columns:repeat(7,1fr);flex:1;min-height:360px}.skel-agenda{display:flex;flex-direction:column;flex:1}.skel-row{display:flex;align-items:center;gap:16px;padding:16px 12px;border-bottom:1px solid #f1f5f9}.skel-row-body{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0}.month-grid{display:flex;flex-direction:column;flex:1;min-height:0;overflow:auto}.month-header{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;position:sticky;top:0;z-index:1}.month-dow{padding:10px 8px;font-size:.75rem;font-weight:600;color:#6b7280;text-align:center;text-transform:uppercase;letter-spacing:.04em}.dow-short{display:none}.month-row{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));flex:1 0 120px}.month-cell{border-right:1px solid #f1f5f9;border-bottom:1px solid #f1f5f9;padding:6px 6px 4px;min-height:120px;transition:background .1s;min-width:0;box-sizing:border-box}.month-cell.clickable{cursor:pointer}.month-cell.clickable:hover{background:#f8fafc}.month-cell:nth-child(7n){border-right:none}.month-cell.other-month{background:#fafafa}.month-cell.other-month .day-num{color:#64748b}.month-cell[data-level=low]{background:#f0fdf4;box-shadow:inset 0 3px #86efac}.month-cell[data-level=medium]{background:#fefce8;box-shadow:inset 0 3px #facc15}.month-cell[data-level=high]{background:#fff7ed;box-shadow:inset 0 3px #fb923c}.month-cell[data-level=critical]{background:#fef2f2;box-shadow:inset 0 3px #ef4444}.month-cell.other-month[data-level] .day-num{color:#475569}.month-cell.today{background:#eff6ff}.day-num{display:inline-block;width:26px;height:26px;line-height:26px;text-align:center;border-radius:50%;font-size:.8125rem;font-weight:500;color:#374151;margin-bottom:4px}.today-badge{background:#2563eb;color:#fff;font-weight:700}.cell-events{display:flex;flex-direction:column;gap:2px}.event-chip{display:flex;align-items:center;gap:3px;padding:2px 6px;width:100%;box-sizing:border-box;text-align:left;font-family:inherit;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;cursor:pointer;overflow:hidden}.event-chip:hover{opacity:.85}.event-chip.stacked{flex-direction:column;align-items:flex-start;gap:0}.chip-head{display:inline-flex;align-items:center;gap:3px;flex-shrink:0}.chip-icon{flex-shrink:0}.chip-time{font-weight:700;flex-shrink:0;color:#1e293b}.chip-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#1e293b;min-width:0;max-width:100%}.strike{text-decoration:line-through}.chip-src{font-size:.625rem;font-weight:700;margin-left:auto;flex-shrink:0;color:#1e293b}.more-events{font-size:.6875rem;color:#2563eb;font-weight:600;cursor:pointer;padding:1px 6px;border:0;background:none;text-align:left;font-family:inherit}.more-events:hover{text-decoration:underline}.week-view{overflow:auto}.week-header{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;background:#f8fafc;flex-shrink:0;overflow-y:scroll}.time-gutter{border-right:1px solid #e2e8f0}.week-day-hdr{display:flex;flex-direction:column;align-items:center;padding:10px 4px;border-right:1px solid #f1f5f9}.week-day-hdr[data-level=low]{background:#f0fdf4;box-shadow:inset 0 3px #86efac}.week-day-hdr[data-level=medium]{background:#fefce8;box-shadow:inset 0 3px #facc15}.week-day-hdr[data-level=high]{background:#fff7ed;box-shadow:inset 0 3px #fb923c}.week-day-hdr[data-level=critical]{background:#fef2f2;box-shadow:inset 0 3px #ef4444}.week-day-hdr.today{background:#eff6ff}.deco-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);border:0;white-space:nowrap}.week-day-hdr:last-child{border-right:none}.wdh-dow{font-size:.6875rem;font-weight:600;color:#6b7280;text-transform:uppercase}.wdh-num{width:28px;height:28px;line-height:28px;text-align:center;border-radius:50%;font-size:.9375rem;font-weight:600;color:#374151;margin-top:2px}.wdh-num.today-badge{background:#2563eb;color:#fff;font-weight:700}.allday-row{display:grid;grid-template-columns:60px repeat(7,1fr);border-bottom:1px solid #e2e8f0;min-height:32px;flex-shrink:0;overflow-y:scroll}.allday-label{font-size:.625rem;color:#64748b;font-weight:600;text-transform:uppercase;display:flex;align-items:center;justify-content:center}.slot-add{position:absolute;top:2px;left:2px;z-index:3;width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap;font-family:inherit}.slot-add:focus,.slot-add:focus-visible{width:auto;height:auto;padding:2px 8px;clip-path:none;background:#1e293b;color:#fff;border-radius:4px;font-size:.75rem;font-weight:600}.allday-cell{position:relative;border-right:1px solid #f1f5f9;padding:3px 4px;display:flex;flex-direction:column;gap:2px;min-width:0}.allday-cell.clickable{cursor:pointer}.allday-cell:last-child{border-right:none}.allday-chip{padding:2px 6px;border:0;border-radius:4px;border-left:3px solid transparent;font-size:.6875rem;font-weight:500;color:#1e293b;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left;font-family:inherit}.allday-chip:hover{opacity:.85}.week-body{display:grid;grid-template-columns:60px repeat(7,1fr);flex:1;overflow-y:scroll}.time-col{display:flex;flex-direction:column;border-right:1px solid #e2e8f0;flex-shrink:0}.time-slot-label{height:60px;display:flex;align-items:flex-start;justify-content:flex-end;padding:4px 8px 0 0;font-size:.6875rem;color:#64748b;font-weight:500;border-bottom:1px solid #f1f5f9;flex-shrink:0;box-sizing:border-box}.day-col{position:relative;border-right:1px solid #f1f5f9;min-width:0}.day-col.clickable{cursor:pointer}.day-col:last-child{border-right:none}.day-col.today{background:#fafbff}.time-slot{height:60px;border-bottom:1px solid #f1f5f9;box-sizing:border-box}.day-col.clickable .time-slot:hover{background:#f8fafc}.timed-event{position:absolute;min-height:20px;border:0;border-radius:6px;padding:3px 6px;overflow:hidden;cursor:pointer;box-sizing:border-box;border-left:3px solid transparent;display:flex;flex-direction:column;align-items:flex-start;gap:1px;box-shadow:0 1px 3px #00000014;text-align:left;font-family:inherit}.timed-event:hover{opacity:.85}.te-title{font-size:.6875rem;font-weight:600;color:#1e293b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.te-time{font-size:.625rem;color:#475569}.agenda-view{overflow-y:auto}.agenda-section{display:block}.agenda-period-hdr{margin:0;padding:8px 12px;font-size:.75rem;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:.06em;background:#f1f5f9;border-bottom:1px solid #e2e8f0;position:-webkit-sticky;position:sticky;top:0;z-index:1}.agenda-group{display:flex;border-bottom:1px solid #f1f5f9}.agenda-date-hdr{width:100px;flex-shrink:0;padding:16px 12px;display:flex;flex-direction:column;gap:4px;background:#f8fafc;border-right:2px solid #e2e8f0}.ag-dow{font-size:.6875rem;font-weight:700;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.ag-date{font-size:.8125rem;font-weight:600;color:#374151}.agenda-events{flex:1;display:flex;flex-direction:column;min-width:0}.agenda-event{display:flex;align-items:stretch;padding:10px 12px;cursor:pointer;border:0;border-bottom:1px solid #f8fafc;background:none;text-align:left;width:100%;font-family:inherit;transition:background .1s}.agenda-event:hover{background:#f8fafc}.agenda-event:last-child{border-bottom:none}.ae-color-bar{display:block;width:4px;border-radius:4px;flex-shrink:0;margin-right:12px}.ae-body{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.ae-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.ae-title{font-size:.9375rem;font-weight:600;color:#111827}.ae-meta{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.ae-meta-item{font-size:.8125rem;color:#6b7280}.item-wrap{position:relative;display:block;min-width:0}.item-wrap.timed-wrap{position:absolute;min-height:20px}.timed-event.in-wrap{position:static;width:100%;height:100%}.item-actions{position:absolute;top:50%;right:2px;transform:translateY(-50%);display:inline-flex;gap:2px;opacity:0;pointer-events:none;z-index:2}.item-wrap:hover>.item-actions,.item-wrap:focus-within>.item-actions{opacity:1;pointer-events:auto}.agenda-wrap>.item-actions{right:12px}.item-action{min-width:20px;height:20px;padding:0 4px;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:.6875rem;font-weight:600;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer}.item-action:hover:not(:disabled){background:#eff6ff;color:#1d4ed8}.item-action--danger{color:#b91c1c;border-color:#fecaca}.item-action--danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.item-action:disabled{opacity:.5;cursor:not-allowed}.item-action:focus-visible{outline:2px solid #3b82f6;outline-offset:1px}@media(hover:none){.agenda-wrap>.item-actions{opacity:1;pointer-events:auto}}@media(pointer:coarse),(max-width:480px){.item-action{min-width:44px;min-height:44px}}@media(prefers-reduced-motion:reduce){.btn-nav,.btn-today,.filter-chip,.month-cell,.agenda-event{transition:none}}@media(pointer:coarse),(max-width:480px){.btn-nav,.btn-today,.filter-chip,.event-chip,.more-events,.allday-chip,.agenda-event{min-height:44px}.btn-nav{min-width:44px}}@media(max-width:768px){.cal-toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 12px}.toolbar-left{flex:1 1 auto}.toolbar-right{flex:0 1 auto;min-width:0;max-width:100%}.toolbar-center{display:none}.period-label{font-size:1.875rem}.toolbar-right{justify-content:flex-end}.mobile-summary{display:block;margin-bottom:4px;flex-shrink:0}.mobile-summary:empty{display:none}.filter-chips{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}.filter-main{flex-basis:100%}.month-view,.cal-skeleton,.outline-grid,.week-view{overflow-x:auto;-webkit-overflow-scrolling:touch}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:560px}.month-row{flex-basis:80px}.month-cell{min-height:80px}.week-header,.allday-row,.week-body{min-width:640px}.agenda-date-hdr{width:76px;padding:12px 8px}.ae-title{font-size:.875rem}}@media(max-width:640px){.event-chip.stacked.has-head .chip-title{display:none}}@media(max-width:640px){.cal-toolbar{padding:14px}.period-label{font-size:1.625rem}.filter-bar{padding:10px 14px 12px}.filter-nav{width:100%;margin-left:0}.filter-nav .nav-controls{display:flex;width:100%}.filter-nav .btn-today{flex:1 1 auto}.chip-head{flex-wrap:wrap;row-gap:0;flex-shrink:1;min-width:0}.chip-time{white-space:normal;line-height:1.1;flex-shrink:1;min-width:0;overflow-wrap:anywhere}.event-chip.stacked{flex-wrap:nowrap}.month-view,.cal-skeleton,.outline-grid{overflow-x:hidden}.month-grid,.skel-month-grid,.skel-week-grid,.skel-dow-row{min-width:0}.month-dow{padding:8px 2px;font-size:.6875rem;letter-spacing:0}.month-row{flex-basis:72px}.month-cell{min-height:72px;padding:3px 2px 2px}.day-num{width:22px;height:22px;line-height:22px;font-size:.75rem;margin-bottom:2px}.cell-events{gap:1px}.event-chip{min-height:24px;padding:1px 3px;font-size:.625rem;gap:2px}.more-events{min-height:24px;padding:1px 3px;font-size:.625rem;white-space:normal;line-height:1.1;max-width:100%}}@media(max-width:480px){.dow-full{display:none}.dow-short{display:inline}}\n"]
42976
43987
  }]
42977
43988
  }],
42978
43989
  ctorParameters: () => [],
@@ -43154,6 +44165,30 @@ i0.ɵɵngDeclareClassMetadata({
43154
44165
  required: false
43155
44166
  }]
43156
44167
  }],
44168
+ dayDecorationFn: [{
44169
+ type: i0.Input,
44170
+ args: [{
44171
+ isSignal: true,
44172
+ alias: "dayDecorationFn",
44173
+ required: false
44174
+ }]
44175
+ }],
44176
+ itemActionsFn: [{
44177
+ type: i0.Input,
44178
+ args: [{
44179
+ isSignal: true,
44180
+ alias: "itemActionsFn",
44181
+ required: false
44182
+ }]
44183
+ }],
44184
+ agendaGroupFn: [{
44185
+ type: i0.Input,
44186
+ args: [{
44187
+ isSignal: true,
44188
+ alias: "agendaGroupFn",
44189
+ required: false
44190
+ }]
44191
+ }],
43157
44192
  rangeChange: [{
43158
44193
  type: i0.Output,
43159
44194
  args: ["rangeChange"]
@@ -43173,6 +44208,10 @@ i0.ɵɵngDeclareClassMetadata({
43173
44208
  moreClick: [{
43174
44209
  type: i0.Output,
43175
44210
  args: ["moreClick"]
44211
+ }],
44212
+ itemAction: [{
44213
+ type: i0.Output,
44214
+ args: ["itemAction"]
43176
44215
  }]
43177
44216
  }
43178
44217
  });
@@ -43750,6 +44789,50 @@ function formatAddress(parts, options = {}) {
43750
44789
  zip
43751
44790
  ].filter(Boolean).join(separator);
43752
44791
  }
44792
+ function getInitials(firstName, lastName) {
44793
+ return (firstName?.[0] || "") + (lastName?.[0] || "");
44794
+ }
44795
+ function formatDuration(seconds) {
44796
+ if (!seconds) return "";
44797
+ const m = Math.floor(seconds / 60);
44798
+ const s = seconds % 60;
44799
+ return m > 0 ? `${m}m ${s}s` : `${s}s`;
44800
+ }
44801
+ function formatPhone(raw) {
44802
+ if (!raw) return "";
44803
+ const normalized = raw.startsWith("+1") && raw.replace(/\D/g, "").length === 11 ? raw.slice(2) : raw;
44804
+ if (normalized.startsWith("+")) return normalized;
44805
+ const digits = normalized.replace(/\D/g, "");
44806
+ const d = digits.startsWith("1") && digits.length === 11 ? digits.slice(1) : digits.slice(0, 10);
44807
+ if (d.length <= 3) return d;
44808
+ if (d.length <= 6) return `(${d.slice(0, 3)}) ${d.slice(3)}`;
44809
+ return `(${d.slice(0, 3)}) ${d.slice(3, 6)}-${d.slice(6)}`;
44810
+ }
44811
+ function formatPhoneDisplay(e164) {
44812
+ const value = (e164 ?? "").trim();
44813
+ const m = /^\+1(\d{3})(\d{3})(\d{4})$/.exec(value);
44814
+ return m ? `+1 ${m[1]} ${m[2]}-${m[3]}` : e164 ?? "";
44815
+ }
44816
+ function formatShortDate(value) {
44817
+ if (!value) return "—";
44818
+ return new Date(/^\d{4}-\d{2}-\d{2}$/.test(value) ? value + "T00:00:00" : value).toLocaleDateString("en-US", {
44819
+ month: "short",
44820
+ day: "numeric",
44821
+ year: "numeric"
44822
+ });
44823
+ }
44824
+ function todayInTimezone(timezone) {
44825
+ const fmt = (tz) => new Intl.DateTimeFormat("en-CA", {
44826
+ timeZone: tz,
44827
+ year: "numeric",
44828
+ month: "2-digit",
44829
+ day: "2-digit"
44830
+ }).format(/* @__PURE__ */ new Date());
44831
+ if (timezone) try {
44832
+ return fmt(timezone);
44833
+ } catch {}
44834
+ return fmt();
44835
+ }
43753
44836
  function downloadBlob(blob, fileName) {
43754
44837
  if (typeof document === "undefined" || typeof URL === "undefined" || typeof URL.createObjectURL !== "function") return;
43755
44838
  const url = URL.createObjectURL(blob);
@@ -53557,6 +54640,6 @@ i0.ɵɵngDeclareClassMetadata({
53557
54640
  }]
53558
54641
  }
53559
54642
  });
53560
- export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationRichBodyComponent, ConversationsComponent, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FillViewportDirective, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KeypadComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, conversationDateLabel, conversationHtmlToText, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, formatAddress, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, gmailShareUrl, groupMessagesByDay, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeHexColor, outlookShareUrl, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, truncateConversationText, xShareUrl };
54643
+ export { ASCII_SPECIAL_PASSWORD_RULES, ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, COMMON_DETAIL_GROUP_STYLES, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, ConversationRichBodyComponent, ConversationsComponent, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DETAIL_CARD_HEADER_BG, DETAIL_GROUP_HEADER_BG, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FillViewportDirective, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KeypadComponent, KpiCardComponent, LAYOUT_GAP_PX, LISTED_SPECIAL_PASSWORD_RULES, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OfflineBannerComponent, OptionCardComponent, PASSWORD_MAX_LENGTH, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, ReminderAlertsComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShareMenuComponent, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, SnackbarComponent, SnackbarService, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_LOCATIONS, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, conversationDateLabel, conversationHtmlToText, conversationInitial, conversationMessageStatusLabel, conversationMessageStatusMark, createFieldReveal, createPasswordPolicyValidator, decodeFilterValues, digitsOnly, downloadBlob, emailShareUrl, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, facebookShareUrl, fileMatchesAccept, formatAddress, formatCategoryLabel, formatConversationPhone, formatConversationTime, formatCurrency, formatDuration, formatFileSize, formatIsoDate, formatIsoDateTime, formatMessageTime, formatPhone, formatPhoneDisplay, formatShortDate, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, getInitials, gmailShareUrl, groupMessagesByDay, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, linkedInShareUrl, maxLengthIssue, mergeDescribedBy, normalizeHexColor, outlookShareUrl, parseBizHours, parseIso, parseTime, passwordMeetsRules, periodGroup, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro, todayInTimezone, truncateConversationText, xShareUrl };
53561
54644
 
53562
54645
  //# sourceMappingURL=forgeroute-ui.mjs.map