@alfresco/aca-content 4.3.0 → 4.4.0-6809241006

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.
Files changed (51) hide show
  1. package/esm2020/folder-rules/rule-details/actions/rule-action.ui-component.mjs +2 -8
  2. package/esm2020/lib/components/common/location-link/location-link.component.mjs +6 -4
  3. package/esm2020/lib/components/common/toggle-shared/toggle-shared.component.mjs +2 -2
  4. package/esm2020/lib/components/context-menu/context-menu-item.component.mjs +2 -2
  5. package/esm2020/lib/components/context-menu/context-menu-outside-event.directive.mjs +4 -7
  6. package/esm2020/lib/components/context-menu/context-menu.service.mjs +1 -4
  7. package/esm2020/lib/components/favorite-libraries/favorite-libraries.component.mjs +2 -2
  8. package/esm2020/lib/components/favorites/favorites.component.mjs +3 -3
  9. package/esm2020/lib/components/files/files.component.mjs +17 -15
  10. package/esm2020/lib/components/info-drawer/library-metadata-tab/library-metadata-form.component.mjs +3 -3
  11. package/esm2020/lib/components/libraries/libraries.component.mjs +2 -2
  12. package/esm2020/lib/components/recent-files/recent-files.component.mjs +5 -5
  13. package/esm2020/lib/components/search/search-libraries-results/search-libraries-query-builder.service.mjs +4 -4
  14. package/esm2020/lib/components/search/search-libraries-results/search-libraries-results.component.mjs +3 -3
  15. package/esm2020/lib/components/search/search-results/search-results.component.mjs +2 -2
  16. package/esm2020/lib/components/search/search-results-row/search-results-row.component.mjs +2 -2
  17. package/esm2020/lib/components/sidenav/directives/active-link.directive.mjs +3 -3
  18. package/esm2020/lib/components/sidenav/directives/expansion-panel.directive.mjs +2 -2
  19. package/esm2020/lib/components/sidenav/directives/menu-panel.directive.mjs +2 -2
  20. package/esm2020/lib/components/sidenav/user-menu/user-menu.component.mjs +2 -2
  21. package/esm2020/lib/dialogs/node-template/create-from-template.dialog.mjs +3 -3
  22. package/esm2020/lib/services/content-management.service.mjs +13 -13
  23. package/esm2020/lib/services/node-actions.service.mjs +8 -8
  24. package/esm2020/lib/services/node-template.service.mjs +2 -2
  25. package/esm2020/lib/store/effects/library.effects.mjs +4 -4
  26. package/esm2020/lib/store/effects/node.effects.mjs +14 -14
  27. package/esm2020/lib/store/effects/upload.effects.mjs +3 -7
  28. package/esm2020/lib/store/effects/viewer.effects.mjs +3 -3
  29. package/esm2020/lib/store/reducers/app.reducer.mjs +2 -2
  30. package/esm2020/preview/lib/components/preview.component.mjs +8 -20
  31. package/esm2020/viewer/lib/components/viewer/viewer.component.mjs +9 -21
  32. package/fesm2015/alfresco-aca-content-folder-rules.mjs +1 -7
  33. package/fesm2015/alfresco-aca-content-folder-rules.mjs.map +1 -1
  34. package/fesm2015/alfresco-aca-content-preview.mjs +9 -19
  35. package/fesm2015/alfresco-aca-content-preview.mjs.map +1 -1
  36. package/fesm2015/alfresco-aca-content-viewer.mjs +12 -22
  37. package/fesm2015/alfresco-aca-content-viewer.mjs.map +1 -1
  38. package/fesm2015/alfresco-aca-content.mjs +128 -99
  39. package/fesm2015/alfresco-aca-content.mjs.map +1 -1
  40. package/fesm2020/alfresco-aca-content-folder-rules.mjs +1 -7
  41. package/fesm2020/alfresco-aca-content-folder-rules.mjs.map +1 -1
  42. package/fesm2020/alfresco-aca-content-preview.mjs +7 -19
  43. package/fesm2020/alfresco-aca-content-preview.mjs.map +1 -1
  44. package/fesm2020/alfresco-aca-content-viewer.mjs +8 -20
  45. package/fesm2020/alfresco-aca-content-viewer.mjs.map +1 -1
  46. package/fesm2020/alfresco-aca-content.mjs +91 -97
  47. package/fesm2020/alfresco-aca-content.mjs.map +1 -1
  48. package/lib/components/context-menu/context-menu-outside-event.directive.d.ts +0 -1
  49. package/lib/components/files/files.component.d.ts +1 -1
  50. package/lib/components/recent-files/recent-files.component.d.ts +0 -1
  51. package/package.json +1 -1
@@ -186,8 +186,8 @@ class NodeActionsService {
186
186
  return observable;
187
187
  }
188
188
  isEntryEntitiesArray(contentEntities) {
189
- if (contentEntities && contentEntities.length) {
190
- const nonEntryNode = contentEntities.find((node) => !node || !node.entry || !(node.entry.nodeId || node.entry.id));
189
+ if (contentEntities?.length) {
190
+ const nonEntryNode = contentEntities.find((node) => !(node?.entry?.nodeId || node?.entry?.id));
191
191
  return !nonEntryNode;
192
192
  }
193
193
  return false;
@@ -201,7 +201,7 @@ class NodeActionsService {
201
201
  if (nodeEntry.parentId) {
202
202
  entryParentId = nodeEntry.parentId;
203
203
  }
204
- else if (nodeEntry.path && nodeEntry.path.elements && nodeEntry.path.elements.length) {
204
+ else if (nodeEntry.path?.elements?.length) {
205
205
  entryParentId = nodeEntry.path.elements[nodeEntry.path.elements.length - 1].id;
206
206
  }
207
207
  return entryParentId;
@@ -280,7 +280,7 @@ class NodeActionsService {
280
280
  }
281
281
  // todo: review this approach once 5.2.3 is out
282
282
  customizeBreadcrumb(node) {
283
- if (node && node.path && node.path.elements) {
283
+ if (node?.path?.elements) {
284
284
  const elements = node.path.elements;
285
285
  if (elements.length > 1) {
286
286
  if (elements[1].name === 'User Homes') {
@@ -337,7 +337,7 @@ class NodeActionsService {
337
337
  }
338
338
  }
339
339
  isSiteContainer(node) {
340
- if (node && node.aspectNames && node.aspectNames.length > 0) {
340
+ if (node?.aspectNames?.length > 0) {
341
341
  return node.aspectNames.indexOf('st:siteContainer') >= 0;
342
342
  }
343
343
  return false;
@@ -615,7 +615,7 @@ class NodeActionsService {
615
615
  const folderMoveResponseData = this.flatten(next);
616
616
  const foundError = folderMoveResponseData.find((node) => node instanceof Error);
617
617
  // data might contain also items of form: { itemMoved, initialParentId }
618
- const foundEntry = folderMoveResponseData.find((node) => (node.itemMoved && node.itemMoved.entry) || (node && node.entry));
618
+ const foundEntry = folderMoveResponseData.find((node) => node.itemMoved?.entry || node?.entry);
619
619
  if (!foundError) {
620
620
  // consider success if NONE of the items from the folder move response is an error
621
621
  acc.succeeded.push(next);
@@ -636,7 +636,7 @@ class NodeActionsService {
636
636
  }, moveStatus);
637
637
  }
638
638
  else {
639
- if ((data.itemMoved && data.itemMoved.entry) || (data && data.entry)) {
639
+ if (data.itemMoved?.entry || data?.entry) {
640
640
  moveStatus.succeeded.push(data);
641
641
  }
642
642
  else {
@@ -835,7 +835,7 @@ class FilesComponent extends PageComponent {
835
835
  const nodeId = folderId || data.defaultNodeId;
836
836
  this.contentApi.getNode(nodeId).subscribe((node) => {
837
837
  this.isValidPath = true;
838
- if (node.entry && node.entry.isFolder) {
838
+ if (node?.entry?.isFolder) {
839
839
  this.updateCurrentNode(node.entry);
840
840
  }
841
841
  else {
@@ -908,7 +908,7 @@ class FilesComponent extends PageComponent {
908
908
  this.store.dispatch(new UploadFileVersionAction(ev));
909
909
  }
910
910
  navigateTo(node) {
911
- if (node && node.entry) {
911
+ if (node?.entry) {
912
912
  this.selectedNode = node;
913
913
  const { isFolder } = node.entry;
914
914
  if (isFolder) {
@@ -932,7 +932,7 @@ class FilesComponent extends PageComponent {
932
932
  onBreadcrumbNavigate(route) {
933
933
  this.documentList.resetNewFolderPagination();
934
934
  // todo: review this approach once 5.2.3 is out
935
- if (this.nodePath && this.nodePath.length > 2) {
935
+ if (this.nodePath && this.nodePath?.length > 2) {
936
936
  if (this.nodePath[1].name === 'Sites' && this.nodePath[2].id === route.id) {
937
937
  return this.navigate(this.nodePath[3].id);
938
938
  }
@@ -942,27 +942,27 @@ class FilesComponent extends PageComponent {
942
942
  onFileUploadedEvent(event) {
943
943
  const node = event.file.data;
944
944
  // check root and child nodes
945
- if (node && node.entry && node.entry.parentId === this.getParentNodeId()) {
945
+ if (node?.entry?.parentId === this.getParentNodeId()) {
946
946
  this.reload(this.selectedNode);
947
947
  return;
948
948
  }
949
949
  // check the child nodes to show dropped folder
950
950
  if (event && event.file.options.parentId === this.getParentNodeId()) {
951
- this.displayFolderParent(event.file.options.path, 0);
951
+ this.displayFolderParent(0, event.file.options.path);
952
952
  return;
953
953
  }
954
- if (event && event.file.options.parentId) {
954
+ if (event?.file.options.parentId) {
955
955
  if (this.nodePath) {
956
956
  const correspondingNodePath = this.nodePath.find((pathItem) => pathItem.id === event.file.options.parentId);
957
957
  // check if the current folder has the 'trigger-upload-folder' as one of its parents
958
958
  if (correspondingNodePath) {
959
959
  const correspondingIndex = this.nodePath.length - this.nodePath.indexOf(correspondingNodePath);
960
- this.displayFolderParent(event.file.options.path, correspondingIndex);
960
+ this.displayFolderParent(correspondingIndex, event.file.options.path);
961
961
  }
962
962
  }
963
963
  }
964
964
  }
965
- displayFolderParent(filePath = '', index) {
965
+ displayFolderParent(index, filePath = '') {
966
966
  const parentName = filePath.split('/')[index];
967
967
  const currentFoldersDisplayed = this.documentList.data.getRows() || [];
968
968
  const alreadyDisplayedParentFolder = currentFoldersDisplayed.find((row) => row.node.entry.isFolder && row.node.entry.name === parentName);
@@ -972,7 +972,7 @@ class FilesComponent extends PageComponent {
972
972
  this.reload(this.selectedNode);
973
973
  }
974
974
  onContentCopied(nodes) {
975
- const newNode = nodes.find((node) => node && node.entry && node.entry.parentId === this.getParentNodeId());
975
+ const newNode = nodes.find((node) => node?.entry?.parentId === this.getParentNodeId());
976
976
  if (newNode) {
977
977
  this.reload(this.selectedNode);
978
978
  }
@@ -980,9 +980,11 @@ class FilesComponent extends PageComponent {
980
980
  // todo: review this approach once 5.2.3 is out
981
981
  async updateCurrentNode(node) {
982
982
  this.nodePath = null;
983
- if (node && node.path && node.path.elements) {
983
+ if (node?.path?.elements) {
984
984
  const elements = node.path.elements;
985
- this.nodePath = elements.map((pathElement) => Object.assign({}, pathElement));
985
+ this.nodePath = elements.map((pathElement) => {
986
+ return { ...pathElement };
987
+ });
986
988
  if (elements.length > 1) {
987
989
  if (elements[1].name === 'User Homes') {
988
990
  if (!this.isAdmin) {
@@ -1023,13 +1025,13 @@ class FilesComponent extends PageComponent {
1023
1025
  }
1024
1026
  }
1025
1027
  isSiteContainer(node) {
1026
- if (node && node.aspectNames && node.aspectNames.length > 0) {
1028
+ if (node?.aspectNames?.length > 0) {
1027
1029
  return node.aspectNames.indexOf('st:siteContainer') >= 0;
1028
1030
  }
1029
1031
  return false;
1030
1032
  }
1031
1033
  isRootNode(nodeId) {
1032
- if (this.node && this.node.path && this.node.path.elements && this.node.path.elements.length > 0) {
1034
+ if (this.node?.path?.elements?.length > 0) {
1033
1035
  return this.node.path.elements[0].id === nodeId;
1034
1036
  }
1035
1037
  return false;
@@ -1051,7 +1053,7 @@ class FilesComponent extends PageComponent {
1051
1053
  const objectFromMap = {};
1052
1054
  activeFilters.forEach((filter) => {
1053
1055
  let paramValue;
1054
- if (filter.value && filter.value.from && filter.value.to) {
1056
+ if (filter?.value?.from && filter?.value?.to) {
1055
1057
  paramValue = `${filter.value.from}||${filter.value.to}`;
1056
1058
  }
1057
1059
  else {
@@ -1124,7 +1126,7 @@ class LibrariesComponent extends PageComponent {
1124
1126
  this.columns = this.extensions.documentListPresets.libraries || [];
1125
1127
  }
1126
1128
  navigateTo(node) {
1127
- if (node && node.entry && node.entry.guid) {
1129
+ if (node?.entry?.guid) {
1128
1130
  this.store.dispatch(new NavigateLibraryAction(node.entry.guid));
1129
1131
  }
1130
1132
  }
@@ -1204,7 +1206,7 @@ class FavoriteLibrariesComponent extends PageComponent {
1204
1206
  this.columns = this.extensions.documentListPresets.favoriteLibraries || [];
1205
1207
  }
1206
1208
  navigateTo(node) {
1207
- if (node && node.entry && node.entry.guid) {
1209
+ if (node?.entry?.guid) {
1208
1210
  this.store.dispatch(new NavigateLibraryAction(node.entry.guid, 'favorite/libraries'));
1209
1211
  }
1210
1212
  }
@@ -1344,7 +1346,7 @@ function appReducer(state = INITIAL_APP_STATE, action) {
1344
1346
  let newState;
1345
1347
  switch (action.type) {
1346
1348
  case AppActionTypes.SetInitialState:
1347
- newState = Object.assign({}, action.payload);
1349
+ newState = { ...action.payload };
1348
1350
  break;
1349
1351
  case NodeActionTypes.SetSelection:
1350
1352
  newState = updateSelectedNodes(state, action);
@@ -1836,7 +1838,7 @@ class ContentManagementService {
1836
1838
  }
1837
1839
  }
1838
1840
  manageVersions(node, focusedElementOnCloseSelector) {
1839
- if (node && node.entry) {
1841
+ if (node?.entry) {
1840
1842
  // shared and favorite
1841
1843
  const id = node.entry.nodeId || node.entry.guid;
1842
1844
  if (id) {
@@ -1850,7 +1852,7 @@ class ContentManagementService {
1850
1852
  }
1851
1853
  }
1852
1854
  manageAspects(node, focusedElementOnCloseSelector) {
1853
- if (node && node.entry) {
1855
+ if (node?.entry) {
1854
1856
  // shared and favorite
1855
1857
  const id = node.entry.nodeId || node.entry.guid;
1856
1858
  if (id) {
@@ -1882,7 +1884,7 @@ class ContentManagementService {
1882
1884
  });
1883
1885
  }
1884
1886
  shareNode(node, focusedElementOnCloseSelector) {
1885
- if (node && node.entry) {
1887
+ if (node?.entry) {
1886
1888
  // shared and favorite
1887
1889
  const id = node.entry.nodeId || node.entry.guid;
1888
1890
  if (id) {
@@ -1971,7 +1973,7 @@ class ContentManagementService {
1971
1973
  }
1972
1974
  this.focusAfterClose(this.createMenuButtonSelector);
1973
1975
  }), map((node) => {
1974
- if (node && node.entry && node.entry.guid) {
1976
+ if (node?.entry?.guid) {
1975
1977
  return node.entry.guid;
1976
1978
  }
1977
1979
  return null;
@@ -2191,7 +2193,7 @@ class ContentManagementService {
2191
2193
  errorJson = JSON.parse(error.message);
2192
2194
  }
2193
2195
  catch { }
2194
- if (errorJson && errorJson.error && errorJson.error.statusCode === 403) {
2196
+ if (errorJson?.error?.statusCode === 403) {
2195
2197
  i18nMessageString = 'APP.MESSAGES.ERRORS.PERMISSION';
2196
2198
  }
2197
2199
  this.store.dispatch(new SnackbarErrorAction(i18nMessageString));
@@ -2238,15 +2240,15 @@ class ContentManagementService {
2238
2240
  }
2239
2241
  }
2240
2242
  undoMoveNodes(moveResponse, selectionParentId) {
2241
- const movedNodes = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'] : [];
2242
- const partiallyMovedNodes = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'] : [];
2243
+ const movedNodes = moveResponse?.['succeeded'] ?? [];
2244
+ const partiallyMovedNodes = moveResponse?.['partiallySucceeded'] ?? [];
2243
2245
  const restoreDeletedNodesBatch = this.nodeActionsService.moveDeletedEntries.map((folderEntry) => this.contentApi.restoreNode(folderEntry.nodeId || folderEntry.id).pipe(map((node) => node.entry)));
2244
2246
  zip(...restoreDeletedNodesBatch, of(null))
2245
2247
  .pipe(mergeMap(() => {
2246
2248
  const nodesToBeMovedBack = [...partiallyMovedNodes, ...movedNodes];
2247
2249
  const revertMoveBatch = this.nodeActionsService
2248
2250
  .flatten(nodesToBeMovedBack)
2249
- .filter((node) => node.entry || (node.itemMoved && node.itemMoved.entry))
2251
+ .filter((node) => node.entry || node.itemMoved?.entry)
2250
2252
  .map((node) => {
2251
2253
  if (node.itemMoved) {
2252
2254
  return this.nodeActionsService.moveNodeAction(node.itemMoved.entry, node.initialParentId);
@@ -2266,7 +2268,7 @@ class ContentManagementService {
2266
2268
  errorJson = JSON.parse(error.message);
2267
2269
  }
2268
2270
  catch { }
2269
- if (errorJson && errorJson.error && errorJson.error.statusCode === 403) {
2271
+ if (errorJson?.error?.statusCode === 403) {
2270
2272
  message = 'APP.MESSAGES.ERRORS.PERMISSION';
2271
2273
  }
2272
2274
  this.store.dispatch(new SnackbarErrorAction(message));
@@ -2551,9 +2553,9 @@ class ContentManagementService {
2551
2553
  return null;
2552
2554
  }
2553
2555
  showMoveMessage(nodes, info, moveResponse) {
2554
- const succeeded = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'].length : 0;
2555
- const partiallySucceeded = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'].length : 0;
2556
- const failures = moveResponse && moveResponse['failed'] ? moveResponse['failed'].length : 0;
2556
+ const succeeded = moveResponse?.['succeeded'].length ?? 0;
2557
+ const partiallySucceeded = moveResponse?.['partiallySucceeded'].length ?? 0;
2558
+ const failures = moveResponse?.['failed'].length ?? 0;
2557
2559
  let successMessage = '';
2558
2560
  let partialSuccessMessage = '';
2559
2561
  let failedMessage = '';
@@ -2728,14 +2730,14 @@ class NodeEffects {
2728
2730
  .select(getAppSelection)
2729
2731
  .pipe(take(1))
2730
2732
  .subscribe((selection) => {
2731
- if (selection && selection.file) {
2733
+ if (selection?.file) {
2732
2734
  this.contentService.shareNode(selection.file, action.configuration?.focusedElementOnCloseSelector);
2733
2735
  }
2734
2736
  });
2735
2737
  }
2736
2738
  })), { dispatch: false });
2737
2739
  this.unshareNodes$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.Unshare), map((action) => {
2738
- if (action && action.payload && action.payload.length > 0) {
2740
+ if (action?.payload?.length > 0) {
2739
2741
  this.contentService.unshareNodes(action.payload);
2740
2742
  }
2741
2743
  else {
@@ -2750,7 +2752,7 @@ class NodeEffects {
2750
2752
  }
2751
2753
  })), { dispatch: false });
2752
2754
  this.purgeDeletedNodes$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.PurgeDeleted), map((action) => {
2753
- if (action && action.payload && action.payload.length > 0) {
2755
+ if (action?.payload?.length > 0) {
2754
2756
  this.contentService.purgeDeletedNodes(action.payload);
2755
2757
  }
2756
2758
  else {
@@ -2765,7 +2767,7 @@ class NodeEffects {
2765
2767
  }
2766
2768
  })), { dispatch: false });
2767
2769
  this.restoreDeletedNodes$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.RestoreDeleted), map((action) => {
2768
- if (action && action.payload && action.payload.length > 0) {
2770
+ if (action?.payload?.length > 0) {
2769
2771
  this.contentService.restoreDeletedNodes(action.payload);
2770
2772
  }
2771
2773
  else {
@@ -2781,7 +2783,7 @@ class NodeEffects {
2781
2783
  })), { dispatch: false });
2782
2784
  this.deleteNodes$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.Delete), map((action) => {
2783
2785
  this.store.dispatch(new ShowLoaderAction(true));
2784
- if (action && action.payload && action.payload.length > 0) {
2786
+ if (action?.payload?.length > 0) {
2785
2787
  this.contentService.deleteNodes(action.payload);
2786
2788
  }
2787
2789
  else {
@@ -2809,7 +2811,7 @@ class NodeEffects {
2809
2811
  .select(getCurrentFolder)
2810
2812
  .pipe(take(1))
2811
2813
  .subscribe((node) => {
2812
- if (node && node.id) {
2814
+ if (node?.id) {
2813
2815
  this.contentService.createFolder(node.id);
2814
2816
  }
2815
2817
  });
@@ -2824,7 +2826,7 @@ class NodeEffects {
2824
2826
  .select(getAppSelection)
2825
2827
  .pipe(take(1))
2826
2828
  .subscribe((selection) => {
2827
- if (selection && selection.folder) {
2829
+ if (selection?.folder) {
2828
2830
  this.contentService.editFolder(selection.folder, action.configuration?.focusedElementOnCloseSelector);
2829
2831
  }
2830
2832
  });
@@ -2912,14 +2914,14 @@ class NodeEffects {
2912
2914
  .select(getAppSelection)
2913
2915
  .pipe(take(1))
2914
2916
  .subscribe((selection) => {
2915
- if (selection && selection.file) {
2917
+ if (selection?.file) {
2916
2918
  this.contentService.manageVersions(selection.file, action.configuration?.focusedElementOnCloseSelector);
2917
2919
  }
2918
2920
  });
2919
2921
  }
2920
2922
  })), { dispatch: false });
2921
2923
  this.printFile$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.PrintFile), map((action) => {
2922
- if (action && action.payload) {
2924
+ if (action?.payload) {
2923
2925
  this.printFile(action.payload);
2924
2926
  }
2925
2927
  else {
@@ -2927,14 +2929,14 @@ class NodeEffects {
2927
2929
  .select(getAppSelection)
2928
2930
  .pipe(take(1))
2929
2931
  .subscribe((selection) => {
2930
- if (selection && selection.file) {
2932
+ if (selection?.file) {
2931
2933
  this.printFile(selection.file);
2932
2934
  }
2933
2935
  });
2934
2936
  }
2935
2937
  })), { dispatch: false });
2936
2938
  this.unlockWrite$ = createEffect(() => this.actions$.pipe(ofType(NodeActionTypes.UnlockForWriting), map((action) => {
2937
- if (action && action.payload) {
2939
+ if (action?.payload) {
2938
2940
  this.contentService.unlockNode(action.payload);
2939
2941
  }
2940
2942
  else {
@@ -2942,7 +2944,7 @@ class NodeEffects {
2942
2944
  .select(getAppSelection)
2943
2945
  .pipe(take(1))
2944
2946
  .subscribe((selection) => {
2945
- if (selection && selection.file) {
2947
+ if (selection?.file) {
2946
2948
  this.contentService.unlockNode(selection.file);
2947
2949
  }
2948
2950
  });
@@ -2980,7 +2982,7 @@ class NodeEffects {
2980
2982
  })), { dispatch: false });
2981
2983
  }
2982
2984
  printFile(node) {
2983
- if (node && node.entry) {
2985
+ if (node?.entry) {
2984
2986
  // shared and favorite
2985
2987
  const id = node.entry.nodeId || node.entry.guid || node.entry.id;
2986
2988
  const mimeType = node.entry.content.mimeType;
@@ -3053,7 +3055,7 @@ class ViewerEffects {
3053
3055
  }
3054
3056
  })), { dispatch: false });
3055
3057
  this.viewFile$ = createEffect(() => this.actions$.pipe(ofType(ViewerActionTypes.ViewFile), map((action) => {
3056
- if (action.payload && action.payload.entry) {
3058
+ if (action.payload?.entry) {
3057
3059
  const { id, nodeId, isFile } = action.payload.entry;
3058
3060
  if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
3059
3061
  this.displayPreview(nodeId || id, action.parentId);
@@ -3064,7 +3066,7 @@ class ViewerEffects {
3064
3066
  .select(fileToPreview)
3065
3067
  .pipe(take(1))
3066
3068
  .subscribe((result) => {
3067
- if (result.selection && result.selection.file) {
3069
+ if (result.selection?.file) {
3068
3070
  const { id, nodeId, isFile } = result.selection.file.entry;
3069
3071
  if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) {
3070
3072
  const parentId = result.folder ? result.folder.id : null;
@@ -3301,7 +3303,7 @@ class LibraryEffects {
3301
3303
  .select(getAppSelection)
3302
3304
  .pipe(take(1))
3303
3305
  .subscribe((selection) => {
3304
- if (selection && selection.library) {
3306
+ if (selection?.library) {
3305
3307
  this.content.deleteLibrary(selection.library.entry.id);
3306
3308
  }
3307
3309
  });
@@ -3316,7 +3318,7 @@ class LibraryEffects {
3316
3318
  .select(getAppSelection)
3317
3319
  .pipe(take(1))
3318
3320
  .subscribe((selection) => {
3319
- if (selection && selection.library) {
3321
+ if (selection?.library) {
3320
3322
  this.content.leaveLibrary(selection.library.entry.id, action.configuration?.focusedElementOnCloseSelector);
3321
3323
  }
3322
3324
  });
@@ -3342,7 +3344,7 @@ class LibraryEffects {
3342
3344
  .select(getAppSelection)
3343
3345
  .pipe(take(1))
3344
3346
  .subscribe((selection) => {
3345
- if (selection && selection.library) {
3347
+ if (selection?.library) {
3346
3348
  const { id } = selection.library.entry;
3347
3349
  const { title, description, visibility } = action.payload;
3348
3350
  const siteBody = {
@@ -3456,7 +3458,7 @@ class UploadEffects {
3456
3458
  .select(getCurrentFolder)
3457
3459
  .pipe(take(1))
3458
3460
  .subscribe((node) => {
3459
- if (node && node.id) {
3461
+ if (node?.id) {
3460
3462
  const input = event.currentTarget;
3461
3463
  const files = FileUtils.toFileArray(input.files).map((file) => new FileModel(file, {
3462
3464
  parentId: node.id,
@@ -3484,11 +3486,7 @@ class UploadEffects {
3484
3486
  this.uploadService.addToQueue(file);
3485
3487
  this.uploadService.uploadFilesInTheQueue();
3486
3488
  const subscription = this.uploadService.fileUploadComplete.subscribe((completed) => {
3487
- if (file.data &&
3488
- file.data.entry &&
3489
- file.data.entry.properties &&
3490
- file.data.entry.properties['cm:lockType'] === 'WRITE_LOCK' &&
3491
- file.data.entry.id === completed.data.entry.id) {
3489
+ if (file.data?.entry?.properties?.['cm:lockType'] === 'WRITE_LOCK' && file.data?.entry?.id === completed.data.entry.id) {
3492
3490
  this.store.dispatch(new UnlockWriteAction(completed.data));
3493
3491
  }
3494
3492
  subscription.unsubscribe();
@@ -3605,10 +3603,10 @@ class CreateFromTemplateDialogComponent {
3605
3603
  }
3606
3604
  }
3607
3605
  CreateFromTemplateDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: CreateFromTemplateDialogComponent, deps: [{ token: i4$1.TranslationService }, { token: i1$1.Store }, { token: i3.UntypedFormBuilder }, { token: i4.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
3608
- CreateFromTemplateDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: CreateFromTemplateDialogComponent, isStandalone: true, selector: "app-create-from-template-dialog", ngImport: i0, template: "<h2 mat-dialog-title [innerHTML]=\"title\"></h2>\n<div mat-dialog-content>\n <form [formGroup]=\"form\" novalidate>\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n cdkFocusInitial\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.NAME' | translate }}\"\n matInput\n formControlName=\"name\"\n required\n />\n\n <mat-error *ngIf=\"form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.TITLE' | translate }}\"\n matInput\n formControlName=\"title\"\n />\n\n <mat-error *ngIf=\"form.controls['title'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.TITLE_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <textarea\n matInput\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.DESCRIPTION' | translate }}\"\n rows=\"2\"\n formControlName=\"description\"\n ></textarea>\n\n <mat-error *ngIf=\"form.controls['description'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.DESCRIPTION_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n </form>\n</div>\n<div mat-dialog-actions>\n <button mat-button mat-dialog-close data-automation-id=\"cancel-folder-template-button\">\n {{ 'NODE_FROM_TEMPLATE.CANCEL' | translate }}\n </button>\n <button\n class=\"create\"\n [disabled]=\"form.invalid\"\n mat-button\n (click)=\"onSubmit()\"\n data-automation-id=\"create-folder-template-button\"\n >\n {{ 'NODE_FROM_TEMPLATE.CREATE' | translate }}\n </button>\n</div>\n", styles: ["app-create-from-template-dialog{overflow:visible;display:block;margin-left:-24px;margin-right:-24px}app-create-from-template-dialog .mat-dialog-title{margin-left:24px;margin-right:24px;font-size:20px;font-style:normal;font-stretch:normal;line-height:1.6;letter-spacing:-.5px;color:var(--theme-text-bold-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}app-create-from-template-dialog .mat-dialog-title .bold{font-weight:600}app-create-from-template-dialog .app-create-from-template-field{width:100%}app-create-from-template-dialog .app-create-from-template-field:not(:last-of-type){margin-bottom:20px}app-create-from-template-dialog .mat-dialog-content{margin:0 2px;overflow:hidden}app-create-from-template-dialog .mat-dialog-actions{padding:8px 22px;display:flex;justify-content:flex-end;color:var(--theme-secondary-text-color)}app-create-from-template-dialog .mat-dialog-actions button{text-transform:uppercase;font-weight:400}app-create-from-template-dialog .mat-dialog-actions .create[disabled]{opacity:.6}app-create-from-template-dialog .mat-dialog-actions .create:enabled{color:var(--theme-accent-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i4.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i4.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i4.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i4.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i7.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None });
3606
+ CreateFromTemplateDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: CreateFromTemplateDialogComponent, isStandalone: true, selector: "app-create-from-template-dialog", ngImport: i0, template: "<h2 mat-dialog-title [innerHTML]=\"title\"></h2>\n<div mat-dialog-content>\n <form [formGroup]=\"form\" novalidate>\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n cdkFocusInitial\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.NAME' | translate }}\"\n matInput\n formControlName=\"name\"\n required\n />\n\n <mat-error *ngIf=\"form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.TITLE' | translate }}\"\n matInput\n formControlName=\"title\"\n />\n\n <mat-error *ngIf=\"form.controls['title'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.TITLE_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <textarea\n matInput\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.DESCRIPTION' | translate }}\"\n rows=\"2\"\n formControlName=\"description\"\n ></textarea>\n\n <mat-error *ngIf=\"form.controls['description'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.DESCRIPTION_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n </form>\n</div>\n<div mat-dialog-actions>\n <button mat-button mat-dialog-close data-automation-id=\"create-from-template-dialog-cancel-button\">\n {{ 'NODE_FROM_TEMPLATE.CANCEL' | translate }}\n </button>\n <button\n class=\"create\"\n [disabled]=\"form.invalid\"\n mat-button\n (click)=\"onSubmit()\"\n data-automation-id=\"create-from-template-dialog-create-button\"\n >\n {{ 'NODE_FROM_TEMPLATE.CREATE' | translate }}\n </button>\n</div>\n", styles: ["app-create-from-template-dialog{overflow:visible;display:block;margin-left:-24px;margin-right:-24px}app-create-from-template-dialog .mat-dialog-title{margin-left:24px;margin-right:24px;font-size:20px;font-style:normal;font-stretch:normal;line-height:1.6;letter-spacing:-.5px;color:var(--theme-text-bold-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}app-create-from-template-dialog .mat-dialog-title .bold{font-weight:600}app-create-from-template-dialog .app-create-from-template-field{width:100%}app-create-from-template-dialog .app-create-from-template-field:not(:last-of-type){margin-bottom:20px}app-create-from-template-dialog .mat-dialog-content{margin:0 2px;overflow:hidden}app-create-from-template-dialog .mat-dialog-actions{padding:8px 22px;display:flex;justify-content:flex-end;color:var(--theme-secondary-text-color)}app-create-from-template-dialog .mat-dialog-actions button{text-transform:uppercase;font-weight:400}app-create-from-template-dialog .mat-dialog-actions .create[disabled]{opacity:.6}app-create-from-template-dialog .mat-dialog-actions .create:enabled{color:var(--theme-accent-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i4.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i4.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i4.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i4.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i7.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i8.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None });
3609
3607
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: CreateFromTemplateDialogComponent, decorators: [{
3610
3608
  type: Component,
3611
- args: [{ standalone: true, imports: [CommonModule, TranslateModule, MatDialogModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule], selector: 'app-create-from-template-dialog', encapsulation: ViewEncapsulation.None, template: "<h2 mat-dialog-title [innerHTML]=\"title\"></h2>\n<div mat-dialog-content>\n <form [formGroup]=\"form\" novalidate>\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n cdkFocusInitial\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.NAME' | translate }}\"\n matInput\n formControlName=\"name\"\n required\n />\n\n <mat-error *ngIf=\"form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.TITLE' | translate }}\"\n matInput\n formControlName=\"title\"\n />\n\n <mat-error *ngIf=\"form.controls['title'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.TITLE_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <textarea\n matInput\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.DESCRIPTION' | translate }}\"\n rows=\"2\"\n formControlName=\"description\"\n ></textarea>\n\n <mat-error *ngIf=\"form.controls['description'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.DESCRIPTION_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n </form>\n</div>\n<div mat-dialog-actions>\n <button mat-button mat-dialog-close data-automation-id=\"cancel-folder-template-button\">\n {{ 'NODE_FROM_TEMPLATE.CANCEL' | translate }}\n </button>\n <button\n class=\"create\"\n [disabled]=\"form.invalid\"\n mat-button\n (click)=\"onSubmit()\"\n data-automation-id=\"create-folder-template-button\"\n >\n {{ 'NODE_FROM_TEMPLATE.CREATE' | translate }}\n </button>\n</div>\n", styles: ["app-create-from-template-dialog{overflow:visible;display:block;margin-left:-24px;margin-right:-24px}app-create-from-template-dialog .mat-dialog-title{margin-left:24px;margin-right:24px;font-size:20px;font-style:normal;font-stretch:normal;line-height:1.6;letter-spacing:-.5px;color:var(--theme-text-bold-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}app-create-from-template-dialog .mat-dialog-title .bold{font-weight:600}app-create-from-template-dialog .app-create-from-template-field{width:100%}app-create-from-template-dialog .app-create-from-template-field:not(:last-of-type){margin-bottom:20px}app-create-from-template-dialog .mat-dialog-content{margin:0 2px;overflow:hidden}app-create-from-template-dialog .mat-dialog-actions{padding:8px 22px;display:flex;justify-content:flex-end;color:var(--theme-secondary-text-color)}app-create-from-template-dialog .mat-dialog-actions button{text-transform:uppercase;font-weight:400}app-create-from-template-dialog .mat-dialog-actions .create[disabled]{opacity:.6}app-create-from-template-dialog .mat-dialog-actions .create:enabled{color:var(--theme-accent-color)}\n"] }]
3609
+ args: [{ standalone: true, imports: [CommonModule, TranslateModule, MatDialogModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule], selector: 'app-create-from-template-dialog', encapsulation: ViewEncapsulation.None, template: "<h2 mat-dialog-title [innerHTML]=\"title\"></h2>\n<div mat-dialog-content>\n <form [formGroup]=\"form\" novalidate>\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n cdkFocusInitial\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.NAME' | translate }}\"\n matInput\n formControlName=\"name\"\n required\n />\n\n <mat-error *ngIf=\"form.controls['name'].errors?.message\">\n {{ form.controls['name'].errors?.message | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <input\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.TITLE' | translate }}\"\n matInput\n formControlName=\"title\"\n />\n\n <mat-error *ngIf=\"form.controls['title'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.TITLE_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n\n <mat-form-field class=\"app-create-from-template-field\">\n <textarea\n matInput\n placeholder=\"{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.DESCRIPTION' | translate }}\"\n rows=\"2\"\n formControlName=\"description\"\n ></textarea>\n\n <mat-error *ngIf=\"form.controls['description'].hasError('maxlength')\">\n {{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.DESCRIPTION_TOO_LONG' | translate }}\n </mat-error>\n </mat-form-field>\n </form>\n</div>\n<div mat-dialog-actions>\n <button mat-button mat-dialog-close data-automation-id=\"create-from-template-dialog-cancel-button\">\n {{ 'NODE_FROM_TEMPLATE.CANCEL' | translate }}\n </button>\n <button\n class=\"create\"\n [disabled]=\"form.invalid\"\n mat-button\n (click)=\"onSubmit()\"\n data-automation-id=\"create-from-template-dialog-create-button\"\n >\n {{ 'NODE_FROM_TEMPLATE.CREATE' | translate }}\n </button>\n</div>\n", styles: ["app-create-from-template-dialog{overflow:visible;display:block;margin-left:-24px;margin-right:-24px}app-create-from-template-dialog .mat-dialog-title{margin-left:24px;margin-right:24px;font-size:20px;font-style:normal;font-stretch:normal;line-height:1.6;letter-spacing:-.5px;color:var(--theme-text-bold-color);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}app-create-from-template-dialog .mat-dialog-title .bold{font-weight:600}app-create-from-template-dialog .app-create-from-template-field{width:100%}app-create-from-template-dialog .app-create-from-template-field:not(:last-of-type){margin-bottom:20px}app-create-from-template-dialog .mat-dialog-content{margin:0 2px;overflow:hidden}app-create-from-template-dialog .mat-dialog-actions{padding:8px 22px;display:flex;justify-content:flex-end;color:var(--theme-secondary-text-color)}app-create-from-template-dialog .mat-dialog-actions button{text-transform:uppercase;font-weight:400}app-create-from-template-dialog .mat-dialog-actions .create[disabled]{opacity:.6}app-create-from-template-dialog .mat-dialog-actions .create:enabled{color:var(--theme-accent-color)}\n"] }]
3612
3610
  }], ctorParameters: function () { return [{ type: i4$1.TranslationService }, { type: i1$1.Store }, { type: i3.UntypedFormBuilder }, { type: i4.MatDialogRef }, { type: i10.Node, decorators: [{
3613
3611
  type: Inject,
3614
3612
  args: [MAT_DIALOG_DATA]
@@ -3705,7 +3703,7 @@ class NodeTemplateService {
3705
3703
  return dialog;
3706
3704
  }
3707
3705
  transformNode(node) {
3708
- if (node && node.path && node.path && node.path.elements instanceof Array) {
3706
+ if (node?.path?.elements instanceof Array) {
3709
3707
  node.path.elements = this.getPathElements(node);
3710
3708
  }
3711
3709
  return node;
@@ -3945,7 +3943,7 @@ class ContextMenuItemComponent {
3945
3943
  }
3946
3944
  }
3947
3945
  hasClickAction(actionRef) {
3948
- return !!(actionRef && actionRef.actions && actionRef.actions.click);
3946
+ return !!actionRef?.actions?.click;
3949
3947
  }
3950
3948
  trackByActionId(_, obj) {
3951
3949
  return obj.id;
@@ -4001,12 +3999,9 @@ class OutsideEventDirective {
4001
3999
  }
4002
4000
  findAncestor(el) {
4003
4001
  const className = 'aca-context-menu';
4004
- if (el.classList.contains(className)) {
4005
- return true;
4002
+ while (el && !el.classList.contains(className)) {
4003
+ el = el.parentElement;
4006
4004
  }
4007
- // eslint-disable-next-line curly
4008
- while ((el = el.parentElement) && !el.classList.contains(className))
4009
- ;
4010
4005
  return !!el;
4011
4006
  }
4012
4007
  }
@@ -4018,7 +4013,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImpor
4018
4013
  standalone: true,
4019
4014
  selector: '[acaContextMenuOutsideEvent]'
4020
4015
  }]
4021
- }], ctorParameters: function () { return []; }, propDecorators: { clickOutside: [{
4016
+ }], propDecorators: { clickOutside: [{
4022
4017
  type: Output
4023
4018
  }] } });
4024
4019
 
@@ -4163,9 +4158,6 @@ class ContextMenuService {
4163
4158
  return containerRef.instance;
4164
4159
  }
4165
4160
  createInjector(contextmenuOverlayRef) {
4166
- const injectionTokens = new WeakMap();
4167
- injectionTokens.set(ContextMenuOverlayRef, contextmenuOverlayRef);
4168
- injectionTokens.set(CONTEXT_MENU_DIRECTION, this.direction);
4169
4161
  return Injector.create({
4170
4162
  parent: this.injector,
4171
4163
  providers: [
@@ -4596,8 +4588,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImpor
4596
4588
  */
4597
4589
  class InstantErrorStateMatcher {
4598
4590
  isErrorState(control, form) {
4599
- const isSubmitted = form && form.submitted;
4600
- return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
4591
+ const isSubmitted = form?.submitted;
4592
+ return !!(control?.invalid && (control?.dirty || control?.touched || isSubmitted));
4601
4593
  }
4602
4594
  }
4603
4595
  class LibraryMetadataFormComponent {
@@ -5611,7 +5603,7 @@ class ExpansionPanelDirective {
5611
5603
  }
5612
5604
  }
5613
5605
  hasActiveLinks() {
5614
- if (this.acaExpansionPanel && this.acaExpansionPanel.children) {
5606
+ if (this.acaExpansionPanel?.children) {
5615
5607
  return this.acaExpansionPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload));
5616
5608
  }
5617
5609
  return false;
@@ -5702,7 +5694,7 @@ class MenuPanelDirective {
5702
5694
  }
5703
5695
  }
5704
5696
  hasActiveLinks() {
5705
- if (this.acaMenuPanel && this.acaMenuPanel.children) {
5697
+ if (this.acaMenuPanel?.children) {
5706
5698
  return this.acaMenuPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload));
5707
5699
  }
5708
5700
  return false;
@@ -5924,7 +5916,7 @@ class ActiveLinkDirective {
5924
5916
  });
5925
5917
  }
5926
5918
  render(routerUrl, actionUrl) {
5927
- if (routerUrl && routerUrl.substring(1).startsWith(actionUrl)) {
5919
+ if (routerUrl?.substring(1).startsWith(actionUrl)) {
5928
5920
  this.isLinkActive = true;
5929
5921
  this.renderer.addClass(this.element.nativeElement, this.acaActiveLink);
5930
5922
  }
@@ -5938,7 +5930,7 @@ class ActiveLinkDirective {
5938
5930
  this.update(this.router.url);
5939
5931
  }
5940
5932
  resolveUrl(item) {
5941
- return (item.action && item.action.click && item.action.click.payload) || item.action.route;
5933
+ return item.action?.click?.payload || item.action?.route;
5942
5934
  }
5943
5935
  }
5944
5936
  ActiveLinkDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: ActiveLinkDirective, deps: [{ token: i2$1.Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: ActionDirective, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
@@ -6160,7 +6152,7 @@ class UserMenuComponent {
6160
6152
  }
6161
6153
  ngOnInit() {
6162
6154
  this.getUserInfo();
6163
- if (this.data && this.data.items) {
6155
+ if (this.data?.items) {
6164
6156
  this.data.items.sort((a, b) => a.order - b.order);
6165
6157
  }
6166
6158
  }
@@ -6290,9 +6282,9 @@ class LocationLinkComponent {
6290
6282
  ngOnInit() {
6291
6283
  if (this.context) {
6292
6284
  const node = this.context.row.node;
6293
- if (node && node.entry && node.entry.path) {
6285
+ if (node?.entry && node?.entry?.path) {
6294
6286
  const path = node.entry.path;
6295
- if (path && path.name && path.elements) {
6287
+ if (path?.name && path?.elements) {
6296
6288
  if (this.showLocation) {
6297
6289
  this.displayText = of(path.name.substring(1).replace(/\//g, ' &#8250; '));
6298
6290
  }
@@ -6339,7 +6331,9 @@ class LocationLinkComponent {
6339
6331
  return;
6340
6332
  }
6341
6333
  let result = null;
6342
- const elements = path.elements.map((e) => Object.assign({}, e));
6334
+ const elements = path.elements.map((e) => {
6335
+ return { ...e };
6336
+ });
6343
6337
  const personalFiles = this.translationService.instant('APP.BROWSE.PERSONAL.TITLE');
6344
6338
  const fileLibraries = this.translationService.instant('APP.BROWSE.LIBRARIES.TITLE');
6345
6339
  if (elements[0].name === 'Company Home') {
@@ -6449,7 +6443,7 @@ class ToggleSharedComponent {
6449
6443
  this.selection$.pipe(takeUntil(this.onDestroy$)).subscribe((selectionState) => {
6450
6444
  this.selectionState = selectionState;
6451
6445
  this.isShared =
6452
- (this.selectionState.first && this.selectionState.first.entry && this.selectionState.first.entry.sharedByUser) ||
6446
+ (this.selectionState?.first?.entry && this.selectionState.first.entry.sharedByUser) ||
6453
6447
  !!this.selectionState?.first?.entry?.properties?.['qshare:sharedId'];
6454
6448
  this.selectionLabel = this.isShared ? 'APP.ACTIONS.SHARE_EDIT' : 'APP.ACTIONS.SHARE';
6455
6449
  });
@@ -6800,12 +6794,12 @@ class SearchLibrariesQueryBuilderService {
6800
6794
  }
6801
6795
  buildQuery() {
6802
6796
  const query = this.userQuery;
6803
- if (query && query.length > 1) {
6797
+ if (query?.length > 1) {
6804
6798
  return {
6805
6799
  term: query,
6806
6800
  opts: {
6807
- skipCount: this.paging && this.paging.skipCount,
6808
- maxItems: this.paging && this.paging.maxItems
6801
+ skipCount: this.paging?.skipCount,
6802
+ maxItems: this.paging?.maxItems
6809
6803
  }
6810
6804
  };
6811
6805
  }
@@ -7252,7 +7246,7 @@ class SearchLibrariesResultsComponent extends PageComponent {
7252
7246
  this.totalResults = this.getNumberOfResults();
7253
7247
  }
7254
7248
  getNumberOfResults() {
7255
- if (this.data && this.data.list && this.data.list.pagination) {
7249
+ if (this.data?.list?.pagination) {
7256
7250
  return this.data.list.pagination.totalItems;
7257
7251
  }
7258
7252
  return 0;
@@ -7265,7 +7259,7 @@ class SearchLibrariesResultsComponent extends PageComponent {
7265
7259
  this.librariesQueryBuilder.update();
7266
7260
  }
7267
7261
  navigateTo(node) {
7268
- if (node && node.entry && node.entry.guid) {
7262
+ if (node?.entry?.guid) {
7269
7263
  this.store.dispatch(new NavigateLibraryAction(node.entry.guid));
7270
7264
  }
7271
7265
  }
@@ -7446,7 +7440,7 @@ class SearchResultsRowComponent {
7446
7440
  const { entry } = row.node;
7447
7441
  if (entry.id === node.id) {
7448
7442
  entry.name = node.name;
7449
- entry.properties = Object.assign({}, node.properties);
7443
+ entry.properties = { ...node.properties };
7450
7444
  this.updateValues();
7451
7445
  }
7452
7446
  }
@@ -7647,7 +7641,7 @@ class SearchResultsComponent extends PageComponent {
7647
7641
  return ['name', 'asc'];
7648
7642
  }
7649
7643
  onNodeDoubleClick(node) {
7650
- if (node && node.entry) {
7644
+ if (node?.entry) {
7651
7645
  if (node.entry.isFolder) {
7652
7646
  this.store.dispatch(new NavigateToFolder(node));
7653
7647
  return;
@@ -7773,7 +7767,7 @@ class FavoritesComponent extends PageComponent {
7773
7767
  navigate(favorite) {
7774
7768
  const { isFolder, id } = favorite;
7775
7769
  // TODO: rework as it will fail on non-English setups
7776
- const isSitePath = (path) => path && path.elements && path.elements.some(({ name }) => name === 'Sites');
7770
+ const isSitePath = (path) => path?.elements?.some(({ name }) => name === 'Sites');
7777
7771
  if (isFolder) {
7778
7772
  this.contentApi
7779
7773
  .getNode(id)
@@ -7785,7 +7779,7 @@ class FavoritesComponent extends PageComponent {
7785
7779
  }
7786
7780
  }
7787
7781
  onNodeDoubleClick(node) {
7788
- if (node && node.entry) {
7782
+ if (node?.entry) {
7789
7783
  if (node.entry.isFolder) {
7790
7784
  this.navigate(node.entry);
7791
7785
  }
@@ -7844,7 +7838,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImpor
7844
7838
  */
7845
7839
  class RecentFilesComponent extends PageComponent {
7846
7840
  constructor() {
7847
- super();
7841
+ super(...arguments);
7848
7842
  this.columns = [];
7849
7843
  }
7850
7844
  ngOnInit() {
@@ -7856,7 +7850,7 @@ class RecentFilesComponent extends PageComponent {
7856
7850
  this.columns = this.extensions.documentListPresets.recent || [];
7857
7851
  }
7858
7852
  onNodeDoubleClick(node) {
7859
- if (node && node.entry) {
7853
+ if (node?.entry) {
7860
7854
  this.showPreview(node, { location: this.router.url });
7861
7855
  }
7862
7856
  }
@@ -7864,7 +7858,7 @@ class RecentFilesComponent extends PageComponent {
7864
7858
  this.onNodeDoubleClick(event.detail?.node);
7865
7859
  }
7866
7860
  }
7867
- RecentFilesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: RecentFilesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7861
+ RecentFilesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: RecentFilesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
7868
7862
  RecentFilesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.3", type: RecentFilesComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<aca-page-layout>\n <div class=\"aca-page-layout-header\">\n <h1 class=\"aca-page-title\">{{ 'APP.BROWSE.RECENT.TITLE' | translate }}</h1>\n <aca-toolbar [items]=\"actions\"></aca-toolbar>\n </div>\n\n <div class=\"aca-page-layout-content\">\n <div class=\"main-content\">\n <adf-document-list\n #documentList\n acaDocumentList\n acaContextActions\n [currentFolderId]=\"'-recent-'\"\n [selectionMode]=\"'multiple'\"\n [navigate]=\"false\"\n [sorting]=\"['modifiedAt', 'desc']\"\n [sortingMode]=\"'client'\"\n [imageResolver]=\"imageResolver\"\n (node-dblclick)=\"handleNodeClick($event)\"\n (name-click)=\"handleNodeClick($event)\"\n >\n <adf-custom-empty-content-template>\n <adf-empty-content icon=\"access_time\" [title]=\"'APP.BROWSE.RECENT.EMPTY_STATE.TITLE'\" subtitle=\"APP.BROWSE.RECENT.EMPTY_STATE.TEXT\">\n </adf-empty-content>\n </adf-custom-empty-content-template>\n\n <data-columns>\n <ng-container *ngFor=\"let column of columns; trackBy: trackByColumnId\">\n <ng-container *ngIf=\"column.template && !(column.desktopOnly && isSmallScreen)\">\n <data-column\n [key]=\"column.key\"\n [title]=\"column.title\"\n [type]=\"column.type\"\n [format]=\"column.format\"\n [class]=\"column.class\"\n [sortable]=\"column.sortable\"\n [isHidden]=\"column.isHidden\"\n >\n <ng-template let-context>\n <adf-dynamic-column [id]=\"column.template\" [context]=\"context\"> </adf-dynamic-column>\n </ng-template>\n </data-column>\n </ng-container>\n\n <ng-container *ngIf=\"!column.template && !(column.desktopOnly && isSmallScreen)\">\n <data-column\n [key]=\"column.key\"\n [title]=\"column.title\"\n [type]=\"column.type\"\n [format]=\"column.format\"\n [class]=\"column.class\"\n [sortable]=\"column.sortable\"\n [isHidden]=\"column.isHidden\"\n >\n </data-column>\n </ng-container>\n </ng-container>\n </data-columns>\n </adf-document-list>\n\n <adf-pagination acaPagination [target]=\"documentList\"> </adf-pagination>\n </div>\n\n <div class=\"aca-sidebar\" *ngIf=\"infoDrawerOpened$ | async\">\n <aca-info-drawer [node]=\"selection.last\"></aca-info-drawer>\n </div>\n </div>\n</aca-page-layout>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: DocumentListModule }, { kind: "component", type: i1.DocumentListComponent, selector: "adf-document-list", inputs: ["includeFields", "where", "display", "permissionsStyle", "locationFormat", "navigate", "showHeader", "navigationMode", "thumbnails", "selectionMode", "multiselect", "contentActions", "contentActionsPosition", "contextMenuActions", "emptyFolderImageUrl", "allowDropFiles", "sorting", "additionalSorting", "sortingMode", "rowStyle", "rowStyleClass", "loading", "_rowFilter", "rowFilter", "imageResolver", "stickyHeader", "headerFilters", "filterValue", "currentFolderId", "preselectNodes", "node", "maxItems", "columnsPresetKey", "maxColumnsVisible"], outputs: ["nodeClick", "nodeDblClick", "folderChange", "preview", "ready", "error", "nodeSelected", "filterSelection"] }, { kind: "directive", type: DocumentListDirective, selector: "[acaDocumentList]" }, { kind: "directive", type: ContextActionsDirective, selector: "[acaContextActions]", inputs: ["acaContextEnable"], exportAs: ["acaContextActions"] }, { kind: "ngmodule", type: TemplateModule }, { kind: "component", type: i4$1.EmptyContentComponent, selector: "adf-empty-content", inputs: ["icon", "title", "subtitle"] }, { kind: "ngmodule", type: DataTableModule }, { kind: "directive", type: i4$1.CustomEmptyContentTemplateDirective, selector: "adf-custom-empty-content-template, empty-folder-content" }, { kind: "component", type: i4$1.DataColumnComponent, selector: "data-column", inputs: ["id", "key", "customData", "type", "format", "sortable", "draggable", "isHidden", "title", "formatTooltip", "sr-title", "class", "copyContent", "editable", "focus", "sortingKey", "order"] }, { kind: "component", type: i4$1.DataColumnListComponent, selector: "data-columns" }, { kind: "ngmodule", type: ExtensionsModule }, { kind: "component", type: i5$1.DynamicColumnComponent, selector: "adf-dynamic-column", inputs: ["id", "context"] }, { kind: "ngmodule", type: PaginationModule }, { kind: "component", type: i4$1.PaginationComponent, selector: "adf-pagination", inputs: ["target", "supportedPageSizes", "pagination"], outputs: ["change", "changePageNumber", "changePageSize", "nextPage", "prevPage"] }, { kind: "directive", type: PaginationDirective, selector: "[acaPagination]" }, { kind: "component", type: InfoDrawerComponent, selector: "aca-info-drawer", inputs: ["nodeId", "node"] }, { kind: "component", type: PageLayoutComponent, selector: "aca-page-layout", inputs: ["hasError"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "component", type: ToolbarComponent, selector: "aca-toolbar", inputs: ["items"] }], encapsulation: i0.ViewEncapsulation.None });
7869
7863
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImport: i0, type: RecentFilesComponent, decorators: [{
7870
7864
  type: Component,
@@ -7883,7 +7877,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.3", ngImpor
7883
7877
  TranslateModule,
7884
7878
  ToolbarComponent
7885
7879
  ], encapsulation: ViewEncapsulation.None, template: "<aca-page-layout>\n <div class=\"aca-page-layout-header\">\n <h1 class=\"aca-page-title\">{{ 'APP.BROWSE.RECENT.TITLE' | translate }}</h1>\n <aca-toolbar [items]=\"actions\"></aca-toolbar>\n </div>\n\n <div class=\"aca-page-layout-content\">\n <div class=\"main-content\">\n <adf-document-list\n #documentList\n acaDocumentList\n acaContextActions\n [currentFolderId]=\"'-recent-'\"\n [selectionMode]=\"'multiple'\"\n [navigate]=\"false\"\n [sorting]=\"['modifiedAt', 'desc']\"\n [sortingMode]=\"'client'\"\n [imageResolver]=\"imageResolver\"\n (node-dblclick)=\"handleNodeClick($event)\"\n (name-click)=\"handleNodeClick($event)\"\n >\n <adf-custom-empty-content-template>\n <adf-empty-content icon=\"access_time\" [title]=\"'APP.BROWSE.RECENT.EMPTY_STATE.TITLE'\" subtitle=\"APP.BROWSE.RECENT.EMPTY_STATE.TEXT\">\n </adf-empty-content>\n </adf-custom-empty-content-template>\n\n <data-columns>\n <ng-container *ngFor=\"let column of columns; trackBy: trackByColumnId\">\n <ng-container *ngIf=\"column.template && !(column.desktopOnly && isSmallScreen)\">\n <data-column\n [key]=\"column.key\"\n [title]=\"column.title\"\n [type]=\"column.type\"\n [format]=\"column.format\"\n [class]=\"column.class\"\n [sortable]=\"column.sortable\"\n [isHidden]=\"column.isHidden\"\n >\n <ng-template let-context>\n <adf-dynamic-column [id]=\"column.template\" [context]=\"context\"> </adf-dynamic-column>\n </ng-template>\n </data-column>\n </ng-container>\n\n <ng-container *ngIf=\"!column.template && !(column.desktopOnly && isSmallScreen)\">\n <data-column\n [key]=\"column.key\"\n [title]=\"column.title\"\n [type]=\"column.type\"\n [format]=\"column.format\"\n [class]=\"column.class\"\n [sortable]=\"column.sortable\"\n [isHidden]=\"column.isHidden\"\n >\n </data-column>\n </ng-container>\n </ng-container>\n </data-columns>\n </adf-document-list>\n\n <adf-pagination acaPagination [target]=\"documentList\"> </adf-pagination>\n </div>\n\n <div class=\"aca-sidebar\" *ngIf=\"infoDrawerOpened$ | async\">\n <aca-info-drawer [node]=\"selection.last\"></aca-info-drawer>\n </div>\n </div>\n</aca-page-layout>\n" }]
7886
- }], ctorParameters: function () { return []; } });
7880
+ }] });
7887
7881
 
7888
7882
  /*!
7889
7883
  * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.