@clr/angular 18.0.0-beta.9 → 18.1.0

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Directive, ViewChild, Component, PLATFORM_ID, Inject, DOCUMENT, EventEmitter, ElementRef, booleanAttribute, Input, Output, Optional, ContentChild, ChangeDetectionStrategy, ContentChildren, forwardRef, HostListener, ViewContainerRef, runInInjectionContext, Injector, ChangeDetectorRef, NgZone, Renderer2, inject, EnvironmentInjector, TemplateRef, IterableDiffers, ViewChildren, InjectionToken, NgModule } from '@angular/core';
2
+ import { Injectable, Directive, ViewChild, Component, PLATFORM_ID, Inject, DOCUMENT, EventEmitter, ElementRef, booleanAttribute, Input, Output, Optional, ContentChild, ChangeDetectionStrategy, ContentChildren, forwardRef, HostListener, ViewContainerRef, runInInjectionContext, Injector, ChangeDetectorRef, NgZone, Renderer2, inject, EnvironmentInjector, TemplateRef, IterableDiffers, afterNextRender, ViewChildren, InjectionToken, NgModule } from '@angular/core';
3
3
  import * as i2 from '@clr/angular/utils';
4
4
  import { uniqueIdFactory, Keys, HostWrapper, IfExpandService, ClrLoadingState, ClrExpandableAnimationDirective, LoadingListener, WillyWonka, OompaLoompa, ClrKeyFocus, DomAdapter, ClrIfExpanded, CdkDragModule, CdkTrapFocusModule, ClrLoadingModule, ClrConditionalModule, ClrOutsideClickModule, ClrExpandableAnimationModule, ClrKeyFocusModule } from '@clr/angular/utils';
5
5
  import * as i2$2 from 'rxjs';
@@ -3436,6 +3436,11 @@ class Selection {
3436
3436
  let newSingle;
3437
3437
  let selectionUpdated = false;
3438
3438
  updatedItems.forEach(item => {
3439
+ if (item === null || item === undefined) {
3440
+ // Virtual scroll may emit a dense array of undefined slot placeholders. Those must
3441
+ // never match the empty single-selection ref (see virtual-scroll + Single).
3442
+ return;
3443
+ }
3439
3444
  const ref = _items.identifyBy(item);
3440
3445
  // If one of the updated items is the previously selectedSingle, set it as the new one
3441
3446
  if (this.currentSelectionRefs[0] === ref) {
@@ -3460,6 +3465,9 @@ class Selection {
3460
3465
  //
3461
3466
  // The both loops below that goes over updatedItems could be combined into one.
3462
3467
  updatedItems.forEach(item => {
3468
+ if (item === null || item === undefined) {
3469
+ return;
3470
+ }
3463
3471
  const ref = _items.identifyBy(item);
3464
3472
  if (this.lockedRefs.indexOf(ref) > -1) {
3465
3473
  updateLockedRef.push(ref);
@@ -3470,6 +3478,9 @@ class Selection {
3470
3478
  // the if statement below results in broken behavior.
3471
3479
  if (leftOver.length > 0) {
3472
3480
  updatedItems.forEach(item => {
3481
+ if (item === null || item === undefined) {
3482
+ return;
3483
+ }
3473
3484
  const ref = _items.identifyBy(item);
3474
3485
  // Look in current selected refs array if item is selected, and update actual value
3475
3486
  const selectedIndex = this.currentSelectionRefs.indexOf(ref);
@@ -3840,6 +3851,13 @@ class ClrDatagridSingleSelectionValueAccessor {
3840
3851
  return value;
3841
3852
  }
3842
3853
  updateChecked() {
3854
+ // Never mark the radio as checked when there is no real selection (state is null/undefined)
3855
+ // or the row item itself is a virtual-scroll placeholder slot (value is null/undefined).
3856
+ // Otherwise keyOf(undefined) === keyOf(undefined) would falsely check the radio.
3857
+ if (this.state === null || this.state === undefined || this.value === null || this.value === undefined) {
3858
+ this.renderer.setProperty(this.elementRef.nativeElement, 'checked', false);
3859
+ return;
3860
+ }
3843
3861
  const state = this.keyOf(this.state);
3844
3862
  const value = this.keyOf(this.value);
3845
3863
  this.renderer.setProperty(this.elementRef.nativeElement, 'checked', state === value);
@@ -4251,81 +4269,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
4251
4269
  type: Input
4252
4270
  }] } });
4253
4271
 
4254
- /*
4255
- * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4256
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4257
- * This software is released under MIT license.
4258
- * The full license information can be found in LICENSE in the root directory of this project.
4259
- */
4260
- var DatagridColumnChanges;
4261
- (function (DatagridColumnChanges) {
4262
- DatagridColumnChanges[DatagridColumnChanges["WIDTH"] = 0] = "WIDTH";
4263
- DatagridColumnChanges[DatagridColumnChanges["HIDDEN"] = 1] = "HIDDEN";
4264
- DatagridColumnChanges[DatagridColumnChanges["INITIALIZE"] = 2] = "INITIALIZE";
4265
- })(DatagridColumnChanges || (DatagridColumnChanges = {}));
4266
- const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
4267
- .map(key => DatagridColumnChanges[key])
4268
- .filter(key => key === parseInt(key, 10) && key !== DatagridColumnChanges.INITIALIZE); // extracts only integer keys
4269
-
4270
- /*
4271
- * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4272
- * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4273
- * This software is released under MIT license.
4274
- * The full license information can be found in LICENSE in the root directory of this project.
4275
- */
4276
- class ColumnsService {
4277
- constructor() {
4278
- this.columns = [];
4279
- this.columnsStateChange = new BehaviorSubject(null);
4280
- this._cache = [];
4281
- }
4282
- get columnStates() {
4283
- return this.columns.map(column => column.value);
4284
- }
4285
- get hasHideableColumns() {
4286
- return this.columnStates.filter(state => state.hideable).length > 0;
4287
- }
4288
- get visibleColumns() {
4289
- return this.columnStates.filter(state => !state.hidden);
4290
- }
4291
- cache() {
4292
- this._cache = this.columns.map(subject => {
4293
- const value = { ...subject.value };
4294
- delete value.changes;
4295
- return value;
4296
- });
4297
- }
4298
- hasCache() {
4299
- return !!this._cache.length;
4300
- }
4301
- resetToLastCache() {
4302
- this._cache.forEach((state, index) => {
4303
- // Just emit the exact value from the cache
4304
- const cachedState = { ...state, changes: ALL_COLUMN_CHANGES };
4305
- this.columns[index].next(cachedState);
4306
- this.columnsStateChange.next(cachedState);
4307
- });
4308
- this._cache = [];
4309
- }
4310
- // Helper method to emit a change to a column only when there is an actual diff to process for that column
4311
- emitStateChangeAt(columnIndex, diff) {
4312
- if (!this.columns[columnIndex]) {
4313
- return;
4314
- }
4315
- this.emitStateChange(this.columns[columnIndex], diff);
4316
- }
4317
- emitStateChange(column, diff) {
4318
- const changedState = { ...column.value, ...diff };
4319
- column.next(changedState);
4320
- this.columnsStateChange.next(changedState);
4321
- }
4322
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4323
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService }); }
4324
- }
4325
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService, decorators: [{
4326
- type: Injectable
4327
- }] });
4328
-
4329
4272
  /*
4330
4273
  * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4331
4274
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -4333,7 +4276,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
4333
4276
  * The full license information can be found in LICENSE in the root directory of this project.
4334
4277
  */
4335
4278
  class ClrDatagridVirtualScrollDirective {
4336
- constructor(changeDetectorRef, iterableDiffers, items, ngZone, renderer2, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, columnsService, injector) {
4279
+ constructor(changeDetectorRef, iterableDiffers, items, ngZone, renderer2, templateRef, viewContainerRef, directionality, scrollDispatcher, viewportRuler, datagrid, injector) {
4337
4280
  this.changeDetectorRef = changeDetectorRef;
4338
4281
  this.iterableDiffers = iterableDiffers;
4339
4282
  this.items = items;
@@ -4345,7 +4288,6 @@ class ClrDatagridVirtualScrollDirective {
4345
4288
  this.scrollDispatcher = scrollDispatcher;
4346
4289
  this.viewportRuler = viewportRuler;
4347
4290
  this.datagrid = datagrid;
4348
- this.columnsService = columnsService;
4349
4291
  this.injector = injector;
4350
4292
  this.renderedRangeChange = new EventEmitter();
4351
4293
  this.persistItems = true;
@@ -4558,7 +4500,7 @@ class ClrDatagridVirtualScrollDirective {
4558
4500
  const virtualScrollViewport = createCdkVirtualScrollViewport(new ElementRef(datagridContentElement), new ElementRef(datagridRowsElement), changeDetectorRef, ngZone, renderer2, virtualScrollStrategy, directionality, scrollDispatcher, viewportRuler, null);
4559
4501
  return virtualScrollViewport;
4560
4502
  }
4561
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i2$1.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: forwardRef(() => ClrDatagrid) }, { token: ColumnsService }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive }); }
4503
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatagridVirtualScrollDirective, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.IterableDiffers }, { token: Items }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: i2$1.Directionality }, { token: i3$1.ScrollDispatcher }, { token: i3$1.ViewportRuler }, { token: forwardRef(() => ClrDatagrid) }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive }); }
4562
4504
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrDatagridVirtualScrollDirective, isStandalone: false, selector: "[clrVirtualScroll],[ClrVirtualScroll]", inputs: { persistItems: ["clrVirtualPersistItems", "persistItems"], cdkVirtualForOf: ["clrVirtualRowsOf", "cdkVirtualForOf"], cdkVirtualForTrackBy: ["clrVirtualRowsTrackBy", "cdkVirtualForTrackBy"], cdkVirtualForTemplate: ["clrVirtualRowsTemplate", "cdkVirtualForTemplate"], cdkVirtualForTemplateCacheSize: ["clrVirtualRowsTemplateCacheSize", "cdkVirtualForTemplateCacheSize"], itemSize: ["clrVirtualRowsItemSize", "itemSize"], minBufferPx: ["clrVirtualRowsMinBufferPx", "minBufferPx"], maxBufferPx: ["clrVirtualRowsMaxBufferPx", "maxBufferPx"], dataRange: ["clrVirtualDataRange", "dataRange"] }, outputs: { renderedRangeChange: "renderedRangeChange" }, providers: [Items], ngImport: i0 }); }
4563
4505
  }
4564
4506
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatagridVirtualScrollDirective, decorators: [{
@@ -4571,7 +4513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
4571
4513
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.IterableDiffers }, { type: Items }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: i2$1.Directionality }, { type: i3$1.ScrollDispatcher }, { type: i3$1.ViewportRuler }, { type: ClrDatagrid, decorators: [{
4572
4514
  type: Inject,
4573
4515
  args: [forwardRef(() => ClrDatagrid)]
4574
- }] }, { type: ColumnsService }, { type: i0.EnvironmentInjector }], propDecorators: { renderedRangeChange: [{
4516
+ }] }, { type: i0.EnvironmentInjector }], propDecorators: { renderedRangeChange: [{
4575
4517
  type: Output
4576
4518
  }], persistItems: [{
4577
4519
  type: Input,
@@ -4639,6 +4581,81 @@ function createCdkVirtualForOfDirective(viewContainerRef, templateRef, iterableD
4639
4581
  return cdkVirtualForInjector.get(CdkVirtualForOf);
4640
4582
  }
4641
4583
 
4584
+ /*
4585
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4586
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4587
+ * This software is released under MIT license.
4588
+ * The full license information can be found in LICENSE in the root directory of this project.
4589
+ */
4590
+ var DatagridColumnChanges;
4591
+ (function (DatagridColumnChanges) {
4592
+ DatagridColumnChanges[DatagridColumnChanges["WIDTH"] = 0] = "WIDTH";
4593
+ DatagridColumnChanges[DatagridColumnChanges["HIDDEN"] = 1] = "HIDDEN";
4594
+ DatagridColumnChanges[DatagridColumnChanges["INITIALIZE"] = 2] = "INITIALIZE";
4595
+ })(DatagridColumnChanges || (DatagridColumnChanges = {}));
4596
+ const ALL_COLUMN_CHANGES = Object.keys(DatagridColumnChanges)
4597
+ .map(key => DatagridColumnChanges[key])
4598
+ .filter(key => key === parseInt(key, 10) && key !== DatagridColumnChanges.INITIALIZE); // extracts only integer keys
4599
+
4600
+ /*
4601
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4602
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
4603
+ * This software is released under MIT license.
4604
+ * The full license information can be found in LICENSE in the root directory of this project.
4605
+ */
4606
+ class ColumnsService {
4607
+ constructor() {
4608
+ this.columns = [];
4609
+ this.columnsStateChange = new BehaviorSubject(null);
4610
+ this._cache = [];
4611
+ }
4612
+ get columnStates() {
4613
+ return this.columns.map(column => column.value);
4614
+ }
4615
+ get hasHideableColumns() {
4616
+ return this.columnStates.filter(state => state.hideable).length > 0;
4617
+ }
4618
+ get visibleColumns() {
4619
+ return this.columnStates.filter(state => !state.hidden);
4620
+ }
4621
+ cache() {
4622
+ this._cache = this.columns.map(subject => {
4623
+ const value = { ...subject.value };
4624
+ delete value.changes;
4625
+ return value;
4626
+ });
4627
+ }
4628
+ hasCache() {
4629
+ return !!this._cache.length;
4630
+ }
4631
+ resetToLastCache() {
4632
+ this._cache.forEach((state, index) => {
4633
+ // Just emit the exact value from the cache
4634
+ const cachedState = { ...state, changes: ALL_COLUMN_CHANGES };
4635
+ this.columns[index].next(cachedState);
4636
+ this.columnsStateChange.next(cachedState);
4637
+ });
4638
+ this._cache = [];
4639
+ }
4640
+ // Helper method to emit a change to a column only when there is an actual diff to process for that column
4641
+ emitStateChangeAt(columnIndex, diff) {
4642
+ if (!this.columns[columnIndex]) {
4643
+ return;
4644
+ }
4645
+ this.emitStateChange(this.columns[columnIndex], diff);
4646
+ }
4647
+ emitStateChange(column, diff) {
4648
+ const changedState = { ...column.value, ...diff };
4649
+ column.next(changedState);
4650
+ this.columnsStateChange.next(changedState);
4651
+ }
4652
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4653
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService }); }
4654
+ }
4655
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColumnsService, decorators: [{
4656
+ type: Injectable
4657
+ }] });
4658
+
4642
4659
  /*
4643
4660
  * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
4644
4661
  * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
@@ -4768,10 +4785,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
4768
4785
  * The full license information can be found in LICENSE in the root directory of this project.
4769
4786
  */
4770
4787
  class DatagridRowRenderer {
4771
- constructor(columnsService) {
4788
+ constructor(columnsService, el) {
4772
4789
  this.columnsService = columnsService;
4790
+ this.el = el;
4773
4791
  this.expandableRows = [];
4774
4792
  this.subscriptions = [];
4793
+ afterNextRender(() => this.addDetachedRowsColumnStateChangesListener());
4775
4794
  }
4776
4795
  ngAfterContentInit() {
4777
4796
  this.setCellsState(); // case #3 and #4
@@ -4806,7 +4825,19 @@ class DatagridRowRenderer {
4806
4825
  });
4807
4826
  }
4808
4827
  }
4809
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowRenderer, deps: [{ token: ColumnsService }], target: i0.ɵɵFactoryTarget.Directive }); }
4828
+ addDetachedRowsColumnStateChangesListener() {
4829
+ this.subscriptions.push(
4830
+ // Active rows are already handled by DatagridMainRenderer.columnStateChanged via @ContentChildren.
4831
+ // Rows sitting in CDK virtual scroll's template cache for example are detached from the document
4832
+ // (element.isConnected = false) and invisible to @ContentChildren, so they miss column state
4833
+ // changes. This subscription self-updates the row only when it is detached state.
4834
+ this.columnsService.columnsStateChange.subscribe(() => {
4835
+ if (!this.el.nativeElement.isConnected) {
4836
+ this.setCellsState();
4837
+ }
4838
+ }));
4839
+ }
4840
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowRenderer, deps: [{ token: ColumnsService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
4810
4841
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: DatagridRowRenderer, isStandalone: false, selector: "clr-dg-row", queries: [{ propertyName: "cells", predicate: DatagridCellRenderer }], ngImport: i0 }); }
4811
4842
  }
4812
4843
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowRenderer, decorators: [{
@@ -4815,7 +4846,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
4815
4846
  selector: 'clr-dg-row',
4816
4847
  standalone: false,
4817
4848
  }]
4818
- }], ctorParameters: () => [{ type: ColumnsService }], propDecorators: { cells: [{
4849
+ }], ctorParameters: () => [{ type: ColumnsService }, { type: i0.ElementRef }], propDecorators: { cells: [{
4819
4850
  type: ContentChildren,
4820
4851
  args: [DatagridCellRenderer]
4821
4852
  }] } });
@@ -7361,8 +7392,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
7361
7392
  * The full license information can be found in LICENSE in the root directory of this project.
7362
7393
  */
7363
7394
  class DatagridRowDetailRenderer extends DatagridRowRenderer {
7364
- constructor(parentRow, columnsService) {
7365
- super(columnsService);
7395
+ constructor(parentRow, columnsService, el) {
7396
+ super(columnsService, el);
7366
7397
  this.parentRow = parentRow;
7367
7398
  parentRow.expandableRows.push(this);
7368
7399
  }
@@ -7370,7 +7401,7 @@ class DatagridRowDetailRenderer extends DatagridRowRenderer {
7370
7401
  this.parentRow.expandableRows = [];
7371
7402
  super.ngOnDestroy();
7372
7403
  }
7373
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowDetailRenderer, deps: [{ token: DatagridRowRenderer }, { token: ColumnsService }], target: i0.ɵɵFactoryTarget.Directive }); }
7404
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowDetailRenderer, deps: [{ token: DatagridRowRenderer }, { token: ColumnsService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
7374
7405
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: DatagridRowDetailRenderer, isStandalone: false, selector: "clr-dg-row-detail", usesInheritance: true, ngImport: i0 }); }
7375
7406
  }
7376
7407
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatagridRowDetailRenderer, decorators: [{
@@ -7379,7 +7410,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
7379
7410
  selector: 'clr-dg-row-detail',
7380
7411
  standalone: false,
7381
7412
  }]
7382
- }], ctorParameters: () => [{ type: DatagridRowRenderer }, { type: ColumnsService }] });
7413
+ }], ctorParameters: () => [{ type: DatagridRowRenderer }, { type: ColumnsService }, { type: i0.ElementRef }] });
7383
7414
 
7384
7415
  /*
7385
7416
  * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.